GeomUtil

Kind of class: public class
Package:
Inherits from:
  • none
Version: 05/11/11
Author: Aaron Clinger, Jon Adams
Classpath: org.casalib.util.GeomUtil
File last modified: Friday, 20 May 2011, 00:59:45
► View source▼ Hide source
/*
    CASA Lib for ActionScript 3.0
    Copyright (c) 2011, Aaron Clinger & Contributors of CASA Lib
    All rights reserved.
    
    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:
    
    - Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    
    - Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    
    - Neither the name of the CASA Lib nor the names of its contributors
      may be used to endorse or promote products derived from this software
      without specific prior written permission.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.
*/
package org.casalib.util {
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import org.casalib.util.ConversionUtil;
    import org.casalib.util.NumberUtil;
    
    
    /**
        Utilities for positioning, calculating and manipulating geometeric shapes and points.
        
        @author Aaron Clinger
        @author Jon Adams
        @version 05/11/11
    */
    public class GeomUtil {
        
        
        /**
            Rotates a Point around another Point by the specified angle.
            
            @param point: The Point to rotate.
            @param centerPoint: The Point to rotate the Point around.
            @param angle: The angle (in degrees) to rotate the Point.
        */
        public static function rotatePoint(point:Point, centerPoint:Point, angle:Number):void {
            const radians:Number = ConversionUtil.degreesToRadians(angle);
            const baseX:Number   = point.x - centerPoint.x;
            const baseY:Number   = point.y - centerPoint.y;
            
            point.x = (Math.cos(radians) * baseX) - (Math.sin(radians) * baseY) + centerPoint.x;
            point.y = (Math.sin(radians) * baseX) + (Math.cos(radians) * baseY) + centerPoint.y;
        }
        
        /**
            Determines the angle/degree between the first and second Point.
            
            @param first: The first Point.
            @param second: The second Point.
            @return The degree between the two points.
        */
        public static function angle(first:Point, second:Point):Number {
            return Math.atan2(second.y - first.y, second.x - first.x) / (Math.PI / 180);
        }
        
        /**
            Places a Point randomly within a defined area.
            
            @param area: The area in which to randomly place the Point.
            @param snapToPixel: If the Point should only be placed on whole pixels true, or allow placement on sub-pixels false; defaults to true.
            @return A randomly placed Point within the defined bounds.
        */
        public static function randomlyPlacePoint(area:Rectangle, snapToPixel:Boolean = true):Point {
            if (snapToPixel)
                return new Point(NumberUtil.randomIntegerWithinRange(Math.ceil(area.x), Math.floor(area.right)), NumberUtil.randomIntegerWithinRange(Math.ceil(area.y), Math.floor(area.bottom)));
            
            return new Point(NumberUtil.randomWithinRange(area.x, area.right), NumberUtil.randomWithinRange(area.y, area.bottom));
        }
        
        /**
            Places a Rectangle randomly within a defined area.
            
            @param area: The area in which to randomly place the Rectangle.
            @param rect: The Rectangle to randomly place within the bounds.
            @param snapToPixel: If the Rectangle should only be placed on whole pixels true, or allow placement on sub-pixels false; defaults to true.
            @return A new randomly placed Rectangle within the defined bounds.
            @throws Error if the area is too small to contain the Rectangle.
        */
        public static function randomlyPlaceRectangle(area:Rectangle, rect:Rectangle, snapToPixel:Boolean = true):Rectangle {
            const zone:Rectangle = area.clone();
            const size:Rectangle = rect.clone();
            size.x               = area.x;
            size.y               = area.y;
            
            if ( ! zone.containsRect(size))
                throw new Error('Area needs to be large enough to contain the rectangle.');
                
            zone.right  -= size.width;
            zone.bottom -= size.height;
            
            const point:Point = GeomUtil.randomlyPlacePoint(zone, snapToPixel);
            
            return new Rectangle(point.x, point.y, rect.width, rect.height);
        }
        
        /**
            Takes the provided Rectangle and returns a new Rectangle that is flipped (width becomes height, height becomes width).
            
            @param rect: The Rectangle to flip.
            @return A new Rectangle that is flipped.
            @usageNote The Rectangle's X and Y are unaffected.
        */
        public static function flipRectangle(rect:Rectangle):Rectangle {
            return new Rectangle(rect.x, rect.y, rect.height, rect.width);
        }
        
        /**
            Calculates the perimeter of a Rectangle.
            
            @param rect: Rectangle to determine the perimeter of.
            @return The Rectangle's perimeter.
        */
        public static function getRectanglePerimeter(rect:Rectangle):Number {
            return rect.width * 2 + rect.height * 2;
        }
        
        /**
            Takes any degree value and returns the normalized 0-360 degree equivalent.
            
            @param degree: The degree to normalize.
            @return Returns a degree value between 0  and 360.
            @example
                
                    trace(GeomUtil.normalizeDegree(-90)); // Traces "270"
                    trace(GeomUtil.normalizeDegree(1080)); // Traces "0"
                
        */
        public static function normalizeDegree(degree:Number):Number {
            degree %= 360;
            
            return (degree < 0) ? degree + 360 : degree;
        }
        
        /**
            Determines the shortest distance and direction between two degrees.
            
            @param startDegree: The first degree.
            @param endDegree: The second degree.
            @return Returns a degree value between -180 and 180.
            @example
                
                    trace(GeomUtil.distanceBetweenDegrees(45, 100)); // Traces "55"
                    trace(GeomUtil.distanceBetweenDegrees(270, 10)); // Traces "100"
                    trace(GeomUtil.distanceBetweenDegrees(0, 190)); // Traces "-170"
                
        */
        public static function distanceBetweenDegrees(startDegree:Number, endDegree:Number):Number {
            const start:Number = GeomUtil.normalizeDegree(startDegree);
            const end:Number   = GeomUtil.normalizeDegree(endDegree);
            const dif:Number   = Math.abs(start - end);
            var dis:Number     = (dif > 180) ? 360 - dif : dif;
            
            if (end != GeomUtil.normalizeDegree(start + dis))
                dis *= -1;
            
            return dis;
        }
    }
}
Utilities for positioning, calculating and manipulating geometeric shapes and points.

