package com.rubenswieringa.geom { import flash.geom.*; /** * Describes a line consisting of two Points. * * @author Ruben Swieringa * ruben.swieringa@gmail.com * www.rubenswieringa.com * www.rubenswieringa.com/blog * @version 1.0.0 * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line * * * edit 4 * * Before modifying and/or redistributing this class, please contact Ruben Swieringa (ruben.swieringa@gmail.com). * * * View code documentation at: * http://www.rubenswieringa.com/code/as3/flex/Geom/docs/ * */ public class lib_flex_book_com_rubenswieringa_geom_Line extends Infinitelib_flex_book_com_rubenswieringa_geom_Line { /** * @private */ protected var _a:Point = new Point(0, 0); /** * @private */ protected var _b:Point = new Point(1, 1); /** * Constructor. * * @param pointA lib_flex_book_com_rubenswieringa_geom_Line's first Point. * @param pointB lib_flex_book_com_rubenswieringa_geom_Line's second Point. * * @see lib_flex_book_com_rubenswieringa_geom_Line#a * @see lib_flex_book_com_rubenswieringa_geom_Line#b * */ public function lib_flex_book_com_rubenswieringa_geom_Line (pointA:Point=null, pointB:Point=null):void { if (pointA != null) this.a = pointA; if (pointA != null) this.b = pointB; } /** * Returns a Point instance that represents the coordinate at which two lib_flex_book_com_rubenswieringa_geom_Line instances intersect. * * @param line1 lib_flex_book_com_rubenswieringa_geom_Line * @param line2 lib_flex_book_com_rubenswieringa_geom_Line * * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#getIntersection() * * @return A Point instance if intersections occurs, null of otherwise. */ public static function getIntersection (line1:lib_flex_book_com_rubenswieringa_geom_Line, line2:lib_flex_book_com_rubenswieringa_geom_Line):Point { var intersect:Point = Infinitelib_flex_book_com_rubenswieringa_geom_Line.getIntersection(line1, line2); if (!line1.containsPoint(intersect) || !line2.containsPoint(intersect)){ return null; }else{ return intersect; } } /** * Creates a lib_flex_book_com_rubenswieringa_geom_Line from an Infinitelib_flex_book_com_rubenswieringa_geom_Line instance. * * @param line Infinitelib_flex_book_com_rubenswieringa_geom_Line * @param range Distance between both ends of the returned lib_flex_book_com_rubenswieringa_geom_Line and the x-intersection of the Infinitelib_flex_book_com_rubenswieringa_geom_Line. Consequently, the returned lib_flex_book_com_rubenswieringa_geom_Line instance its length will be twice the value of the range parameter. * * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#xIntersection * * @return lib_flex_book_com_rubenswieringa_geom_Line. */ public static function createFromInfinite (line:Infinitelib_flex_book_com_rubenswieringa_geom_Line, range:Number=100):lib_flex_book_com_rubenswieringa_geom_Line { var point1:Point; var point2:Point; if (!line.horizontal){ point1 = new Point(line.xIntersection, 0); point2 = new Point(line.xIntersection+1, line.xCoefficient); }else{ point1 = new Point(0, line.yIntersection); point2 = new Point(line.yCoefficient, line.yIntersection+1); } var angle:Number = line.getAngle(); // calculate ends: var newlib_flex_book_com_rubenswieringa_geom_Line:lib_flex_book_com_rubenswieringa_geom_Line = new lib_flex_book_com_rubenswieringa_geom_Line(); newlib_flex_book_com_rubenswieringa_geom_Line.a = new Point(point1.x + range * Math.cos(angle), point1.y + range * Math.sin(angle)); angle += Math.PI; newlib_flex_book_com_rubenswieringa_geom_Line.b = new Point(point1.x + range * Math.cos(angle), point1.y + range * Math.sin(angle)); // return value: return newlib_flex_book_com_rubenswieringa_geom_Line; } /** * Returns an Array if which the first index and second (0 and 1) indexes are (respectively) the lib_flex_book_com_rubenswieringa_geom_Line its first and second Points (a and b). * * @return Array */ public function toArray ():Array { return [this.a, this.b]; } /** * The String representation of this lib_flex_book_com_rubenswieringa_geom_Line instance. * * @return String */ override public function toString ():String { return "lib_flex_book_com_rubenswieringa_geom_Line(("+this.a.x+","+this.a.y+")->("+this.b.x+","+this.b.y+"))"; } /** * Sets both ends of this lib_flex_book_com_rubenswieringa_geom_Line instance equal to the values of the respective parameter values. This method does nothing more than setting the values of the a and b properties. * * @param a lib_flex_book_com_rubenswieringa_geom_Line's first Point. * @param b lib_flex_book_com_rubenswieringa_geom_Line's second Point. * * @see lib_flex_book_com_rubenswieringa_geom_Line#a * @see lib_flex_book_com_rubenswieringa_geom_Line#b * */ override public function syncToPoints (a:Point, b:Point):void { this.a = a; this.b = b; } /** * Returns a cloned instance of this lib_flex_book_com_rubenswieringa_geom_Line. * * @return lib_flex_book_com_rubenswieringa_geom_Line */ override public function clone ():* { return new lib_flex_book_com_rubenswieringa_geom_Line(this.a, this.b); } /** * Returns true if the provided coordinate is on this lib_flex_book_com_rubenswieringa_geom_Line. * * @param point Point instance representing a coordinate. * @param round Boolean indicating whether or not to round values before making equations. * * @see lib_flex_book_com_rubenswieringa_geom_Line#containslib_flex_book_com_rubenswieringa_geom_Line() * * @returns Boolean */ override public function containsPoint (point:Point, round:Boolean=true):Boolean { // coordinate can't be on this lib_flex_book_com_rubenswieringa_geom_Line if both Points in this lib_flex_book_com_rubenswieringa_geom_Line are on one side of the coordinate: if ((point.x < this.a.x && point.x < this.b.x) || (point.x > this.a.x && point.x > this.b.x) || (point.y < this.a.y && point.y < this.b.y) || (point.y > this.a.y && point.y > this.b.y) ){ return false; } // invoke super: return super.containsPoint(point, round); } /** * Returns true if the provided lib_flex_book_com_rubenswieringa_geom_Line is in this lib_flex_book_com_rubenswieringa_geom_Line. Note that true is only returned if both Points of the provided lib_flex_book_com_rubenswieringa_geom_Line instance are on this lib_flex_book_com_rubenswieringa_geom_Line. * * @param line lib_flex_book_com_rubenswieringa_geom_Line * @param round Boolean indicating whether or not to round values before making equations. * * @see lib_flex_book_com_rubenswieringa_geom_Line#containslib_flex_book_com_rubenswieringa_geom_LinePartially() * @see lib_flex_book_com_rubenswieringa_geom_Line#containsPoint() * @see lib_flex_book_com_rubenswieringa_geom_Line#equals() * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#isParallelTo() * * @returns Boolean */ public function containslib_flex_book_com_rubenswieringa_geom_Line (line:lib_flex_book_com_rubenswieringa_geom_Line, round:Boolean=true):Boolean { return (this.containsPoint(line.a, round) && this.containsPoint(line.b, round)); } /** * Returns true if the provided lib_flex_book_com_rubenswieringa_geom_Line is partially in this lib_flex_book_com_rubenswieringa_geom_Line. * * @param line lib_flex_book_com_rubenswieringa_geom_Line * @param round Boolean indicating whether or not to round values before making equations. * * @see lib_flex_book_com_rubenswieringa_geom_Line#containslib_flex_book_com_rubenswieringa_geom_Line() * @see lib_flex_book_com_rubenswieringa_geom_Line#containsPoint() * @see lib_flex_book_com_rubenswieringa_geom_Line#equals() * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#isParallelTo() * * @returns Boolean */ public function containslib_flex_book_com_rubenswieringa_geom_LinePartially (line:lib_flex_book_com_rubenswieringa_geom_Line, round:Boolean=true):Boolean { return ((this.containsPoint(line.a, round) || this.containsPoint(line.b, round)) && this.xCoefficient == line.xCoefficient); } /** * Returns true if the provided lib_flex_book_com_rubenswieringa_geom_Line instance is equal to this lib_flex_book_com_rubenswieringa_geom_Line. * * @param line lib_flex_book_com_rubenswieringa_geom_Line * @param round Boolean indicating whether or not to round values before making equations. * * @see lib_flex_book_com_rubenswieringa_geom_Line#containslib_flex_book_com_rubenswieringa_geom_Line() * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#isParallelTo() * * @return Boolean */ override public function equals (line:Infinitelib_flex_book_com_rubenswieringa_geom_Line, round:Boolean=true):Boolean { if (line is lib_flex_book_com_rubenswieringa_geom_Line){ var castlib_flex_book_com_rubenswieringa_geom_Line:lib_flex_book_com_rubenswieringa_geom_Line = lib_flex_book_com_rubenswieringa_geom_Line(line); var a1:Point = (round) ? SuperPoint.round(this.a) : this.a; var b1:Point = (round) ? SuperPoint.round(this.b) : this.b; var a2:Point = (round) ? SuperPoint.round(castlib_flex_book_com_rubenswieringa_geom_Line.a) : castlib_flex_book_com_rubenswieringa_geom_Line.a; var b2:Point = (round) ? SuperPoint.round(castlib_flex_book_com_rubenswieringa_geom_Line.b) : castlib_flex_book_com_rubenswieringa_geom_Line.b; return ((a1.equals(a2) && b1.equals(b2)) || (a1.equals(b2) && b1.equals(a2))); }else{ return super.equals(line); } } /** * The outcome of Point B its x-position minus Point A its x-position. * @see lib_flex_book_com_rubenswieringa_geom_Line#diffY */ public function get diffX ():Number { return this.b.x - this.a.x; } /** * The outcome of Point B its y-position minus Point A its y-position. * @see lib_flex_book_com_rubenswieringa_geom_Line#diffY */ public function get diffY ():Number { return this.b.y - this.a.y; } /** * The exact center of the first and second Points of this lib_flex_book_com_rubenswieringa_geom_Line. */ public function get middle ():Point { return Point.interpolate(this.a, this.b, 0.5); } /** * lib_flex_book_com_rubenswieringa_geom_Line's first Point. */ public function get a ():Point { return this._a; } public function set a (point:Point):void { this._a = point; super.syncToPoints(this.a, this.b); } /** * lib_flex_book_com_rubenswieringa_geom_Line's second Point. */ public function get b ():Point { return this._b; } public function set b (point:Point):void { this._b = point; super.syncToPoints(this.a, this.b); } /** * @inheritdoc * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#xIntersection */ override public function get xIntersection ():Number { return super.xIntersection; } override public function set xIntersection (value:Number):void { this._a.x += value - this._xIntersection; this._b.x += value - this._xIntersection; this.setXIntersection(value); } /** * @inheritdoc * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#yIntersection */ override public function get yIntersection ():Number { return super.yIntersection; } override public function set yIntersection (value:Number):void { this._a.y += value - this._yIntersection; this._b.y += value - this._yIntersection; this.setYIntersection(value); } /** * @inheritdoc * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#xCoefficient */ override public function get xCoefficient ():Number { return super.xCoefficient; } override public function set xCoefficient (value:Number):void { // remember distances between both ends and the intersection with the x-axis: var xIntersect:Point = new Point(this.xIntersection, 0); var dist1:Number = Point.distance(this.a, xIntersect); var dist2:Number = Point.distance(this.b, xIntersect); // set property: this.setXCoefficient(value); // reposition both ends of this lib_flex_book_com_rubenswieringa_geom_Line: var angle:Number = this.getAngle(); angle += Math.PI; this._a = new Point(xIntersect.x + dist1 * Math.cos(angle), xIntersect.y + dist1 * Math.sin(angle)); angle += Math.PI; this._b = new Point(xIntersect.x + dist2 * Math.cos(angle), xIntersect.y + dist2 * Math.sin(angle)); } /** * @inheritdoc * @see Infinitelib_flex_book_com_rubenswieringa_geom_Line#yCoefficient */ override public function get yCoefficient ():Number { return super.yCoefficient; } override public function set yCoefficient (value:Number):void { // remember distances between both ends and the intersection with the x-axis: var xIntersect:Point = new Point(this.xIntersection, 0); var dist1:Number = Point.distance(this.a, xIntersect); var dist2:Number = Point.distance(this.b, xIntersect); // set property: this.setYCoefficient(value); // reposition both ends of this lib_flex_book_com_rubenswieringa_geom_Line: var angle:Number = this.getAngle(); angle += Math.PI; this._a = new Point(xIntersect.x + dist1 * Math.cos(angle), xIntersect.y + dist1 * Math.sin(angle)); angle += Math.PI; this._b = new Point(xIntersect.x + dist2 * Math.cos(angle), xIntersect.y + dist2 * Math.sin(angle)); } } }