Summary

Class methods
  • rotatePoint (point:Point, centerPoint:Point, angle:Number) : void
    • Rotates a Point around another Point by the specified angle.
  • angle (first:Point, second:Point) : Number
    • Determines the angle/degree between the first and second Point.
  • randomlyPlacePoint (area:Rectangle, snapToPixel:Boolean = true) : Point
    • Places a Point randomly within a defined area.
  • randomlyPlaceRectangle (area:Rectangle, rect:Rectangle, snapToPixel:Boolean = true) : Rectangle
    • Places a Rectangle randomly within a defined area.
  • flipRectangle (rect:Rectangle) : Rectangle
    • Takes the provided Rectangle and returns a new Rectangle that is flipped (width becomes height, height becomes width).
  • getRectanglePerimeter (rect:Rectangle) : Number
    • Calculates the perimeter of a Rectangle.
  • normalizeDegree (degree:Number) : Number
    • Takes any degree value and returns the normalized 0-360 degree equivalent.
  • distanceBetweenDegrees (startDegree:Number, endDegree:Number) : Number
    • Determines the shortest distance and direction between two degrees.

Class methods

angle

static function angle(first:Point, second:Point) : Number

Determines the angle/degree between the first and second Point.

Parameters
first :The first Point.
second:The second Point.
Returns
  • The degree between the two points.

distanceBetweenDegrees

static function distanceBetweenDegrees(startDegree:Number, endDegree:Number) : Number

Determines the shortest distance and direction between two degrees.

Parameters
startDegree:The first degree.
endDegree :The second degree.
Example
  • trace(GeomUtil.distanceBetweenDegrees(45, 100)); // Traces "55"
    trace(GeomUtil.distanceBetweenDegrees(270, 10)); // Traces "100"
    trace(GeomUtil.distanceBetweenDegrees(0, 190)); // Traces "-170"
    
Returns
  • Returns a degree value between -180 and 180.

flipRectangle

static function flipRectangle(rect:Rectangle) : Rectangle

Takes the provided Rectangle and returns a new Rectangle that is flipped (width becomes height, height becomes width).

Parameters
rect:The Rectangle to flip.
Returns
  • A new Rectangle that is flipped.
Usage note
  • The Rectangle's X and Y are unaffected.

getRectanglePerimeter

static function getRectanglePerimeter(rect:Rectangle) : Number

Calculates the perimeter of a Rectangle.

Parameters
rect:Rectangle to determine the perimeter of.
Returns
  • The Rectangle's perimeter.

normalizeDegree

static function normalizeDegree(degree:Number) : Number

Takes any degree value and returns the normalized 0-360 degree equivalent.

Parameters
degree:The degree to normalize.
Example
  • trace(GeomUtil.normalizeDegree(-90)); // Traces "270"
    trace(GeomUtil.normalizeDegree(1080)); // Traces "0"
    
Returns
  • Returns a degree value between 0 and 360.

randomlyPlacePoint

static function randomlyPlacePoint(area:Rectangle, snapToPixel:Boolean = true) : Point

Places a Point randomly within a defined area.

Parameters
area :The area in which to randomly place the Point.
snapToPixel:If the Point should only be placed on whole pixels true, or allow placement on sub-pixels false; defaults to true.
Returns
  • A randomly placed Point within the defined bounds.

randomlyPlaceRectangle

static function randomlyPlaceRectangle(area:Rectangle, rect:Rectangle, snapToPixel:Boolean = true) : Rectangle

Places a Rectangle randomly within a defined area.

Parameters
area :The area in which to randomly place the Rectangle.
rect :The Rectangle to randomly place within the bounds.
snapToPixel:If the Rectangle should only be placed on whole pixels true, or allow placement on sub-pixels false; defaults to true.
Returns
  • A new randomly placed Rectangle within the defined bounds.
Throws
  • Error if the area is too small to contain the Rectangle.

rotatePoint

static function rotatePoint(point:Point, centerPoint:Point, angle:Number) : void

Rotates a Point around another Point by the specified angle.

Parameters
point :The Point to rotate.
centerPoint:The Point to rotate the Point around.
angle :The angle (in degrees) to rotate the Point.