├── .gitignore ├── README ├── lib ├── AsUnit-4.1.2.swc ├── as3-signals.swc └── robotlegs-framework-v1.0.0.swc ├── src ├── alecmce │ ├── data │ │ ├── bitwise │ │ │ ├── BitField.as │ │ │ ├── BitFieldBase.as │ │ │ └── BitFieldUtil.as │ │ └── graph │ │ │ ├── DirectedAcyclicGraph.as │ │ │ ├── DirectedGraph.as │ │ │ ├── Graph.as │ │ │ ├── GraphJoin.as │ │ │ └── algorithms │ │ │ ├── BellmanFord.as │ │ │ └── Dijkstra.as │ ├── invalidation │ │ ├── Invalidates.as │ │ ├── InvalidatesVO.as │ │ ├── InvalidationManager.as │ │ └── signals │ │ │ └── InvalidationSignal.as │ ├── math │ │ └── Primes.as │ └── ui │ │ ├── Paint.as │ │ ├── interactive │ │ └── DragMechanism.as │ │ ├── paint │ │ └── SolidPaint.as │ │ └── util │ │ └── UIArcHelper.as ├── as3geometry │ ├── AS3GeometryContext.as │ ├── AdditiveCollection.as │ ├── abstract │ │ ├── AbstractMutableAdditiveCollection.as │ │ └── Mutable.as │ ├── errors │ │ └── MutabilityError.as │ └── geom2D │ │ ├── Angle.as │ │ ├── Circle.as │ │ ├── CircleSector.as │ │ ├── CircleSegment.as │ │ ├── CollectionOfPolygons.as │ │ ├── CollectionOfVertices.as │ │ ├── InteractiveVertex.as │ │ ├── Line.as │ │ ├── LineType.as │ │ ├── Parabola.as │ │ ├── Polygon.as │ │ ├── SpatialVector.as │ │ ├── Triangle.as │ │ ├── Vertex.as │ │ ├── VertexOnCircle.as │ │ ├── VertexOnLine.as │ │ ├── VertexOnParabola.as │ │ ├── angle │ │ └── MutableAngleFromVectors.as │ │ ├── circle │ │ ├── ImmutableCircle.as │ │ ├── MutableCircle.as │ │ ├── MutableCircleSector.as │ │ ├── MutableCircleSegment.as │ │ ├── MutableCircleWithRadialVertex.as │ │ └── errors │ │ │ └── SegmentDefinitionError.as │ │ ├── intersection │ │ ├── CircleAndLineIntersectionVertex.as │ │ ├── IntersectionOfCircleAndLine.as │ │ └── IntersectionsOfLineAndPolygon.as │ │ ├── line │ │ ├── ImmutableLine.as │ │ ├── IntersectionOfTwoLinesVertex.as │ │ ├── MutableLine.as │ │ └── VertexProjectedToLine.as │ │ ├── parabola │ │ ├── ImmutableParabola.as │ │ └── MutableParabola.as │ │ ├── polygons │ │ ├── ImmutablePolygon.as │ │ ├── ImmutableTriangle.as │ │ ├── MutablePolygon.as │ │ ├── MutableTriangle.as │ │ ├── intersection │ │ │ ├── ExpandedPolygonVectors.as │ │ │ ├── ExpandedPolygonVertex.as │ │ │ ├── IntersectionOfTwoPolygons.as │ │ │ ├── IntersectionPolygon.as │ │ │ ├── OrignalPolygonVertexWrapper.as │ │ │ ├── PotentialIntersectionVertex.as │ │ │ └── SortedPolygonVectors.as │ │ └── test │ │ │ ├── ExpandedPolygonVertex.as │ │ │ ├── OrignalPolygonVertexWrapper.as │ │ │ ├── PotentialIntersectionVertex.as │ │ │ ├── TestIntersectionOfPolygons.as │ │ │ └── TestIntersectionPolygon.as │ │ ├── ui │ │ ├── CircleDrawer.as │ │ ├── CircleSectorDrawer.as │ │ ├── CircleSegmentDrawer.as │ │ ├── DEFAULT_PAINT.as │ │ ├── LineDrawer.as │ │ ├── ParabolaDrawer.as │ │ ├── PolygonDrawer.as │ │ ├── PolygonsDrawer.as │ │ ├── TriangleDrawer.as │ │ ├── VertexDrawer.as │ │ ├── generic │ │ │ ├── UIDrawer.as │ │ │ └── UIMutableSprite.as │ │ └── vertices │ │ │ ├── UIVertex.as │ │ │ ├── UIVertexOnCircle.as │ │ │ └── UIVertexOnParabola.as │ │ ├── util │ │ ├── AngleHelper.as │ │ ├── LineHelper.as │ │ ├── ParabolaHelper.as │ │ └── PolygonHelper.as │ │ ├── vectors │ │ └── ImmutableSpatialVector.as │ │ └── vertices │ │ ├── ImmutableVertex.as │ │ ├── IndependentVertex.as │ │ ├── ProjectVertexToCircle.as │ │ └── VertexOnCircle.as └── examples │ ├── CircleSectorByVertices.as │ ├── CircleSegmentByVertices.as │ ├── CircleSegmentFromCircleAndLine.as │ ├── ExampleBaseSprite.as │ ├── IntersectCircleAndLine.as │ ├── IntersectLineAndLine.as │ ├── IntersectTwoQuadrilaterals.as │ ├── IntersectTwoQuadrilateralsWithOppositeDirections.as │ ├── ParabolaFromLineAndVertex.as │ ├── ParabolaFromSegmentAndVertex.as │ ├── ThreePoints.as │ └── VertexOnParabolaExample.as ├── test ├── AllTests.as ├── ProjectTestRunner.as ├── alecmce │ ├── data │ │ ├── AllDataTests.as │ │ └── graph │ │ │ ├── AllDataGraphTests.as │ │ │ ├── DirectedAcyclicGraphTest.as │ │ │ ├── DirectedGraphTest.as │ │ │ ├── GraphTest.as │ │ │ ├── MockGraphNode.as │ │ │ └── algorithms │ │ │ ├── AllDataGraphAlgorithmsTests.as │ │ │ └── DijkstraTest.as │ ├── invalidation │ │ ├── AllInvalidationTests.as │ │ ├── ExampleInvalidator.as │ │ └── InvalidateTest.as │ └── math │ │ ├── AllMathTests.as │ │ └── PrimesTest.as └── as3geometry │ ├── AS3GeometryTestRunner.as │ ├── AllGeometryTests.as │ └── geom2D │ ├── AllGeom2DTests.as │ ├── immutable │ ├── AllImmutableTests.as │ ├── ImmutableCircleTest.as │ ├── ImmutableLineTest.as │ ├── ImmutablePolygonTest.as │ └── ImmutableTriangleTest.as │ ├── intersection │ ├── AllIntersectionTests.as │ ├── IntersectionOfTwoLinesVertexTest.as │ ├── IntersectionOfTwoPolygonsTest.as │ └── IntersectionsOfLineAndPolygonTest.as │ ├── mutable │ ├── AllMutableTests.as │ └── MutableAnglesFromVectorsTest.as │ └── util │ ├── AllUtilTests.as │ └── PolygonHelperTest.as └── tmp ├── QuadraticBezier.as └── TestQuadraticBezier.as /.gitignore: -------------------------------------------------------------------------------- 1 | .as3_classpath 2 | .project 3 | .settings 4 | bin 5 | 6 | *.swf -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | AS3 Geometry is a place for me to place my geometry classes. Over the years I've created innumerable geometry implementations, and I am looking to create a definitive collection. 2 | 3 | Principles: 4 | 5 | # Types of objects are defined by interfaces 6 | # Objects have at least one implementation which is immutable; the defining data are unchangable after construction. 7 | # Objecst may have another implementation which is mutable. Mutable objects require an AS3GeometryContext injection. The context helps manage the invalidation of elements and their redrawing. This tweak removes the problem of updates happening on different frames. -------------------------------------------------------------------------------- /lib/AsUnit-4.1.2.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alecmce/as3geometry/3c425a5b31fbd937440687b6c10fe652cc5418ef/lib/AsUnit-4.1.2.swc -------------------------------------------------------------------------------- /lib/as3-signals.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alecmce/as3geometry/3c425a5b31fbd937440687b6c10fe652cc5418ef/lib/as3-signals.swc -------------------------------------------------------------------------------- /lib/robotlegs-framework-v1.0.0.swc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alecmce/as3geometry/3c425a5b31fbd937440687b6c10fe652cc5418ef/lib/robotlegs-framework-v1.0.0.swc -------------------------------------------------------------------------------- /src/alecmce/data/bitwise/BitField.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.bitwise 2 | { 3 | 4 | public class BitField 5 | { 6 | private var _vector:Vector.; 7 | 8 | public function BitField() 9 | { 10 | _vector = new Vector.(); 11 | _vector[0] = 0; 12 | } 13 | 14 | public function get length():uint 15 | { 16 | return _vector.length << 5; 17 | } 18 | 19 | public function getBit(position:uint):Boolean 20 | { 21 | var index:uint = position >> 5; 22 | var bit:uint = 1 << (position % 32); 23 | 24 | if (_vector.length <= index) 25 | return false; 26 | 27 | return Boolean(_vector[index] & bit); 28 | } 29 | 30 | public function setBit(position:uint, value:Boolean):void 31 | { 32 | if (position == -1) 33 | throw new Error("invalid bit position -1"); 34 | 35 | var index:uint = position >> 5; 36 | var bit:uint = 1 << (position % 32); 37 | 38 | while (_vector.length <= index) 39 | _vector.push(0); 40 | 41 | var current:uint = _vector[index]; 42 | _vector[index] = value ? current | bit : ~(~current | bit); 43 | } 44 | 45 | public function serialize(base:BitFieldBase):String 46 | { 47 | var strings:Vector. = new Vector.(); 48 | 49 | switch (base) 50 | { 51 | case BitFieldBase.BASE_2: 52 | case BitFieldBase.BASE_16: 53 | var length:uint = _vector.length; 54 | for (var i:int = 0;i < length;i++) 55 | strings.unshift(base.encode(_vector[i])); 56 | 57 | break; 58 | 59 | default: 60 | throw new Error("base not supported in seralize method"); 61 | break; 62 | } 63 | 64 | return strings.join(""); 65 | } 66 | 67 | public function deserialize(value:String, base:BitFieldBase):void 68 | { 69 | _vector = new Vector.(); 70 | 71 | switch (base) 72 | { 73 | case BitFieldBase.BASE_2: 74 | case BitFieldBase.BASE_16: 75 | var firstChar:uint = 0; 76 | var charsPer32Bit:uint = base.charsPer32Bit; 77 | var length:uint = Math.ceil(value.length / charsPer32Bit); 78 | 79 | for (var i:int = 0;i < length;i++) 80 | { 81 | var string:String = value.substr(firstChar, charsPer32Bit); 82 | firstChar += charsPer32Bit; 83 | _vector.push(base.decode(string)); 84 | } 85 | 86 | break; 87 | 88 | default: 89 | throw new Error("base not supported in deseralize method"); 90 | break; 91 | } 92 | } 93 | 94 | public function clone():BitField 95 | { 96 | var field:BitField = new BitField(); 97 | field._vector = _vector.concat(); 98 | 99 | return field; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/alecmce/data/bitwise/BitFieldBase.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.bitwise 2 | { 3 | 4 | public class BitFieldBase 5 | { 6 | 7 | public static const BASE_16:BitFieldBase = new BitFieldBase(16); public static const BASE_2:BitFieldBase = new BitFieldBase(2); 8 | 9 | private var _radix:uint; 10 | private var _charsPer32Bit:uint; 11 | 12 | public function BitFieldBase(radix:uint) 13 | { 14 | _radix = radix; 15 | _charsPer32Bit = 32 / (1 << Math.log(radix)); 16 | } 17 | 18 | public function encode(value:uint):String 19 | { 20 | var chars:Array = value.toString(_radix).split(""); 21 | var len:uint = chars.length; 22 | while (len++ < _charsPer32Bit) 23 | chars.unshift(0); 24 | 25 | return chars.join(""); 26 | } 27 | 28 | public function decode(value:String):uint 29 | { 30 | return parseInt(value, _radix); 31 | } 32 | 33 | public function get charsPer32Bit():uint 34 | { 35 | return _charsPer32Bit; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/alecmce/data/bitwise/BitFieldUtil.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.bitwise 2 | { 3 | 4 | public class BitFieldUtil 5 | { 6 | /** 7 | * performs a bitwise disjunction (logical OR) on two bitfields and 8 | * returns a new BitField as a result 9 | */ 10 | public function or(a:BitField, b:BitField):BitField 11 | { 12 | var result:BitField = a.clone(); 13 | var length:uint = b.length; 14 | 15 | for (var i:int = 0; i < length; i++) 16 | { 17 | if (b.getBit(i)) 18 | result.setBit(i, true); 19 | } 20 | 21 | return result; 22 | } 23 | 24 | /** 25 | * performs a bitwise disjunction (logical OR) on two bitfields, changing 26 | * the first bitfield as a result 27 | */ 28 | public function merge_or(mutable:BitField, argument:BitField):void 29 | { 30 | var length:uint = argument.length; 31 | for (var i:int = 0; i < length; i++) 32 | { 33 | if (argument.getBit(i)) 34 | mutable.setBit(i, true); 35 | } 36 | } 37 | 38 | /** 39 | * performs a bitwise conjunction (logical AND) on two bitfields and 40 | * returns a new BitField as a result 41 | */ 42 | public function and(a:BitField, b:BitField):BitField 43 | { 44 | var result:BitField = a.clone(); 45 | var length:uint = b.length; 46 | 47 | for (var i:int = 0; i < length; i++) 48 | { 49 | if (result.getBit(i) && !b.getBit(i)) 50 | result.setBit(i, false); 51 | } 52 | 53 | return result; 54 | } 55 | 56 | /** 57 | * performs a bitwise conjunction (logical AND) on two bitfields, changing 58 | * the first bitfield as a result 59 | */ 60 | public function merge_and(mutable:BitField, argument:BitField):void 61 | { 62 | var length:uint = argument.length; 63 | for (var i:int = 0; i < length; i++) 64 | { 65 | if (mutable.getBit(i) && !argument.getBit(i)) 66 | mutable.setBit(i, false); 67 | } 68 | } 69 | 70 | /** 71 | * a b carry result carry 72 | * 0 0 0 0 (0) 73 | * 0 0 1 1 (0) 74 | * 0 1 0 1 (0) 2nd condition 75 | * 0 1 1 0 (1) 2nd condition 76 | * 1 0 0 1 (0) 2nd condition 77 | * 1 0 1 0 (1) 2nd condition 78 | * 1 1 0 0 (1) first condition 79 | * 1 1 1 1 (1) first condition 80 | */ 81 | public function add(a:BitField, b:BitField):BitField 82 | { 83 | var aLength:uint = a.length; 84 | var bLength:uint = b.length; 85 | var length:uint = aLength > bLength ? aLength : bLength; 86 | var result:BitField = new BitField(); 87 | var carry:Boolean = false; 88 | 89 | for (var i:int = 0; i < length; i++) 90 | { 91 | var aBit:Boolean = a.getBit(i); 92 | var bBit:Boolean = b.getBit(i); 93 | 94 | if (aBit && bBit) // when both are true 95 | { 96 | result.setBit(i, carry); 97 | carry = true; 98 | } 99 | else if (aBit || bBit) // when one is true 100 | { 101 | result.setBit(i, !carry); 102 | } 103 | else 104 | { 105 | result.setBit(i, carry); 106 | carry = false; 107 | } 108 | } 109 | 110 | if (carry) 111 | result.setBit(length, true); 112 | 113 | return result; 114 | } 115 | 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/alecmce/data/graph/DirectedAcyclicGraph.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | import alecmce.data.bitwise.BitField; 4 | import alecmce.data.bitwise.BitFieldUtil; 5 | 6 | import flash.utils.Dictionary; 7 | 8 | public class DirectedAcyclicGraph extends DirectedGraph 9 | { 10 | private var _util:BitFieldUtil; 11 | private var _reverseJoinReferences:Dictionary; 12 | 13 | public function DirectedAcyclicGraph() 14 | { 15 | super(); 16 | 17 | _util = new BitFieldUtil(); 18 | _reverseJoinReferences = new Dictionary(); 19 | } 20 | 21 | override public function joinNodes(a:Object, b:Object, cost:Number = 1):void 22 | { 23 | var bitA:int = registerNode(a); 24 | var bitB:int = registerNode(b); 25 | 26 | var fieldA:BitField = _reverseJoinReferences[a]; 27 | if (!fieldA) 28 | _reverseJoinReferences[a] = fieldA = new BitField(); 29 | 30 | if (fieldA.getBit(bitB)) 31 | throw new Error("Attempted join would create a cyclic graph"); 32 | 33 | fieldA = fieldA.clone(); 34 | fieldA.setBit(bitA, true); 35 | 36 | assignBits(b, fieldA); 37 | super.joinNodes(a, b, cost); 38 | } 39 | 40 | private function assignBits(b:Object, fieldA:BitField):void 41 | { 42 | var fieldB:BitField = _reverseJoinReferences[b]; 43 | if (fieldB) 44 | fieldB = _util.or(fieldA, fieldB); 45 | else 46 | fieldB = fieldA.clone(); 47 | 48 | _reverseJoinReferences[b] = fieldB; 49 | 50 | var joins:Vector. = _joinMap[b]; 51 | for each (var join:GraphJoin in joins) 52 | assignBits(join.destination, fieldA); 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/alecmce/data/graph/DirectedGraph.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | public class DirectedGraph extends Graph 4 | { 5 | public function DirectedGraph() 6 | { 7 | super(); 8 | } 9 | 10 | override public function joinNodes(a:Object, b:Object, cost:Number = 1):void 11 | { 12 | registerNode(a); 13 | registerNode(b); 14 | 15 | var joins:Vector. = (_joinMap[a] ||= new Vector.()); 16 | var join:GraphJoin = new GraphJoin(a, b, cost); 17 | 18 | joins.push(join); 19 | _joins.push(join); 20 | } 21 | 22 | override public function areJoined(a:Object, b:Object):Boolean 23 | { 24 | var joins:Vector. = _joinMap[a]; 25 | if (!joins) 26 | return false; 27 | 28 | var len:uint = joins.length; 29 | for (var i:uint = 0; i < len; i++) 30 | { 31 | if (joins[i].destination == b) 32 | return true; 33 | } 34 | 35 | return false; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/alecmce/data/graph/Graph.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | import flash.utils.Dictionary; 4 | 5 | public class Graph 6 | { 7 | protected var _nodes:Vector.; 8 | protected var _joins:Vector.; 9 | protected var _joinMap:Dictionary; 10 | 11 | public function Graph() 12 | { 13 | _nodes = new Vector.(); 14 | _joins = new Vector.(); 15 | _joinMap = new Dictionary(); 16 | } 17 | 18 | public function getJoins(node:Object):Vector. 19 | { 20 | return _joinMap[node] ||= new Vector.(); 21 | } 22 | 23 | public function get nodes():Vector. 24 | { 25 | return _nodes; 26 | } 27 | 28 | public function get joins():Vector. 29 | { 30 | return _joins; 31 | } 32 | 33 | public function joinNodes(a:Object, b:Object, cost:Number = 1):void 34 | { 35 | registerNode(a); 36 | registerNode(b); 37 | 38 | var joinsA:Vector. = getJoins(a); 39 | var joinsB:Vector. = getJoins(b); 40 | var join:GraphJoin = new GraphJoin(a, b, cost); 41 | 42 | joinsA.push(join); joinsB.push(join); 43 | _joins.push(join); 44 | } 45 | 46 | protected function registerNode(a:Object):int 47 | { 48 | var i:int = _nodes.indexOf(a); 49 | 50 | if (i == -1) 51 | { 52 | i = _nodes.length; 53 | _nodes.push(a); 54 | } 55 | 56 | return i; 57 | } 58 | 59 | public function areJoined(a:Object, b:Object):Boolean 60 | { 61 | var joins:Vector. = _joinMap[a]; 62 | if (!joins) 63 | return false; 64 | 65 | var len:uint = joins.length; 66 | for (var i:uint = 0; i < len; i++) 67 | { 68 | if (joins[i].source == b || joins[i].destination == b) 69 | return true; 70 | } 71 | 72 | return false; 73 | } 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/alecmce/data/graph/GraphJoin.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | 4 | /** 5 | * @author amceachran 6 | */ 7 | public class GraphJoin 8 | { 9 | private var _source:Object; private var _destination:Object; 10 | private var _cost:Number; 11 | 12 | public function GraphJoin(source:Object, destination:Object, cost:Number) 13 | { 14 | _source = source; 15 | _destination = destination; 16 | _cost = cost; 17 | } 18 | 19 | public function get source():Object 20 | { 21 | return _source; 22 | } 23 | 24 | public function get destination():Object 25 | { 26 | return _destination; 27 | } 28 | 29 | public function get cost():Number 30 | { 31 | return _cost; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/alecmce/data/graph/algorithms/BellmanFord.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph.algorithms 2 | { 3 | import alecmce.data.graph.DirectedGraph; 4 | import alecmce.data.graph.GraphJoin; 5 | 6 | import flash.utils.Dictionary; 7 | 8 | /** 9 | * Discovers the shortest-path from an initial node to all other nodes within 10 | * a graph using the Bellman-Ford Algorithm 11 | * 12 | * TODO An efficiency improvement to Bellman-Ford exists, called Yen's 13 | * improvement. This has not yet been implemented. 14 | * 15 | * @see http://en.wikipedia.org/wiki/Bellman-Ford_algorithm 16 | */ 17 | public class BellmanFord 18 | { 19 | 20 | private var _costs:Dictionary; 21 | private var _previous:Dictionary; 22 | private var _graph:DirectedGraph; 23 | 24 | private var _isReset:Boolean; 25 | 26 | public function BellmanFord() 27 | { 28 | reset(); 29 | } 30 | 31 | public function reset():void 32 | { 33 | if (_isReset) 34 | return; 35 | 36 | _costs = new Dictionary(); 37 | _previous = new Dictionary(); 38 | _graph = null; 39 | _isReset = true; 40 | } 41 | 42 | public function apply(graph:DirectedGraph, initial:Object):void 43 | { 44 | if (!_isReset) 45 | reset(); 46 | 47 | _graph = graph; 48 | setInitialCosts(initial); 49 | 50 | var len:uint = _graph.nodes.length; 51 | var joins:Vector. = _graph.joins; 52 | for (var i:int = 0; i < len; i++) 53 | findCosts(joins); 54 | 55 | _isReset = false; 56 | } 57 | 58 | public function getCost(node:Object):Number 59 | { 60 | return _costs[node]; 61 | } 62 | 63 | public function getRoute(node:Object):Vector. 64 | { 65 | var nodes:Vector. = new Vector.(); 66 | 67 | nodes[0] = node; 68 | 69 | while (_previous[node]) 70 | { 71 | node = _previous[node]; 72 | nodes.push(node); 73 | } 74 | 75 | return nodes.reverse(); 76 | } 77 | 78 | public function get graph():DirectedGraph 79 | { 80 | return _graph; 81 | } 82 | 83 | private function setInitialCosts(initial:Object):void 84 | { 85 | var nodes:Vector. = _graph.nodes; 86 | 87 | for each (var node:Object in nodes) 88 | _costs[node] = Number.POSITIVE_INFINITY; 89 | 90 | _costs[initial] = 0; 91 | } 92 | 93 | private function findCosts(joins:Vector.):void 94 | { 95 | for each (var join:GraphJoin in joins) 96 | { 97 | var source:Object = join.source; 98 | var destination:Object = join.destination; 99 | 100 | var cost:Number = _costs[source] + join.cost; 101 | if (cost < _costs[destination]) 102 | { 103 | _costs[destination] = cost; 104 | _previous[destination] = source; 105 | } 106 | } 107 | } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/alecmce/data/graph/algorithms/Dijkstra.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph.algorithms 2 | { 3 | import alecmce.data.graph.DirectedGraph; 4 | import alecmce.data.graph.GraphJoin; 5 | 6 | import flash.utils.Dictionary; 7 | 8 | /** 9 | * Discovers the shortest-path from an initial node to all other nodes within 10 | * a graph using the Dijkstra Algorithm. 11 | * 12 | * @see http://en.wikipedia.org/wiki/Dijkstra's_algorithm 13 | */ 14 | public class Dijkstra 15 | { 16 | private var _costs:Dictionary; 17 | private var _visited:Dictionary; 18 | private var _previous:Dictionary; 19 | private var _graph:DirectedGraph; 20 | 21 | private var _isReset:Boolean; 22 | 23 | public function Dijkstra() 24 | { 25 | reset(); 26 | } 27 | 28 | public function reset():void 29 | { 30 | if (_isReset) 31 | return; 32 | 33 | _costs = new Dictionary(); 34 | _visited = new Dictionary(); 35 | _previous = new Dictionary(); _graph = null; 36 | _isReset = true; 37 | } 38 | 39 | public function apply(graph:DirectedGraph, initial:Object):void 40 | { 41 | if (!_isReset) 42 | reset(); 43 | 44 | _graph = graph; 45 | setInitialCosts(initial); 46 | findCosts(initial); 47 | _isReset = false; 48 | } 49 | 50 | public function getCost(node:Object):Number 51 | { 52 | return _costs[node]; 53 | } 54 | 55 | public function getRoute(node:Object):Vector. 56 | { 57 | var nodes:Vector. = new Vector.(); 58 | 59 | nodes[0] = node; 60 | 61 | while (_previous[node]) 62 | { 63 | node = _previous[node]; 64 | nodes.push(node); 65 | } 66 | 67 | return nodes.reverse(); 68 | } 69 | 70 | public function get graph():DirectedGraph 71 | { 72 | return _graph; 73 | } 74 | 75 | private function setInitialCosts(initial:Object):void 76 | { 77 | var nodes:Vector. = _graph.nodes; 78 | var len:uint = nodes.length; 79 | 80 | for (var i:uint = 0; i < len; i++) 81 | _costs[nodes[i]] = Number.POSITIVE_INFINITY; 82 | 83 | _costs[initial] = 0; 84 | } 85 | 86 | private function findCosts(current:Object):void 87 | { 88 | var nearestNeighbour:Object; 89 | var lowestCostToNeighbour:Number; 90 | 91 | var joins:Vector. = _graph.getJoins(current); 92 | var len:uint = joins.length; 93 | 94 | for (var i:uint = 0; i < len; i++) 95 | { 96 | var join:GraphJoin = joins[i]; 97 | var target:Object = join.destination; 98 | var cost:Number = join.cost; 99 | if (cost < 0) 100 | throw new Error("Dijkstra's Algorithm functions only if the join costs are positive. Use Bellman-Ford for graphs with negative costs"); 101 | 102 | if (_visited[target]) 103 | continue; 104 | 105 | cost += _costs[current]; 106 | if (_costs[target] != null && cost < _costs[target]) 107 | _costs[target] = cost; 108 | 109 | if (nearestNeighbour == null || cost < lowestCostToNeighbour) 110 | { 111 | lowestCostToNeighbour = cost; 112 | nearestNeighbour = target; 113 | _previous[target] = current; 114 | } 115 | } 116 | 117 | _visited[current] = true; 118 | if (nearestNeighbour) 119 | findCosts(nearestNeighbour); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /src/alecmce/invalidation/Invalidates.as: -------------------------------------------------------------------------------- 1 | package alecmce.invalidation 2 | { 3 | import alecmce.invalidation.signals.InvalidationSignal; 4 | 5 | public interface Invalidates 6 | { 7 | function invalidate(resolveImmediately:Boolean = false):void; 8 | 9 | function get invalidated():InvalidationSignal; 10 | 11 | function get isInvalid():Boolean; 12 | 13 | function resolve():void; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/alecmce/invalidation/InvalidatesVO.as: -------------------------------------------------------------------------------- 1 | package alecmce.invalidation 2 | { 3 | internal class InvalidatesVO 4 | { 5 | 6 | public var target:Invalidates; 7 | public var dependencies:Vector.; public var dependees:Vector.; 8 | public var tier:uint; 9 | 10 | public var isInvalidated:Boolean; 11 | 12 | public function InvalidatesVO(target:Invalidates) 13 | { 14 | this.target = target; 15 | this.dependencies = new Vector.(); this.dependees = new Vector.(); 16 | this.tier = 0; 17 | 18 | this.isInvalidated = false; 19 | } 20 | 21 | public function resolve():void 22 | { 23 | isInvalidated = false; 24 | target.resolve(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/alecmce/invalidation/signals/InvalidationSignal.as: -------------------------------------------------------------------------------- 1 | package alecmce.invalidation.signals 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | 5 | import org.osflash.signals.Signal; 6 | 7 | public class InvalidationSignal extends Signal 8 | { 9 | public function InvalidationSignal() 10 | { 11 | super(Invalidates); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/alecmce/ui/Paint.as: -------------------------------------------------------------------------------- 1 | package alecmce.ui 2 | { 3 | import flash.display.Graphics; 4 | 5 | /** 6 | * 7 | * 8 | * (c) 2009 alecmce.com 9 | * 10 | * @author Alec McEachran 11 | */ 12 | public interface Paint 13 | { 14 | 15 | function beginPaint(graphics:Graphics):void; 16 | 17 | function endPaint(graphics:Graphics):void; 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/alecmce/ui/interactive/DragMechanism.as: -------------------------------------------------------------------------------- 1 | package alecmce.ui.interactive 2 | { 3 | import flash.display.InteractiveObject; 4 | import flash.events.Event; 5 | import flash.events.MouseEvent; 6 | 7 | /** 8 | * 9 | * 10 | * (c) 2009 alecmce.com 11 | * 12 | * @author Alec McEachran 13 | */ 14 | public class DragMechanism 15 | { 16 | private var _draggables:Array; 17 | 18 | private var _offsetX:Number; 19 | 20 | private var _offsetY:Number; 21 | 22 | private var _dragging:InteractiveObject; 23 | 24 | public function DragMechanism() 25 | { 26 | _draggables = []; 27 | } 28 | 29 | public function apply(target:InteractiveObject):void 30 | { 31 | if (_draggables.indexOf(target) != -1) 32 | return; 33 | 34 | _draggables.push(target); 35 | addEventListeners(target); 36 | } 37 | 38 | public function clear(target:InteractiveObject):void 39 | { 40 | var i:int = _draggables.indexOf(target); 41 | _draggables.splice(i, 1); 42 | 43 | removeEventListeners(target); 44 | 45 | if (_dragging == target) 46 | _dragging = null; 47 | } 48 | 49 | public function clearAll():void 50 | { 51 | var i:int = _draggables.length; 52 | while (--i > -1) 53 | { 54 | var target:InteractiveObject = _draggables[i]; 55 | clear(target); 56 | } 57 | } 58 | 59 | private function addEventListeners(target:InteractiveObject):void 60 | { 61 | if (target.stage) 62 | { 63 | target.addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); 64 | target.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); 65 | } 66 | else 67 | { 68 | target.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 69 | } } 70 | 71 | private function removeEventListeners(target:InteractiveObject):void 72 | { 73 | target.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); target.removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); target.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); 74 | 75 | if (target.stage) 76 | target.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); 77 | } 78 | 79 | private function onAddedToStage(event:Event):void 80 | { 81 | var target:InteractiveObject = InteractiveObject(event.currentTarget); 82 | target.addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); 83 | target.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 84 | target.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); 85 | } 86 | 87 | private function onRemovedFromStage(event:Event):void 88 | { 89 | var target:InteractiveObject = InteractiveObject(event.currentTarget); 90 | 91 | target.removeEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage); 92 | target.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 93 | 94 | target.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); 95 | } 96 | 97 | private function onMouseDown(event:MouseEvent):void 98 | { 99 | var target:InteractiveObject = InteractiveObject(event.currentTarget); 100 | 101 | _dragging = target; 102 | _dragging.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); _dragging.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); 103 | _offsetX = event.stageX - target.x; _offsetY = event.stageY - target.y; 104 | } 105 | 106 | private function onMouseUp(event:MouseEvent):void 107 | { 108 | _dragging.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); _dragging.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); 109 | _dragging = null; 110 | } 111 | 112 | private function onMouseMove(event:MouseEvent):void 113 | { 114 | _dragging.x = event.stageX + _offsetX; _dragging.y = event.stageY + _offsetY; 115 | event.updateAfterEvent(); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/alecmce/ui/paint/SolidPaint.as: -------------------------------------------------------------------------------- 1 | package alecmce.ui.paint 2 | { 3 | import alecmce.ui.Paint; 4 | 5 | import flash.display.Graphics; 6 | 7 | /** 8 | * 9 | * 10 | * (c) 2009 alecmce.com 11 | * 12 | * @author Alec McEachran 13 | */ 14 | public class SolidPaint implements Paint 15 | { 16 | 17 | private static const ALPHA_SCALAR:Number = 1 / 0xFF; 18 | 19 | private var _fill:uint; 20 | 21 | private var _stroke:uint; 22 | 23 | private var _width:int; 24 | 25 | public function SolidPaint(fill:uint, stroke:uint, width:int = -1) 26 | { 27 | _fill = fill; 28 | _stroke = stroke; 29 | _width = width; 30 | } 31 | 32 | public function get fill():uint 33 | { 34 | return _fill; 35 | } 36 | 37 | public function get stroke():uint 38 | { 39 | return _stroke; 40 | } 41 | 42 | public function get width():int 43 | { 44 | return _width; 45 | } 46 | 47 | public function beginPaint(graphics:Graphics):void 48 | { 49 | if (_fill) 50 | graphics.beginFill(_fill & 0xFFFFFF, (_fill >>> 24) * ALPHA_SCALAR); 51 | 52 | if (_width >= 0) 53 | graphics.lineStyle(_width, _stroke & 0xFFFFFF, (_stroke >>> 24) * ALPHA_SCALAR); 54 | else 55 | graphics.lineStyle(); 56 | } 57 | 58 | public function endPaint(graphics:Graphics):void 59 | { 60 | if (_fill) 61 | graphics.endFill(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/alecmce/ui/util/UIArcHelper.as: -------------------------------------------------------------------------------- 1 | package alecmce.ui.util 2 | { 3 | import as3geometry.geom2D.vertices.ImmutableVertex; 4 | 5 | import flash.display.Graphics; 6 | 7 | /** 8 | * A graphical method for approximating an arc by drawing a sequence of bezier curves. 9 | * 10 | * This algorithm takes the simple approach of calculating quadratic bezier curves the midpoint for which 11 | * lies on the circle that it approximates. All of the quadratic curves therefore lie slightly inside the circle. It 12 | * might be possible to add a small adjustment variable to this approximation to improve the perception of an arc for 13 | * extremely large values, but this would need a great deal of care and testing as it would almost certainly be an ad-hoc 14 | * solution. 15 | * 16 | * (c) 2009 alecmce.com 17 | * 18 | * @author Alec McEachran 19 | */ 20 | public class UIArcHelper 21 | { 22 | 23 | public function arcInitialPosition(x:Number, y:Number, radius:Number, start:Number):ImmutableVertex 24 | { 25 | var nx:Number = x + radius * Math.cos(start); 26 | var ny:Number = y + radius * Math.sin(start); 27 | return new ImmutableVertex(nx, ny); 28 | } 29 | 30 | public function drawArc(graphics:Graphics, x:Number, y:Number, radius:Number, start:Number, sweep:Number, curves:uint = 8):void 31 | { 32 | var dAngle:Number = sweep / (2 * curves); 33 | var angle:Number = start; 34 | 35 | var multiplied:Number = radius * (2 - Math.cos(dAngle)); 36 | 37 | for (var i:uint = 0; i < curves; i++) 38 | { 39 | angle += dAngle; 40 | var cx:Number = x + multiplied * Math.cos(angle); var cy:Number = y + multiplied * Math.sin(angle); 41 | 42 | angle += dAngle; 43 | var nx:Number = x + radius * Math.cos(angle); 44 | var ny:Number = y + radius * Math.sin(angle); 45 | 46 | graphics.curveTo(cx, cy, nx, ny); 47 | } 48 | } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/as3geometry/AS3GeometryContext.as: -------------------------------------------------------------------------------- 1 | package as3geometry 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | import alecmce.invalidation.InvalidationManager; 5 | 6 | import flash.display.DisplayObjectContainer; 7 | import flash.events.Event; 8 | 9 | public class AS3GeometryContext 10 | { 11 | private var _root:DisplayObjectContainer; 12 | private var _invalidationManager:InvalidationManager; 13 | 14 | public function AS3GeometryContext(root:DisplayObjectContainer) 15 | { 16 | _root = root; 17 | _invalidationManager = new InvalidationManager(); 18 | _invalidationManager.invalidated.add(onInvalidated); 19 | } 20 | 21 | public function register(invalidates:Invalidates):void 22 | { 23 | _invalidationManager.register(invalidates); 24 | } 25 | 26 | public function get invalidationManager():InvalidationManager 27 | { 28 | return _invalidationManager; 29 | } 30 | 31 | private function onInvalidated():void 32 | { 33 | if (_root.stage) 34 | { 35 | _root.stage.addEventListener(Event.RENDER, onStageRender); 36 | _root.stage.invalidate(); 37 | } 38 | else 39 | { 40 | _root.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 41 | } 42 | } 43 | 44 | private function onAddedToStage(event:Event):void 45 | { 46 | _root.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 47 | _invalidationManager.resolve(); 48 | } 49 | 50 | private function onStageRender(event:Event):void 51 | { 52 | _root.removeEventListener(Event.RENDER, onStageRender); 53 | _invalidationManager.resolve(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/as3geometry/AdditiveCollection.as: -------------------------------------------------------------------------------- 1 | package as3geometry 2 | { 3 | import org.osflash.signals.Signal; 4 | 5 | /** 6 | * Defines the common functionality which all collections must have. If 7 | * generics were possible it would also have a getElement. method but 8 | * this is not yet available 9 | * 10 | * (c) 2009 alecmce.com 11 | * 12 | * @author Alec McEachran 13 | */ 14 | public interface AdditiveCollection 15 | { 16 | 17 | function get added():Signal; 18 | 19 | function get removed():Signal; 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/as3geometry/abstract/AbstractMutableAdditiveCollection.as: -------------------------------------------------------------------------------- 1 | package as3geometry.abstract 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.AdditiveCollection; 5 | 6 | import org.osflash.signals.Signal; 7 | 8 | /** 9 | * 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | public class AbstractMutableAdditiveCollection extends Mutable implements AdditiveCollection 16 | { 17 | 18 | private var _added:Signal; 19 | 20 | private var _removed:Signal; 21 | 22 | public function AbstractMutableAdditiveCollection(context:AS3GeometryContext, collectionClass:Class) 23 | { 24 | super(context); 25 | _added = new Signal(collectionClass); _removed = new Signal(collectionClass); 26 | } 27 | 28 | public function get added():Signal 29 | { 30 | return _added; 31 | } 32 | 33 | public function get removed():Signal 34 | { 35 | return _removed; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/as3geometry/abstract/Mutable.as: -------------------------------------------------------------------------------- 1 | package as3geometry.abstract 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | import alecmce.invalidation.signals.InvalidationSignal; 5 | 6 | import as3geometry.AS3GeometryContext; 7 | 8 | /** 9 | * A generic form for mutable objects which handles the adding and 10 | * removing of definiens 11 | * 12 | * (c) 2009 alecmce.com 13 | * 14 | * @author Alec McEachran 15 | */ 16 | public class Mutable implements Invalidates 17 | { 18 | private var _context:AS3GeometryContext; 19 | 20 | private var _invalidated:InvalidationSignal; 21 | 22 | private var _isInvalidated:Boolean; 23 | 24 | public function Mutable(context:AS3GeometryContext) 25 | { 26 | _context = context; 27 | _invalidated = new InvalidationSignal(); 28 | _isInvalidated = false; 29 | 30 | _context.register(this); 31 | } 32 | 33 | protected function addDefinien(definien:*):void 34 | { 35 | if (definien && definien is Invalidates) 36 | _context.invalidationManager.addDependency(Invalidates(definien), this); 37 | } 38 | 39 | protected function removeDefinien(definien:*):void 40 | { 41 | if (definien && definien is Invalidates) 42 | _context.invalidationManager.removeDependency(Invalidates(definien), this); 43 | } 44 | 45 | public function invalidate(resolveImmediately:Boolean = false):void 46 | { 47 | _isInvalidated = true; 48 | _invalidated.dispatch(this, resolveImmediately); 49 | } 50 | 51 | public function resolve():void 52 | { 53 | _isInvalidated = false; 54 | } 55 | 56 | public function get invalidated():InvalidationSignal 57 | { 58 | return _invalidated; 59 | } 60 | 61 | public function get isInvalid():Boolean 62 | { 63 | return _isInvalidated; 64 | } 65 | 66 | public function get context():AS3GeometryContext 67 | { 68 | return _context; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/as3geometry/errors/MutabilityError.as: -------------------------------------------------------------------------------- 1 | package as3geometry.errors 2 | { 3 | 4 | /** 5 | * An error that is thrown if an immutable object defined by a mutable object 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public class MutabilityError extends Error 12 | { 13 | public function MutabilityError(message:String) 14 | { 15 | super(message); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/Angle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * Defines a directed angle 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public interface Angle 12 | { 13 | 14 | function get degrees():Number; 15 | 16 | function get radians():Number; 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/Circle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * Defines a circle on a Cartesian plane by center Vertex and radius 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public interface Circle 12 | { 13 | 14 | function get center():Vertex; 15 | 16 | function get radius():Number; 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/CircleSector.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | public interface CircleSector 4 | { 5 | 6 | function get from():VertexOnCircle; 7 | 8 | function get to():VertexOnCircle; 9 | 10 | function get angle():Number; 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/CircleSegment.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public interface CircleSegment 12 | { 13 | 14 | function get from():VertexOnCircle; 15 | 16 | function get to():VertexOnCircle; 17 | 18 | function get angle():Number; 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/CollectionOfPolygons.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | 5 | /** 6 | * Describes a collection of polygons 7 | * 8 | * (c) 2009 alecmce.com 9 | * 10 | * @author Alec McEachran 11 | */ 12 | public interface CollectionOfPolygons 13 | { 14 | 15 | function get countPolygons():uint; 16 | 17 | function getPolygon(index:uint):Polygon; 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/CollectionOfVertices.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | 5 | /** 6 | * Describes a collection of vertices 7 | * 8 | * (c) 2009 alecmce.com 9 | * 10 | * @author Alec McEachran 11 | */ 12 | public interface CollectionOfVertices 13 | { 14 | 15 | function get countVertices():uint; 16 | 17 | function getVertex(index:uint):Vertex; 18 | 19 | function indexOfVertex(vertex:Vertex):int; 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/InteractiveVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | public interface InteractiveVertex extends Vertex 5 | { 6 | 7 | function set x(value:Number):void; 8 | 9 | function set y(value:Number):void; 10 | 11 | function set(x:Number, y:Number):void; 12 | 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/Line.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * Defines a line on a Cartesian plane by two vertices 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public interface Line 12 | { 13 | 14 | function get a():Vertex; 15 | 16 | function get b():Vertex; 17 | 18 | function get vector():SpatialVector; 19 | 20 | function get type():LineType; 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/LineType.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * An enumeration of line types: 6 | * 7 | * A LINE extends infinitely in both directions from the two definitional vertices 8 | * 9 | * A RAY starts at Vertex a and extends infinitely through Vertex b 10 | * 11 | * A SEGMENT starts at Vertex a and stops at Vertex b 12 | * 13 | * (c) 2009 alecmce.com 14 | * 15 | * @author Alec McEachran 16 | */ 17 | public class LineType 18 | { 19 | 20 | public static const LINE:LineType = new LineType(checkLine); 21 | 22 | private static function checkLine(n:Number):Boolean 23 | { 24 | n; // stop FDT warning 25 | return true; 26 | } 27 | 28 | public static const RAY:LineType = new LineType(checkRay); 29 | 30 | private static function checkRay(n:Number):Boolean 31 | { 32 | return n >= 0; 33 | } 34 | 35 | public static const SEGMENT:LineType = new LineType(checkSegment); 36 | 37 | private static function checkSegment(n:Number):Boolean 38 | { 39 | return n >= 0 && n <= 1; 40 | } 41 | 42 | private var fn:Function; 43 | 44 | public function LineType(fn:Function) 45 | { 46 | this.fn = fn; 47 | } 48 | 49 | public function isValidPositionMultiplier(n:Number):Boolean 50 | { 51 | if (isNaN(n)) 52 | return false; 53 | 54 | return fn(n); 55 | } 56 | 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/Parabola.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * Defines a parabola defined geometrically as the locus of points equidistant 6 | * to a point and a line (where the distance from a point to a line is taken 7 | * as the shortest distance; the distance of the perpendicular from the line 8 | * to the point) 9 | * 10 | * (c) 2009 alecmce.com 11 | * 12 | * @author Alec McEachran 13 | */ 14 | public interface Parabola 15 | { 16 | 17 | function get focus():Vertex; 18 | 19 | function get directrix():Line; 20 | 21 | /** 22 | * A parabola's vertices can be enumerated with respect to the vertex that 23 | * lies perpendicular to them on the directrix. 24 | * 25 | * @param n A position on the directrix such that 0 is on directrix.a and 26 | * 1 is on directrix.b. The range of values that are appropriate is 27 | * contingent upon the LineType of the Line. 28 | * 29 | * @return The vertex that lies perpendicular to the directrix such that 30 | * the vertex defined by n on the directrix is the intersection of the 31 | * directrix and the perpendicular line 32 | */ 33 | function getVertex(n:Number):Vertex; 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/Polygon.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | 5 | /** 6 | * Defines a polygon on a Cartesian plane by a list of vertices 7 | * 8 | * (c) 2009 alecmce.com 9 | * 10 | * @author Alec McEachran 11 | */ 12 | public interface Polygon extends CollectionOfVertices 13 | { 14 | 15 | function getEdge(index:uint):Line; 16 | 17 | function contains(vertex:Vertex):Boolean; 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/SpatialVector.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * Defines a vector that describes a translation on a Cartesian plane 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public interface SpatialVector 12 | { 13 | 14 | function get i():Number; 15 | 16 | function get j():Number; 17 | 18 | function get length():Number; 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/Triangle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * Defines a triangle on a Cartesian plane by three vertices 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public interface Triangle 12 | { 13 | 14 | function get a():Vertex; 15 | 16 | function get b():Vertex; 17 | 18 | function get c():Vertex; 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/Vertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * Defines a vertex on a cartesian plane. 6 | * 7 | * Vertex is preferred instead of flash.geom.Point because the Vertex class 8 | * is immutable. 9 | * 10 | * (c) 2009 alecmce.com 11 | * 12 | * @author Alec McEachran 13 | */ 14 | public interface Vertex 15 | { 16 | 17 | function get x():Number; 18 | 19 | function get y():Number; 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/VertexOnCircle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public interface VertexOnCircle extends Vertex 12 | { 13 | 14 | function get circle():Circle; 15 | 16 | function get angle():Number; 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/VertexOnLine.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | /** 5 | * 6 | * 7 | * (c) 2009 alecmce.com 8 | * 9 | * @author Alec McEachran 10 | */ 11 | public interface VertexOnLine extends InteractiveVertex 12 | { 13 | 14 | function get line():Line; 15 | 16 | function get positionOnLineAsMultiplier():Number; 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/VertexOnParabola.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | 4 | public interface VertexOnParabola extends InteractiveVertex 5 | { 6 | 7 | function get parabola():Parabola; 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/angle/MutableAngleFromVectors.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.angle 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Angle; 6 | import as3geometry.geom2D.SpatialVector; 7 | import as3geometry.geom2D.util.AngleHelper; 8 | 9 | /** 10 | * 11 | * 12 | * (c) 2009 alecmce.com 13 | * 14 | * @author Alec McEachran 15 | */ 16 | public class MutableAngleFromVectors extends Mutable implements Angle 17 | { 18 | private var _helper:AngleHelper; 19 | 20 | private var _a:SpatialVector; 21 | private var _b:SpatialVector; 22 | 23 | private var _radians:Number; 24 | 25 | private var _degrees:Number; 26 | 27 | public function MutableAngleFromVectors(context:AS3GeometryContext, a:SpatialVector, b:SpatialVector) 28 | { 29 | super(context); 30 | addDefinien(_a = a); addDefinien(_b = b); 31 | 32 | _helper = new AngleHelper(); 33 | invalidate(true); 34 | } 35 | 36 | public function get radians():Number 37 | { 38 | return _radians; 39 | } 40 | 41 | public function get degrees():Number 42 | { 43 | return _degrees; 44 | } 45 | 46 | public function get a():SpatialVector 47 | { 48 | return _a; 49 | } 50 | 51 | public function set a(a:SpatialVector):void 52 | { 53 | if (_a == a) 54 | return; 55 | 56 | removeDefinien(_a); 57 | _a = a; 58 | addDefinien(_a); 59 | invalidate(); 60 | } 61 | 62 | public function get b():SpatialVector 63 | { 64 | return _b; 65 | } 66 | 67 | public function set b(b:SpatialVector):void 68 | { 69 | if (_b == b) 70 | return; 71 | 72 | removeDefinien(_b); 73 | _b = b; 74 | addDefinien(_b); 75 | invalidate(); 76 | } 77 | 78 | override public function resolve():void 79 | { 80 | super.resolve(); 81 | _radians = _helper.directedAngleFromVectors(_a.i, _a.j, _b.i, _b.j); 82 | _degrees = _helper.toDegrees(_radians); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/circle/ImmutableCircle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.circle 2 | { 3 | import as3geometry.abstract.Mutable; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.Circle; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.vertices.ImmutableVertex; 8 | 9 | /** 10 | * Defines a circle on a Cartesian plane by center Vertex and radius 11 | * 12 | * (c) 2009 alecmce.com 13 | * 14 | * @author Alec McEachran 15 | */ 16 | public class ImmutableCircle implements Circle 17 | { 18 | 19 | /*********************************************************************/ 20 | // Member Variables 21 | /*********************************************************************/ 22 | 23 | 24 | /** The center of the circle */ 25 | private var _center:Vertex; 26 | 27 | /** The radius of the circle */ 28 | private var _radius:Number; 29 | 30 | 31 | /*********************************************************************/ 32 | // Public Methods 33 | /*********************************************************************/ 34 | 35 | 36 | /** 37 | * Class Constructor 38 | * 39 | * @param center The center of the circle 40 | * @param radius The radius of the circle 41 | */ 42 | public function ImmutableCircle(center:Vertex = null, radius:Number = 1) 43 | { 44 | _center = center ? center : new ImmutableVertex(0, 0); 45 | 46 | if (_center is Mutable) 47 | throw new MutabilityError("The ImmutableCircle's definitional center is mutable"); 48 | 49 | _radius = radius; 50 | } 51 | 52 | 53 | /** 54 | * @return The center of the circle 55 | */ 56 | public function get center():Vertex 57 | { 58 | return _center; 59 | } 60 | 61 | /** 62 | * @return The radius of the circle 63 | */ 64 | public function get radius():Number 65 | { 66 | return _radius; 67 | } 68 | 69 | /** 70 | * @return A user-readable string describing this circle 71 | */ 72 | public function toString():String 73 | { 74 | return "[CIRCLE " + center + ", r=" + radius + "]"; 75 | } 76 | 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/circle/MutableCircle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.circle 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Circle; 6 | import as3geometry.geom2D.Vertex; 7 | 8 | /** 9 | * Defines a circle on a Cartesian plane by center Vertex and radius 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | public class MutableCircle extends Mutable implements Circle 16 | { 17 | 18 | private var _center:Vertex; 19 | private var _radius:Number; 20 | 21 | public function MutableCircle(context:AS3GeometryContext, center:Vertex, radius:Number) 22 | { 23 | super(context); 24 | addDefinien(_center = center); 25 | _radius = radius; 26 | invalidate(true); 27 | } 28 | 29 | public function get center():Vertex 30 | { 31 | return _center; 32 | } 33 | 34 | public function set center(value:Vertex):void 35 | { 36 | if (_center == value) 37 | return; 38 | 39 | removeDefinien(_center); 40 | _center = value; 41 | addDefinien(_center); 42 | invalidate(); 43 | } 44 | 45 | public function get radius():Number 46 | { 47 | return _radius; 48 | } 49 | 50 | public function set radius(value:Number):void 51 | { 52 | if (_radius == value) 53 | return; 54 | 55 | _radius = value; 56 | invalidate(); 57 | } 58 | 59 | public function toString():String 60 | { 61 | return "[CIRCLE " + center + ", r=" + radius + "]"; 62 | } 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/circle/MutableCircleSector.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.circle 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.CircleSector; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.VertexOnCircle; 8 | import as3geometry.geom2D.circle.errors.SegmentDefinitionError; 9 | import as3geometry.geom2D.util.AngleHelper; 10 | 11 | /** 12 | * 13 | * 14 | * (c) 2009 alecmce.com 15 | * 16 | * @author Alec McEachran 17 | */ 18 | public class MutableCircleSector extends Mutable implements CircleSector 19 | { 20 | private static const TWOPI:Number = Math.PI * 2; 21 | 22 | private var _helper:AngleHelper; 23 | 24 | private var _from:VertexOnCircle; 25 | private var _to:VertexOnCircle; 26 | 27 | private var _isRight:Boolean; 28 | 29 | private var _angle:Number; 30 | 31 | public function MutableCircleSector(context:AS3GeometryContext, from:VertexOnCircle, to:VertexOnCircle, isRight:Boolean) 32 | { 33 | super(context); 34 | 35 | if (from.circle != to.circle) 36 | throw new SegmentDefinitionError("The from and to vertices must lie on the same circle"); 37 | 38 | addDefinien(_from = from); 39 | addDefinien(_to = to); 40 | 41 | _isRight = isRight; 42 | _helper = new AngleHelper(); 43 | invalidate(true); 44 | } 45 | 46 | public function get from():VertexOnCircle 47 | { 48 | return _from; 49 | } 50 | 51 | public function set from(from:VertexOnCircle):void 52 | { 53 | if (_from == from) 54 | return; 55 | 56 | if (from.circle != _to.circle) 57 | throw new SegmentDefinitionError("The from and to vertices must lie on the same circle"); 58 | 59 | _from = from; 60 | invalidate(); 61 | } 62 | 63 | public function get to():VertexOnCircle 64 | { 65 | return _to; 66 | } 67 | 68 | public function set to(to:VertexOnCircle):void 69 | { 70 | if (_to == to) 71 | return; 72 | 73 | if (to.circle != _from.circle) 74 | throw new SegmentDefinitionError("The from and to vertices must lie on the same circle"); 75 | 76 | _to = to; 77 | invalidate(); 78 | } 79 | 80 | public function get angle():Number 81 | { 82 | return _angle; 83 | } 84 | 85 | override public function resolve():void 86 | { 87 | super.resolve(); 88 | 89 | if (isNaN(_from.x) || isNaN(_from.y) || isNaN(_to.x) || isNaN(_to.y)) 90 | { 91 | _angle = Number.NaN; 92 | return; 93 | } 94 | 95 | var center:Vertex = _from.circle.center; 96 | _angle = _helper.directedAngleFromVertices(center, _from, _to); 97 | if (_isRight == _angle < 0) 98 | _angle = TWOPI + _angle; 99 | } 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/circle/MutableCircleSegment.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.circle 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.CircleSegment; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.VertexOnCircle; 8 | import as3geometry.geom2D.circle.errors.SegmentDefinitionError; 9 | import as3geometry.geom2D.util.AngleHelper; 10 | 11 | /** 12 | * 13 | * 14 | * (c) 2009 alecmce.com 15 | * 16 | * @author Alec McEachran 17 | */ 18 | public class MutableCircleSegment extends Mutable implements CircleSegment 19 | { 20 | private static const TWOPI:Number = Math.PI * 2; 21 | 22 | private var _helper:AngleHelper; 23 | 24 | private var _from:VertexOnCircle; 25 | private var _to:VertexOnCircle; 26 | 27 | private var _isRight:Boolean; 28 | 29 | private var _angle:Number; 30 | 31 | public function MutableCircleSegment(context:AS3GeometryContext, from:VertexOnCircle, to:VertexOnCircle, isRight:Boolean) 32 | { 33 | super(context); 34 | 35 | if (from.circle != to.circle) 36 | throw new SegmentDefinitionError("The from and to vertices must lie on the same circle"); 37 | 38 | addDefinien(_from = from); 39 | addDefinien(_to = to); 40 | 41 | _isRight = isRight; 42 | _helper = new AngleHelper(); 43 | invalidate(true); 44 | } 45 | 46 | public function get from():VertexOnCircle 47 | { 48 | return _from; 49 | } 50 | 51 | public function set from(from:VertexOnCircle):void 52 | { 53 | if (_from == from) 54 | return; 55 | 56 | if (from.circle != _to.circle) 57 | throw new SegmentDefinitionError("The from and to vertices must lie on the same circle"); 58 | 59 | _from = from; 60 | invalidate(); 61 | } 62 | 63 | public function get to():VertexOnCircle 64 | { 65 | return _to; 66 | } 67 | 68 | public function set to(to:VertexOnCircle):void 69 | { 70 | if (_to == to) 71 | return; 72 | 73 | if (to.circle != _from.circle) 74 | throw new SegmentDefinitionError("The from and to vertices must lie on the same circle"); 75 | 76 | _to = to; 77 | invalidate(); 78 | } 79 | 80 | public function get angle():Number 81 | { 82 | return _angle; 83 | } 84 | 85 | override public function resolve():void 86 | { 87 | super.resolve(); 88 | 89 | if (isNaN(_from.x) || isNaN(_from.y) || isNaN(_to.x) || isNaN(_to.y)) 90 | { 91 | _angle = Number.NaN; 92 | return; 93 | } 94 | 95 | var center:Vertex = _from.circle.center; 96 | _angle = _helper.directedAngleFromVertices(center, _from, _to); 97 | if (_isRight == _angle < 0) 98 | _angle = TWOPI + _angle; 99 | } 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/circle/MutableCircleWithRadialVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.circle 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Circle; 6 | import as3geometry.geom2D.Vertex; 7 | 8 | /** 9 | * Defines a circle on a Cartesian plane by center Vertex and radius 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | public class MutableCircleWithRadialVertex extends Mutable implements Circle 16 | { 17 | private var _center:Vertex; 18 | private var _radial:Vertex; 19 | private var _radius:Number; 20 | 21 | public function MutableCircleWithRadialVertex(context:AS3GeometryContext, center:Vertex, radial:Vertex) 22 | { 23 | super(context); 24 | addDefinien(_center = center); 25 | addDefinien(_radial = radial); 26 | invalidate(true); 27 | } 28 | 29 | public function get center():Vertex 30 | { 31 | return _center; 32 | } 33 | 34 | public function set center(value:Vertex):void 35 | { 36 | if (_center == value) 37 | return; 38 | 39 | removeDefinien(_center); 40 | _center = value; 41 | addDefinien(_center); 42 | invalidate(true); 43 | } 44 | 45 | public function get radial():Vertex 46 | { 47 | return _radial; 48 | } 49 | 50 | public function set radial(value:Vertex):void 51 | { 52 | if (_radial == value) 53 | return; 54 | 55 | removeDefinien(_radial); 56 | _radial = value; 57 | addDefinien(_radial); 58 | invalidate(); 59 | } 60 | 61 | public function get radius():Number 62 | { 63 | return _radius; 64 | } 65 | 66 | override public function resolve():void 67 | { 68 | super.resolve(); 69 | 70 | var x:Number = _radial.x - _center.x; 71 | var y:Number = _radial.y - _center.y; 72 | trace("[RESOLVE] MutableCircleWithRadialVertex", x, y); 73 | 74 | _radius = Math.sqrt(x * x + y * y); 75 | } 76 | 77 | public function toString():String 78 | { 79 | return "[CIRCLE " + _center + " -> " + _radial + ", r=" + radius + "]"; 80 | } 81 | 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/circle/errors/SegmentDefinitionError.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.circle.errors 2 | { 3 | import Error; 4 | 5 | /** 6 | * An error that is thrown if a segment is defined incorrectly 7 | * 8 | * (c) 2009 alecmce.com 9 | * 10 | * @author Alec McEachran 11 | */ 12 | public class SegmentDefinitionError extends Error 13 | { 14 | public function SegmentDefinitionError(message:String) 15 | { 16 | super(message); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/intersection/CircleAndLineIntersectionVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.intersection 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | import alecmce.invalidation.signals.InvalidationSignal; 5 | 6 | import as3geometry.AS3GeometryContext; 7 | import as3geometry.geom2D.Circle; 8 | import as3geometry.geom2D.Vertex; 9 | import as3geometry.geom2D.VertexOnCircle; 10 | 11 | /** 12 | * 13 | * 14 | * (c) 2009 alecmce.com 15 | * 16 | * @author Alec McEachran 17 | */ 18 | internal class CircleAndLineIntersectionVertex implements VertexOnCircle, Invalidates 19 | { 20 | private var _invalidated:InvalidationSignal; 21 | private var _isInvalidated:Boolean; 22 | 23 | private var _circle:Circle; 24 | private var _x:Number; 25 | private var _y:Number; 26 | private var _angle:Number; 27 | 28 | public function CircleAndLineIntersectionVertex(context:AS3GeometryContext, container:IntersectionOfCircleAndLine) 29 | { 30 | _invalidated = new InvalidationSignal(); 31 | _isInvalidated = false; 32 | 33 | context.invalidationManager.addDependency(container, this); 34 | 35 | _circle = null; 36 | _angle = Number.NaN; 37 | _x = Number.NaN; 38 | _y = Number.NaN; 39 | } 40 | 41 | public function get circle():Circle 42 | { 43 | return _circle; 44 | } 45 | 46 | public function get angle():Number 47 | { 48 | return _angle; 49 | } 50 | 51 | public function get x():Number 52 | { 53 | return _x; 54 | } 55 | 56 | public function get y():Number 57 | { 58 | return _y; 59 | } 60 | 61 | public function invalidate(resolveImmediately:Boolean = false):void 62 | { 63 | _isInvalidated = true; 64 | _invalidated.dispatch(this, resolveImmediately); 65 | } 66 | 67 | public function resolve():void 68 | { 69 | // do nothing - in this unusual case resolve is deferred to the 70 | // IntersectionOfCircleAndLine container object that performs the 71 | // calculation and calls update in it's own resolve cycle. Because 72 | // the container object is a definien, it must be resolved before 73 | // this object 74 | } 75 | 76 | internal function update(circle:Circle, x:Number, y:Number):void 77 | { 78 | _circle = circle; 79 | _x = x; 80 | _y = y; 81 | 82 | if (isNaN(_x) || isNaN(_y)) 83 | { 84 | _angle = Number.NaN; 85 | } 86 | else 87 | { 88 | var center:Vertex = _circle.center; 89 | _angle = Math.atan2(_y - center.y, _x - center.x); 90 | } 91 | 92 | _isInvalidated = false; 93 | } 94 | 95 | public function get invalidated():InvalidationSignal 96 | { 97 | return _invalidated; 98 | } 99 | 100 | public function get isInvalid():Boolean 101 | { 102 | return _isInvalidated; 103 | } 104 | 105 | public function set(x:Number, y:Number):void 106 | { 107 | } 108 | 109 | public function set x(value:Number):void 110 | { 111 | } 112 | 113 | public function set y(value:Number):void 114 | { 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/intersection/IntersectionOfCircleAndLine.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.intersection 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Circle; 6 | import as3geometry.geom2D.Line; 7 | import as3geometry.geom2D.VertexOnCircle; 8 | 9 | /** 10 | * 11 | * 12 | * (c) 2009 alecmce.com 13 | * 14 | * @author Alec McEachran 15 | */ 16 | public class IntersectionOfCircleAndLine extends Mutable 17 | { 18 | private var _circle:Circle; 19 | private var _line:Line; 20 | 21 | private var _first:CircleAndLineIntersectionVertex; 22 | private var _second:CircleAndLineIntersectionVertex; 23 | 24 | public function IntersectionOfCircleAndLine(context:AS3GeometryContext, circle:Circle, line:Line) 25 | { 26 | super(context); 27 | 28 | _circle = circle; 29 | addDefinien(_circle); 30 | 31 | _line = line; 32 | addDefinien(_line); 33 | 34 | _first = new CircleAndLineIntersectionVertex(context, this); _second = new CircleAndLineIntersectionVertex(context, this); 35 | 36 | invalidate(true); 37 | } 38 | 39 | public function get circle():Circle 40 | { 41 | return _circle; 42 | } 43 | 44 | public function set circle(circle:Circle):void 45 | { 46 | if (_circle == circle) 47 | return; 48 | 49 | removeDefinien(_circle); 50 | _circle = circle; 51 | addDefinien(_circle); 52 | invalidate(); 53 | } 54 | 55 | public function get line():Line 56 | { 57 | return _line; 58 | } 59 | 60 | public function set line(line:Line):void 61 | { 62 | if (_line == line) 63 | return; 64 | 65 | removeDefinien(_line); 66 | _line = line; 67 | addDefinien(_line); 68 | invalidate(); 69 | } 70 | 71 | public function get first():VertexOnCircle 72 | { 73 | return _first; 74 | } 75 | 76 | public function get second():VertexOnCircle 77 | { 78 | return _second; 79 | } 80 | 81 | override public function resolve():void 82 | { 83 | var fx:Number = Number.NaN; var fy:Number = Number.NaN; var sx:Number = Number.NaN; var sy:Number = Number.NaN; 84 | 85 | if (_circle && _line) 86 | { 87 | var cx:Number = _circle.center.x; var cy:Number = _circle.center.y; 88 | var r:Number = _circle.radius; 89 | var x:Number = _line.a.x - cx; var y:Number = _line.a.y - cy; 90 | var i:Number = _line.b.x - _line.a.x; var j:Number = _line.b.y - _line.a.y; 91 | 92 | // you can derive a quadratic of the form An^2 + Bn + C = 0 93 | var A:Number = i * i + j * j; 94 | var B:Number = 2 * (x * i + y * j); 95 | var C:Number = x * x + y * y - r * r; 96 | 97 | var n:Number; 98 | 99 | // checking the discriminant for number of solutions 100 | var discriminant:Number = B * B - 4 * A * C; 101 | if (discriminant == 0) 102 | { 103 | n = -B / (2 * A); 104 | 105 | if (_line.type.isValidPositionMultiplier(n)) 106 | { 107 | fx = cx + x + i * n; 108 | fy = cy + y + j * n; 109 | } 110 | } 111 | else if (discriminant > 0) 112 | { 113 | discriminant = Math.sqrt(discriminant); 114 | 115 | cx += x; 116 | cy += y; 117 | 118 | n = (-B + discriminant) / (2 * A); 119 | var isFirstValueValid:Boolean = _line.type.isValidPositionMultiplier(n); 120 | if (isFirstValueValid) 121 | { 122 | fx = cx + i * n; 123 | fy = cy + j * n; 124 | } 125 | 126 | n = (-B - discriminant) / (2 * A); 127 | if (_line.type.isValidPositionMultiplier(n)) 128 | { 129 | if (isFirstValueValid) 130 | { 131 | sx = cx + i * n; sy = cy + j * n; 132 | } 133 | else 134 | { 135 | fx = cx + i * n; 136 | fy = cy + j * n; 137 | } 138 | } 139 | } 140 | } 141 | 142 | _first.update(_circle, fx, fy); _second.update(_circle, sx, sy); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/intersection/IntersectionsOfLineAndPolygon.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.intersection 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.LineType; 7 | import as3geometry.geom2D.Polygon; 8 | import as3geometry.geom2D.Vertex; 9 | import as3geometry.geom2D.line.ImmutableLine; 10 | import as3geometry.geom2D.line.IntersectionOfTwoLinesVertex; 11 | import as3geometry.geom2D.vertices.IndependentVertex; 12 | 13 | /** 14 | * 15 | * 16 | * (c) 2009 alecmce.com 17 | * 18 | * @author Alec McEachran 19 | */ 20 | public class IntersectionsOfLineAndPolygon extends Mutable 21 | { 22 | 23 | private var _polygon:Polygon; 24 | private var _line:Line; 25 | 26 | private var _potential:Array; 27 | private var _actual:Array; 28 | 29 | public function IntersectionsOfLineAndPolygon(context:AS3GeometryContext, polygon:Polygon, line:Line) 30 | { 31 | super(context); 32 | 33 | _polygon = polygon; 34 | addDefinien(_polygon); 35 | 36 | _line = line; 37 | addDefinien(_line); 38 | 39 | _potential = calculateVertices(); 40 | _actual = generateActuals(); 41 | invalidate(true); 42 | } 43 | 44 | public function get potentialIntersections():Array 45 | { 46 | return _potential; 47 | } 48 | 49 | public function get actualIntersections():Array 50 | { 51 | return _actual; 52 | } 53 | 54 | override public function resolve():void 55 | { 56 | super.resolve(); 57 | 58 | var sorted:Array = _potential.sort(sortByMultipliers); 59 | 60 | var len:int = _potential.length; 61 | var nullify:Boolean = false; 62 | for (var i:int = 0; i < len; i++) 63 | { 64 | var a:IndependentVertex = _actual[i]; 65 | 66 | p = sorted[i]; 67 | if (!nullify) 68 | { 69 | var p:IntersectionOfTwoLinesVertex = sorted[i]; 70 | nullify = isNaN(p.x); 71 | } 72 | 73 | if (nullify) 74 | a.set(Number.NaN, Number.NaN); 75 | else 76 | a.set(p.x, p.y); 77 | } 78 | } 79 | 80 | private function calculateVertices():Array 81 | { 82 | var count:int = _polygon.countVertices; 83 | var vertices:Array = []; 84 | 85 | var b:Vertex = _polygon.getVertex(count - 1); 86 | for (var i:int = 0; i < count; i++) 87 | { 88 | var a:Vertex = _polygon.getVertex(i); 89 | var edge:ImmutableLine = new ImmutableLine(a, b, LineType.SEGMENT); 90 | var vertex:IntersectionOfTwoLinesVertex = new IntersectionOfTwoLinesVertex(context, edge, _line); 91 | b = a; 92 | 93 | vertices[i] = vertex; 94 | } 95 | 96 | return vertices; 97 | } 98 | 99 | private function generateActuals():Array 100 | { 101 | var n:int = _potential.length; 102 | var actuals:Array = []; 103 | 104 | while (--n > -1) 105 | actuals[n] = new IndependentVertex(context, Number.NaN, Number.NaN); 106 | 107 | return actuals; 108 | } 109 | 110 | private function sortByMultipliers(a:IntersectionOfTwoLinesVertex, b:IntersectionOfTwoLinesVertex):int 111 | { 112 | var aN:Number = a.bMultiplier; var bN:Number = b.bMultiplier; 113 | 114 | var isAInvalid:Boolean = isNaN(aN); 115 | var isBInvalid:Boolean = isNaN(bN); 116 | 117 | if (isAInvalid && isBInvalid) 118 | return 0; 119 | else if (isAInvalid) 120 | return 1; 121 | else if (isBInvalid) 122 | return -1; 123 | if (aN < bN) 124 | return -1; 125 | else if (aN > bN) 126 | return 1; 127 | 128 | return 0; 129 | } 130 | 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/line/ImmutableLine.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.line 2 | { 3 | import as3geometry.abstract.Mutable; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.LineType; 7 | import as3geometry.geom2D.SpatialVector; 8 | import as3geometry.geom2D.Vertex; 9 | import as3geometry.geom2D.vectors.ImmutableSpatialVector; 10 | import as3geometry.geom2D.vertices.ImmutableVertex; 11 | 12 | /** 13 | * Defines a line on a Cartesian plane by two vertices 14 | * 15 | * (c) 2009 alecmce.com 16 | * 17 | * @author Alec McEachran 18 | */ 19 | public class ImmutableLine implements Line 20 | { 21 | 22 | /*********************************************************************/ 23 | // Member Variables 24 | /*********************************************************************/ 25 | 26 | 27 | /** a vertex of the line */ 28 | private var _a:Vertex; 29 | 30 | /** a vertex of the line */ 31 | private var _b:Vertex; 32 | 33 | /** the line type */ 34 | private var _type:LineType; 35 | 36 | private var _vector:SpatialVector; 37 | 38 | 39 | /*********************************************************************/ 40 | // Public Methods 41 | /*********************************************************************/ 42 | 43 | 44 | /** 45 | * Class Constructor 46 | * 47 | * @param a A vertex of the line 48 | * @param b A vertex of the line 49 | */ 50 | public function ImmutableLine(a:Vertex = null, b:Vertex = null, type:LineType = null) 51 | { 52 | _a = a ? a : new ImmutableVertex(0, 0); 53 | _b = b ? b : new ImmutableVertex(0, 0); 54 | _type = type ? type : LineType.LINE; 55 | 56 | if (_a is Mutable || _b is Mutable) 57 | throw new MutabilityError("One of the ImmutableLine's definitional points is mutable"); 58 | } 59 | 60 | 61 | public function get a():Vertex 62 | { 63 | return _a; 64 | } 65 | 66 | 67 | public function get b():Vertex 68 | { 69 | return _b; 70 | } 71 | 72 | 73 | public function get vector():SpatialVector 74 | { 75 | if (!_vector) 76 | _vector = new ImmutableSpatialVector(_b.x - _a.x, _b.y - _a.y); 77 | 78 | return _vector; 79 | } 80 | 81 | 82 | public function get type():LineType 83 | { 84 | return _type; 85 | } 86 | 87 | 88 | /** 89 | * determine whether two lines are the same iff they share the same 90 | * determinant vertices 91 | * 92 | * @param line The line to compare this line with 93 | * @return Whether the two lines are the same 94 | */ 95 | public function isSame(line:Line):Boolean 96 | { 97 | return (a == line.a && b == line.b) || (a == line.b && b == line.a); 98 | } 99 | 100 | 101 | /** 102 | * @return A user-readable string describing this line 103 | */ 104 | public function toString():String 105 | { 106 | return "[LINE " + a + ", " + b + "]"; 107 | } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/line/MutableLine.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.line 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.LineType; 7 | import as3geometry.geom2D.SpatialVector; 8 | import as3geometry.geom2D.Vertex; 9 | 10 | /** 11 | * Defines a line on a Cartesian plane by two vertices 12 | * 13 | * (c) 2009 alecmce.com 14 | * 15 | * @author Alec McEachran 16 | */ 17 | public class MutableLine extends Mutable implements Line, SpatialVector 18 | { 19 | 20 | private var _a:Vertex; 21 | 22 | private var _b:Vertex; 23 | 24 | private var _type:LineType; 25 | 26 | private var _i:Number; 27 | private var _j:Number; 28 | private var _length:Number; 29 | 30 | public function MutableLine(context:AS3GeometryContext, a:Vertex, b:Vertex, type:LineType = null) 31 | { 32 | super(context); 33 | addDefinien(_a = a); 34 | addDefinien(_b = b); 35 | _type = type ? type : LineType.LINE; 36 | invalidate(true); 37 | } 38 | 39 | public function get a():Vertex 40 | { 41 | return _a; 42 | } 43 | 44 | public function set a(a:Vertex):void 45 | { 46 | if (_a == a) 47 | return; 48 | 49 | removeDefinien(_a); 50 | _a = a; 51 | addDefinien(_a); 52 | invalidate(); 53 | } 54 | 55 | public function get b():Vertex 56 | { 57 | return _b; 58 | } 59 | 60 | public function set b(b:Vertex):void 61 | { 62 | if (_b == b) 63 | return; 64 | 65 | removeDefinien(_b); 66 | _b = b; 67 | addDefinien(_b); 68 | invalidate(); 69 | } 70 | 71 | override public function resolve():void 72 | { 73 | _i = _b.x - _a.x; 74 | _j = _b.y - _a.y; 75 | _length = Math.sqrt(_i * _i + _j * _j); 76 | } 77 | 78 | public function get i():Number 79 | { 80 | return _i; 81 | } 82 | 83 | public function get j():Number 84 | { 85 | return _j; 86 | } 87 | 88 | public function get length():Number 89 | { 90 | return _length; 91 | } 92 | 93 | public function get vector():SpatialVector 94 | { 95 | return this; 96 | } 97 | 98 | public function get type():LineType 99 | { 100 | return _type; 101 | } 102 | 103 | public function isSame(line:Line):Boolean 104 | { 105 | return (a == line.a && b == line.b) || (a == line.b && b == line.a); 106 | } 107 | 108 | public function toString():String 109 | { 110 | return "[LINE " + a + ", " + b + "]"; 111 | } 112 | 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/line/VertexProjectedToLine.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.line 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.SpatialVector; 7 | import as3geometry.geom2D.Vertex; 8 | 9 | public class VertexProjectedToLine extends Mutable implements Vertex 10 | { 11 | private var _line:Line; 12 | private var _vertex:Vertex; 13 | 14 | private var _x:Number; 15 | private var _y:Number; 16 | 17 | public function VertexProjectedToLine(context:AS3GeometryContext, line:Line, vertex:Vertex) 18 | { 19 | super(context); 20 | addDefinien(_vertex = vertex); 21 | addDefinien(_line = line); 22 | resolve(); 23 | } 24 | 25 | public function get line():Line 26 | { 27 | return _line; 28 | } 29 | 30 | public function set line(value:Line):void 31 | { 32 | if (_line == value) 33 | return; 34 | 35 | removeDefinien(_line); 36 | _line = value; 37 | addDefinien(_line); 38 | invalidate(); 39 | } 40 | 41 | public function get vertex():Vertex 42 | { 43 | return _vertex; 44 | } 45 | 46 | public function set vertex(value:Vertex):void 47 | { 48 | if (_vertex == value) 49 | return; 50 | 51 | removeDefinien(_vertex); 52 | _vertex = value; 53 | addDefinien(_vertex); 54 | invalidate(); 55 | } 56 | 57 | public function get x():Number 58 | { 59 | return _x; 60 | } 61 | 62 | public function get y():Number 63 | { 64 | return _y; 65 | } 66 | 67 | override public function resolve():void 68 | { 69 | super.resolve(); 70 | 71 | var a:Vertex = _line.a; 72 | var v:SpatialVector = _line.vector; 73 | 74 | var x:Number = _vertex.x; 75 | var y:Number = _vertex.y; 76 | var i:Number = v.i; 77 | var j:Number = v.j; 78 | var n:Number = x - a.x; 79 | var m:Number = y - a.y; 80 | 81 | var delta:Number = (j * n - i * m) / (i * i + j * j); 82 | 83 | _x = x - j * delta; 84 | _y = y + i * delta; 85 | } 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/parabola/ImmutableParabola.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.parabola 2 | { 3 | import as3geometry.abstract.Mutable; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.Parabola; 7 | import as3geometry.geom2D.Vertex; 8 | import as3geometry.geom2D.util.ParabolaHelper; 9 | 10 | /** 11 | * Defines a parabola defined geometrically as the locus of points equidistant 12 | * to a point and a line 13 | * 14 | * (c) 2009 alecmce.com 15 | * 16 | * @author Alec McEachran 17 | */ 18 | public class ImmutableParabola implements Parabola 19 | { 20 | private var _focus:Vertex; 21 | private var _directrix:Line; 22 | 23 | /** 24 | * Class Constructor 25 | * 26 | * @param focus The 27 | */ 28 | public function ImmutableParabola(focus:Vertex, directrix:Line) 29 | { 30 | if (focus is Mutable) 31 | throw new MutabilityError("A vertex defining an ImmutableParabola is Mutable"); 32 | else 33 | _focus = focus; 34 | 35 | if (directrix is Mutable) 36 | throw new MutabilityError("A line defining an ImmutableParabola is Mutable"); 37 | else 38 | _directrix = directrix; 39 | } 40 | 41 | public function get focus():Vertex 42 | { 43 | return _focus; 44 | } 45 | 46 | public function get directrix():Line 47 | { 48 | return _directrix; 49 | } 50 | 51 | /** 52 | * A parabola's vertices can be enumerated with respect to the vertex that 53 | * lies perpendicular to them on the directrix. 54 | * 55 | * @param n A position on the directrix such that 0 is on directrix.a and 56 | * 1 is on directrix.b. The range of values that are appropriate is 57 | * contingent upon the LineType of the Line. 58 | * 59 | * @return The vertex that lies perpendicular to the directrix such that 60 | * the vertex defined by n on the directrix is the intersection of the 61 | * directrix and the perpendicular line 62 | */ 63 | public function getVertex(n:Number):Vertex 64 | { 65 | var helper:ParabolaHelper = new ParabolaHelper(); 66 | return helper.vertexFromParameter(this, n); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/parabola/MutableParabola.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.parabola 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.Parabola; 7 | import as3geometry.geom2D.Vertex; 8 | import as3geometry.geom2D.util.ParabolaHelper; 9 | 10 | public class MutableParabola extends Mutable implements Parabola 11 | { 12 | private var _focus:Vertex; 13 | private var _directrix:Line; 14 | 15 | private var helper:ParabolaHelper; 16 | 17 | public function MutableParabola(context:AS3GeometryContext, focus:Vertex, directrix:Line) 18 | { 19 | super(context); 20 | addDefinien(_focus = focus); 21 | addDefinien(_directrix = directrix); 22 | invalidate(true); 23 | } 24 | 25 | public function getVertex(n:Number):Vertex 26 | { 27 | helper ||= new ParabolaHelper(); 28 | return helper.vertexFromParameter(this, n); 29 | } 30 | 31 | public function get focus():Vertex 32 | { 33 | return _focus; 34 | } 35 | 36 | public function get directrix():Line 37 | { 38 | return _directrix; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/ImmutablePolygon.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons 2 | { 3 | import as3geometry.abstract.Mutable; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.LineType; 7 | import as3geometry.geom2D.Polygon; 8 | import as3geometry.geom2D.Vertex; 9 | import as3geometry.geom2D.line.ImmutableLine; 10 | import as3geometry.geom2D.util.PolygonHelper; 11 | 12 | /** 13 | * Defines a polygon on a Cartesian plane by a list of vertices 14 | * 15 | * (c) 2009 alecmce.com 16 | * 17 | * @author Alec McEachran 18 | */ 19 | public class ImmutablePolygon implements Polygon 20 | { 21 | private var _vertices:Array; 22 | private var _edges:Array; 23 | 24 | /** 25 | * Class Constructor 26 | * 27 | * @param vertices The array of vertices that defines the polygon 28 | */ 29 | public function ImmutablePolygon(vertices:Array) 30 | { 31 | _vertices = vertices.concat(); 32 | _edges = []; 33 | 34 | var i:int = vertices.length; 35 | while (--i > -1) 36 | { 37 | var v:Vertex = vertices[i]; 38 | if (v is Mutable) 39 | throw new MutabilityError("A vertex defining an ImmutablePolygon is mutable"); 40 | } 41 | } 42 | 43 | 44 | /** 45 | * @return The number of vertices in the polygon 46 | */ 47 | public function get countVertices():uint 48 | { 49 | return _vertices.length; 50 | } 51 | 52 | 53 | /** 54 | * retrieve the vertex at a given index 55 | * 56 | * @param index The index of the vertex to be retrieved 57 | * 58 | * @return The vertex at the corresponding index 59 | */ 60 | public function getVertex(index:uint):Vertex 61 | { 62 | return _vertices[index]; 63 | } 64 | 65 | /** 66 | * get the edge of the polygon at a given index 67 | * 68 | * I've adopted a strategay of just-in-time referencing of the ImmutablePolygon edges as 69 | * I anticipate in many cases they will not need to be defined 70 | */ 71 | public function getEdge(index:uint):Line 72 | { 73 | var edge:Line = _edges[index]; 74 | if (edge == null) 75 | { 76 | var a:Vertex = getVertex(index); 77 | var b:Vertex = getVertex(index + 1 == _vertices.length ? 0 : index + 1); 78 | _edges[index] = edge = new ImmutableLine(a, b, LineType.SEGMENT); 79 | } 80 | 81 | return edge; 82 | } 83 | 84 | public function contains(vertex:Vertex):Boolean 85 | { 86 | var helper:PolygonHelper = new PolygonHelper(); 87 | return helper.vertexPolygonContains(_vertices, vertex); 88 | } 89 | 90 | public function indexOfVertex(vertex:Vertex):int 91 | { 92 | return _vertices.indexOf(vertex); 93 | } 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/ImmutableTriangle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons 2 | { 3 | import as3geometry.abstract.Mutable; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.Triangle; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.vertices.ImmutableVertex; 8 | 9 | /** 10 | * Defines a triangle on a Cartesian plane by three vertices 11 | * 12 | * (c) 2009 alecmce.com 13 | * 14 | * @author Alec McEachran 15 | */ 16 | public class ImmutableTriangle implements Triangle 17 | { 18 | 19 | /*********************************************************************/ 20 | // Member Variables 21 | /*********************************************************************/ 22 | 23 | 24 | /** a vertex of the triangle */ 25 | private var _a:Vertex; 26 | /** a vertex of the triangle */ 27 | private var _b:Vertex; 28 | /** a vertex of the triangle */ 29 | private var _c:Vertex; 30 | 31 | 32 | /*********************************************************************/ 33 | // Public Methods 34 | /*********************************************************************/ 35 | 36 | 37 | public function ImmutableTriangle(a:Vertex = null, b:Vertex = null, c:Vertex = null) 38 | { 39 | _a = a ? a : new ImmutableVertex(0, 0); _b = b ? b : new ImmutableVertex(0, 0); _c = c ? c : new ImmutableVertex(0, 0); 40 | 41 | if (_a is Mutable || _b is Mutable || _c is Mutable) 42 | throw new MutabilityError("One of the ImmutableTriangle's definitional points is mutable"); 43 | } 44 | 45 | public function get a():Vertex 46 | { 47 | return _a; 48 | } 49 | 50 | public function get b():Vertex 51 | { 52 | return _b; 53 | } 54 | 55 | public function get c():Vertex 56 | { 57 | return _c; 58 | } 59 | 60 | public function toString():String 61 | { 62 | return "[TRIANGLE " + _a + ", " + _b + ", " + _c + "]"; 63 | } 64 | 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/MutablePolygon.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.LineType; 7 | import as3geometry.geom2D.Polygon; 8 | import as3geometry.geom2D.Vertex; 9 | import as3geometry.geom2D.line.MutableLine; 10 | import as3geometry.geom2D.util.PolygonHelper; 11 | 12 | /** 13 | * Defines a polygon on a Cartesian plane by a list of vertices 14 | * 15 | * (c) 2009 alecmce.com 16 | * 17 | * @author Alec McEachran 18 | */ 19 | public class MutablePolygon extends Mutable implements Polygon 20 | { 21 | 22 | protected var _vertices:Array; 23 | 24 | private var _edges:Array; 25 | 26 | public function MutablePolygon(context:AS3GeometryContext, vertices:Array) 27 | { 28 | super(context); 29 | 30 | _vertices = vertices.concat(); 31 | _edges = []; 32 | 33 | var i:int = vertices.length; 34 | while (--i > -1) 35 | { 36 | var v:Vertex = vertices[i]; 37 | addDefinien(v); 38 | } 39 | 40 | invalidate(true); 41 | } 42 | 43 | public function get countVertices():uint 44 | { 45 | return _vertices.length; 46 | } 47 | 48 | public function getVertex(index:uint):Vertex 49 | { 50 | return _vertices[index]; 51 | } 52 | 53 | /** 54 | * get the edge of the polygon at a given index 55 | * 56 | * I've adopted a strategay of just-in-time referencing of the MutablePolygon edges; 57 | * The mutability of the polygon means that the edges are fixed once defined (in case 58 | * a vertex is defined on it or as an intersection with it and another item) it cannot 59 | * be disposed and re-generated later-on 60 | */ 61 | public function getEdge(index:uint):Line 62 | { 63 | var edge:Line = _edges[index]; 64 | if (edge == null) 65 | { 66 | var a:Vertex = getVertex(index); 67 | var b:Vertex = getVertex(index + 1 == _vertices.length ? 0 : index + 1); 68 | _edges[index] = edge = new MutableLine(context, a, b, LineType.SEGMENT); 69 | } 70 | 71 | return edge; 72 | } 73 | 74 | public function contains(vertex:Vertex):Boolean 75 | { 76 | var helper:PolygonHelper = new PolygonHelper(); 77 | return helper.vertexPolygonContains(_vertices, vertex); 78 | } 79 | 80 | public function indexOfVertex(vertex:Vertex):int 81 | { 82 | return _vertices.indexOf(vertex); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/MutableTriangle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Triangle; 6 | import as3geometry.geom2D.Vertex; 7 | 8 | /** 9 | * Defines a triangle on a Cartesian plane by three vertices 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | public class MutableTriangle extends Mutable implements Triangle 16 | { 17 | private var _a:Vertex; 18 | private var _b:Vertex; 19 | private var _c:Vertex; 20 | 21 | public function MutableTriangle(context:AS3GeometryContext, a:Vertex, b:Vertex, c:Vertex) 22 | { 23 | super(context); 24 | addDefinien(_a = a); addDefinien(_b = b); 25 | addDefinien(_c = c); 26 | invalidate(true); 27 | } 28 | 29 | public function get a():Vertex 30 | { 31 | return _a; 32 | } 33 | 34 | public function set a(a:Vertex):void 35 | { 36 | if (_a == a) 37 | return; 38 | 39 | removeDefinien(_a); 40 | _a = a; 41 | addDefinien(_a); 42 | invalidate(); 43 | } 44 | 45 | public function get b():Vertex 46 | { 47 | return _b; 48 | } 49 | 50 | public function set b(b:Vertex):void 51 | { 52 | if (_b == b) 53 | return; 54 | 55 | removeDefinien(_b); 56 | _b = b; 57 | addDefinien(_b); 58 | invalidate(); 59 | } 60 | 61 | public function get c():Vertex 62 | { 63 | return _c; 64 | } 65 | 66 | public function set c(c:Vertex):void 67 | { 68 | if (_c == c) 69 | return; 70 | 71 | removeDefinien(_c); 72 | _c = c; 73 | addDefinien(_c); 74 | invalidate(); 75 | } 76 | 77 | public function toString():String 78 | { 79 | return "[TRIANGLE " + _a + ", " + _b + ", " + _c + "]"; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/intersection/ExpandedPolygonVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.intersection 2 | { 3 | import as3geometry.geom2D.Vertex; 4 | 5 | /** 6 | * This was intended to be an interface (see commit prior to this) but there is a 7 | * problem with having a Array 8 | * where the BranchInterface extends the RootInterface, so I resorted to this being 9 | * an abstract base class 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | internal class ExpandedPolygonVertex implements Vertex 16 | { 17 | public var visited:Boolean; 18 | 19 | public var isReal:Boolean; 20 | 21 | public var positionOnPolygonAAsCycle:Number; 22 | 23 | public var positionOnPolygonBAsCycle:Number; 24 | 25 | public var polygonIndex:int; 26 | 27 | public function ExpandedPolygonVertex() 28 | { 29 | polygonIndex = -1; 30 | visited = false; 31 | } 32 | 33 | public function get x():Number 34 | { 35 | return Number.NaN; 36 | } 37 | 38 | public function get y():Number 39 | { 40 | return Number.NaN; 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/intersection/IntersectionOfTwoPolygons.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.intersection 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.AbstractMutableAdditiveCollection; 5 | import as3geometry.geom2D.CollectionOfPolygons; 6 | import as3geometry.geom2D.Polygon; 7 | 8 | /** 9 | * The intersection of two polygons is complex. The aim of the excersize is to not re-evaluate the 10 | * entire intersection every time that one of the container polygons is moved; that would take up 11 | * too many resources to be practical. 12 | * 13 | * (c) 2009 alecmce.com 14 | * 15 | * @author Alec McEachran 16 | */ 17 | public class IntersectionOfTwoPolygons extends AbstractMutableAdditiveCollection implements CollectionOfPolygons 18 | { 19 | private var _a:Polygon; 20 | private var _b:Polygon; 21 | 22 | private var _expanded:ExpandedPolygonVectors; 23 | private var _sorted:SortedPolygonVectors; 24 | 25 | private var _polygonCount:uint; 26 | private var _polygons:Array; 27 | 28 | public function IntersectionOfTwoPolygons(context:AS3GeometryContext, a:Polygon, b:Polygon) 29 | { 30 | super(context, Polygon); 31 | 32 | _a = a; 33 | _b = b; 34 | addDefinien(_expanded = new ExpandedPolygonVectors(context, _a, _b)); 35 | 36 | _sorted = new SortedPolygonVectors(context, _expanded); 37 | 38 | _polygons = _sorted.findPolygons(); 39 | _polygonCount = _polygons.length; 40 | } 41 | 42 | public function get countPolygons():uint 43 | { 44 | return _polygonCount; 45 | } 46 | 47 | public function getPolygon(i:uint):Polygon 48 | { 49 | return _polygons[i]; 50 | } 51 | 52 | // private function onExpandedPolygonVectorsChanged(vertex:PotentialIntersectionVertex):void 53 | // { 54 | // if (vertex.isReal) 55 | // { 56 | // 57 | // } 58 | // else 59 | // { 60 | // var index:int = vertex.polygonIndex; 61 | // if (index == -1) 62 | // return; 63 | // 64 | // var polygon:IntersectionPolygon = _polygons[index]; 65 | // if (polygon) 66 | // { 67 | // polygon.removeVertex(vertex); 68 | // vertex.polygonIndex = -1; 69 | // } 70 | // } 71 | // } 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/intersection/IntersectionPolygon.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.intersection 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.AdditiveCollection; 5 | import as3geometry.geom2D.Vertex; 6 | import as3geometry.geom2D.polygons.MutablePolygon; 7 | 8 | import org.osflash.signals.Signal; 9 | 10 | /** 11 | * 12 | * 13 | * (c) 2009 alecmce.com 14 | * 15 | * @author Alec McEachran 16 | */ 17 | internal class IntersectionPolygon extends MutablePolygon implements AdditiveCollection 18 | { 19 | 20 | private var _added:Signal; 21 | private var _removed:Signal; 22 | 23 | public function IntersectionPolygon(context:AS3GeometryContext, vertices:Array) 24 | { 25 | _added = new Signal(Vertex); _removed = new Signal(Vertex); 26 | 27 | super(context, vertices); 28 | } 29 | 30 | 31 | public function removeVertex(vertex:Vertex):void 32 | { 33 | var i:int = _vertices.indexOf(vertex); 34 | if (i == -1) 35 | return; 36 | 37 | _vertices.splice(i, 1); 38 | _removed.dispatch(vertex); 39 | } 40 | 41 | public function get added():Signal 42 | { 43 | return _added; 44 | } 45 | 46 | public function get removed():Signal 47 | { 48 | return _removed; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/intersection/OrignalPolygonVertexWrapper.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.intersection 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | import alecmce.invalidation.signals.InvalidationSignal; 5 | 6 | import as3geometry.geom2D.Vertex; 7 | 8 | /** 9 | * 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | internal class OrignalPolygonVertexWrapper extends ExpandedPolygonVertex 16 | { 17 | private var _original:Vertex; 18 | 19 | private var _invalidated:InvalidationSignal; 20 | 21 | public function OrignalPolygonVertexWrapper(original:Vertex, aIndex:int, bIndex:int) 22 | { 23 | _original = original; 24 | if (_original is Invalidates) 25 | _invalidated = Invalidates(_original).invalidated; 26 | else 27 | _invalidated = new InvalidationSignal(); 28 | 29 | positionOnPolygonAAsCycle = aIndex; 30 | positionOnPolygonBAsCycle = bIndex; 31 | isReal = true; 32 | visited = false; 33 | } 34 | 35 | override public function get x():Number 36 | { 37 | return _original.x; 38 | } 39 | 40 | override public function get y():Number 41 | { 42 | return _original.y; 43 | } 44 | 45 | public function get invalidated():InvalidationSignal 46 | { 47 | return _invalidated; 48 | } 49 | 50 | public function get target():Vertex 51 | { 52 | return _original; 53 | } 54 | 55 | public function toString() : String 56 | { 57 | var str:String = "Vertex: (@X@,@Y@)"; 58 | str = str.replace("@X@", x); 59 | str = str.replace("@Y@", y); 60 | 61 | return str; 62 | } 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/intersection/PotentialIntersectionVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.intersection 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | import alecmce.invalidation.signals.InvalidationSignal; 5 | 6 | import as3geometry.AS3GeometryContext; 7 | import as3geometry.geom2D.Line; 8 | import as3geometry.geom2D.line.IntersectionOfTwoLinesVertex; 9 | 10 | import org.osflash.signals.Signal; 11 | 12 | /** 13 | * A vertex that lies on the intersection of two vertices 14 | * 15 | * (c) 2009 alecmce.com 16 | * 17 | * @author Alec McEachran 18 | */ 19 | internal class PotentialIntersectionVertex extends ExpandedPolygonVertex implements Invalidates 20 | { 21 | private var _context:AS3GeometryContext; 22 | 23 | private var _intersection:IntersectionOfTwoLinesVertex; 24 | 25 | private var _invalidated:InvalidationSignal; 26 | 27 | private var _realityChanged:Signal; 28 | 29 | private var _aIndex:uint; 30 | 31 | private var _bIndex:uint; 32 | private var _isInvalid:Boolean; 33 | 34 | public function PotentialIntersectionVertex(context:AS3GeometryContext, a:Line, b:Line, aIndex:uint, bIndex:uint) 35 | { 36 | _context = context; 37 | _invalidated = new InvalidationSignal(); 38 | 39 | _intersection = new IntersectionOfTwoLinesVertex(context, a, b); 40 | context.invalidationManager.addDependency(_intersection, this); 41 | 42 | _aIndex = aIndex; _bIndex = bIndex; 43 | 44 | _realityChanged = new Signal(PotentialIntersectionVertex); 45 | resolve(); 46 | } 47 | 48 | public function toString() : String 49 | { 50 | var str:String = "Intersection: (@X@,@Y@)"; 51 | str = str.replace("@X@", x); str = str.replace("@Y@", y); 52 | 53 | return str; 54 | } 55 | 56 | public function get realityChanged():Signal 57 | { 58 | return _realityChanged; 59 | } 60 | 61 | override public function get x():Number 62 | { 63 | return _intersection.x; 64 | } 65 | 66 | override public function get y():Number 67 | { 68 | return _intersection.y; 69 | } 70 | 71 | public function get a():Line 72 | { 73 | return _intersection.a; 74 | } 75 | 76 | public function get b():Line 77 | { 78 | return _intersection.b; 79 | } 80 | 81 | public function invalidate(resolve:Boolean = false):void 82 | { 83 | _invalidated.dispatch(this); 84 | _isInvalid = true; 85 | } 86 | 87 | public function get invalidated():InvalidationSignal 88 | { 89 | return _invalidated; 90 | } 91 | 92 | public function get isInvalid():Boolean 93 | { 94 | return _isInvalid; 95 | } 96 | 97 | public function resolve():void 98 | { 99 | _isInvalid = false; 100 | 101 | var x:Number = _intersection.x; 102 | var y:Number = _intersection.y; 103 | 104 | var newIsIntersection:Boolean = !isNaN(x) && !isNaN(y); 105 | var realValueHasChanged:Boolean = isReal != newIsIntersection; 106 | 107 | isReal = newIsIntersection; 108 | 109 | if (isReal) 110 | { 111 | positionOnPolygonAAsCycle = _aIndex + _intersection.aMultiplier; 112 | positionOnPolygonBAsCycle = _bIndex + _intersection.bMultiplier; 113 | } 114 | else 115 | { 116 | positionOnPolygonAAsCycle = Number.NaN; 117 | positionOnPolygonBAsCycle = Number.NaN; 118 | } 119 | 120 | if (realValueHasChanged) 121 | _realityChanged.dispatch(this); 122 | } 123 | 124 | public function get context():AS3GeometryContext 125 | { 126 | return _context; 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/test/ExpandedPolygonVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.test 2 | { 3 | import as3geometry.geom2D.Vertex; 4 | 5 | /** 6 | * This was intended to be an interface (see commit prior to this) but there is a 7 | * problem with having a Array 8 | * where the BranchInterface extends the RootInterface, so I resorted to this being 9 | * an abstract base class 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | internal class ExpandedPolygonVertex implements Vertex 16 | { 17 | public var visited:Boolean; 18 | 19 | public var isReal:Boolean; 20 | 21 | public var positionOnPolygonAAsCycle:Number; 22 | 23 | public var positionOnPolygonBAsCycle:Number; 24 | 25 | public var polygonIndex:int; 26 | 27 | public function ExpandedPolygonVertex() 28 | { 29 | polygonIndex = -1; 30 | visited = false; 31 | } 32 | 33 | public function get x():Number 34 | { 35 | return Number.NaN; 36 | } 37 | 38 | public function get y():Number 39 | { 40 | return Number.NaN; 41 | } 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/test/OrignalPolygonVertexWrapper.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.test 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | import alecmce.invalidation.signals.InvalidationSignal; 5 | 6 | import as3geometry.geom2D.Vertex; 7 | 8 | /** 9 | * 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | internal class OrignalPolygonVertexWrapper extends ExpandedPolygonVertex 16 | { 17 | private var _original:Vertex; 18 | 19 | private var _invalidated:InvalidationSignal; 20 | 21 | public function OrignalPolygonVertexWrapper(original:Vertex, aIndex:int, bIndex:int) 22 | { 23 | _original = original; 24 | if (_original is Invalidates) 25 | _invalidated = Invalidates(_original).invalidated; 26 | else 27 | _invalidated = new InvalidationSignal(); 28 | 29 | positionOnPolygonAAsCycle = aIndex; 30 | positionOnPolygonBAsCycle = bIndex; 31 | isReal = true; 32 | visited = false; 33 | } 34 | 35 | override public function get x():Number 36 | { 37 | return _original.x; 38 | } 39 | 40 | override public function get y():Number 41 | { 42 | return _original.y; 43 | } 44 | 45 | public function get invalidated():InvalidationSignal 46 | { 47 | return _invalidated; 48 | } 49 | 50 | public function get target():Vertex 51 | { 52 | return _original; 53 | } 54 | 55 | public function toString() : String 56 | { 57 | var str:String = "Vertex: (@X@,@Y@)"; 58 | str = str.replace("@X@", x); 59 | str = str.replace("@Y@", y); 60 | 61 | return str; 62 | } 63 | 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/test/PotentialIntersectionVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.test 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | import alecmce.invalidation.signals.InvalidationSignal; 5 | 6 | import as3geometry.AS3GeometryContext; 7 | import as3geometry.geom2D.Line; 8 | import as3geometry.geom2D.line.IntersectionOfTwoLinesVertex; 9 | 10 | import org.osflash.signals.Signal; 11 | 12 | /** 13 | * A vertex that lies on the intersection of two vertices 14 | * 15 | * (c) 2009 alecmce.com 16 | * 17 | * @author Alec McEachran 18 | */ 19 | internal class PotentialIntersectionVertex extends ExpandedPolygonVertex implements Invalidates 20 | { 21 | private var _context:AS3GeometryContext; 22 | 23 | private var _intersection:IntersectionOfTwoLinesVertex; 24 | 25 | private var _invalidated:InvalidationSignal; 26 | 27 | private var _realityChanged:Signal; 28 | 29 | private var _aIndex:uint; 30 | 31 | private var _bIndex:uint; 32 | private var _isInvalid:Boolean; 33 | 34 | public function PotentialIntersectionVertex(context:AS3GeometryContext, a:Line, b:Line, aIndex:uint, bIndex:uint) 35 | { 36 | _context = context; 37 | _invalidated = new InvalidationSignal(); 38 | 39 | _intersection = new IntersectionOfTwoLinesVertex(context, a, b); 40 | context.invalidationManager.addDependency(_intersection, this); 41 | 42 | _aIndex = aIndex; _bIndex = bIndex; 43 | 44 | _realityChanged = new Signal(PotentialIntersectionVertex); 45 | resolve(); 46 | } 47 | 48 | public function toString() : String 49 | { 50 | var str:String = "Intersection: (@X@,@Y@)"; 51 | str = str.replace("@X@", x); str = str.replace("@Y@", y); 52 | 53 | return str; 54 | } 55 | 56 | public function get realityChanged():Signal 57 | { 58 | return _realityChanged; 59 | } 60 | 61 | override public function get x():Number 62 | { 63 | return _intersection.x; 64 | } 65 | 66 | override public function get y():Number 67 | { 68 | return _intersection.y; 69 | } 70 | 71 | public function get a():Line 72 | { 73 | return _intersection.a; 74 | } 75 | 76 | public function get b():Line 77 | { 78 | return _intersection.b; 79 | } 80 | 81 | public function invalidate(resolve:Boolean = false):void 82 | { 83 | _invalidated.dispatch(this); 84 | _isInvalid = true; 85 | } 86 | 87 | public function get invalidated():InvalidationSignal 88 | { 89 | return _invalidated; 90 | } 91 | 92 | public function get isInvalid():Boolean 93 | { 94 | return _isInvalid; 95 | } 96 | 97 | public function resolve():void 98 | { 99 | _isInvalid = false; 100 | 101 | var x:Number = _intersection.x; 102 | var y:Number = _intersection.y; 103 | 104 | var newIsIntersection:Boolean = !isNaN(x) && !isNaN(y); 105 | var realValueHasChanged:Boolean = isReal != newIsIntersection; 106 | 107 | isReal = newIsIntersection; 108 | 109 | if (isReal) 110 | { 111 | positionOnPolygonAAsCycle = _aIndex + _intersection.aMultiplier; 112 | positionOnPolygonBAsCycle = _bIndex + _intersection.bMultiplier; 113 | } 114 | else 115 | { 116 | positionOnPolygonAAsCycle = Number.NaN; 117 | positionOnPolygonBAsCycle = Number.NaN; 118 | } 119 | 120 | if (realValueHasChanged) 121 | _realityChanged.dispatch(this); 122 | } 123 | 124 | public function get context():AS3GeometryContext 125 | { 126 | return _context; 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/polygons/test/TestIntersectionPolygon.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.polygons.test 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.Polygon; 7 | import as3geometry.geom2D.Vertex; 8 | 9 | /** 10 | * @author amceachran 11 | */ 12 | public class TestIntersectionPolygon extends Mutable implements Polygon 13 | { 14 | 15 | private var _potentialVertices:Array; 16 | private var _potentialLines:Array; 17 | 18 | private var _actualVertices:Array; 19 | private var _actualLines:Array; 20 | 21 | public function TestIntersectionPolygon(context:AS3GeometryContext, vertices:Array) 22 | { 23 | super(context); 24 | 25 | _potentialVertices = vertices; 26 | 27 | var len:int = vertices.length; 28 | for (var i:int = 0; i < len; i++) 29 | { 30 | var v:Vertex = vertices[i]; 31 | if (v is PotentialIntersectionVertex) 32 | PotentialIntersectionVertex(v).realityChanged.add(onRealityChanged); 33 | } 34 | } 35 | 36 | private function onRealityChanged(vertex:PotentialIntersectionVertex):void 37 | { 38 | 39 | 40 | invalidate(); 41 | } 42 | 43 | public function getEdge(index:uint):Line 44 | { 45 | // TODO: Auto-generated method stub 46 | return null; 47 | } 48 | 49 | public function contains(vertex:Vertex):Boolean 50 | { 51 | // TODO: Auto-generated method stub 52 | return null; 53 | } 54 | 55 | public function getVertex(index:uint):Vertex 56 | { 57 | // TODO: Auto-generated method stub 58 | return null; 59 | } 60 | 61 | public function indexOfVertex(vertex:Vertex):int 62 | { 63 | // TODO: Auto-generated method stub 64 | return 0; 65 | } 66 | 67 | public function get countVertices() : uint 68 | { 69 | // TODO: Auto-generated method stub 70 | return 0; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/CircleDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Circle; 5 | import as3geometry.geom2D.Vertex; 6 | import as3geometry.geom2D.ui.generic.UIDrawer; 7 | 8 | import alecmce.ui.Paint; 9 | 10 | /** 11 | * Draws a circle 12 | * 13 | * (c) 2009 alecmce.com 14 | * 15 | * @author Alec McEachran 16 | */ 17 | public class CircleDrawer extends UIDrawer 18 | { 19 | private var _circle:Circle; 20 | 21 | public function CircleDrawer(context:AS3GeometryContext, circle:Circle, paint:Paint = null) 22 | { 23 | super(context, paint); 24 | addDefinien(_circle = circle); 25 | } 26 | 27 | public function get circle():Circle 28 | { 29 | return _circle; 30 | } 31 | 32 | public function set circle(value:Circle):void 33 | { 34 | if (_circle == value) 35 | return; 36 | 37 | removeDefinien(_circle); 38 | _circle = value; 39 | addDefinien(_circle); 40 | invalidate(); 41 | } 42 | 43 | override protected function draw():void 44 | { 45 | trace("[RESOLVE] CircleDrawer"); 46 | 47 | try 48 | { 49 | var c:Vertex = _circle.center; 50 | graphics.drawCircle(c.x, c.y, _circle.radius); 51 | } 52 | catch (error:Error) 53 | { 54 | // do nothing 55 | } 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/CircleSectorDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Circle; 5 | import as3geometry.geom2D.CircleSector; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.ui.generic.UIDrawer; 8 | import as3geometry.geom2D.util.AngleHelper; 9 | 10 | import alecmce.ui.Paint; 11 | import alecmce.ui.util.UIArcHelper; 12 | 13 | /** 14 | * Draws a circle 15 | * 16 | * (c) 2009 alecmce.com 17 | * 18 | * @author Alec McEachran 19 | */ 20 | public class CircleSectorDrawer extends UIDrawer 21 | { 22 | private var angles:AngleHelper; 23 | 24 | private var helper:UIArcHelper; 25 | 26 | private var _sector:CircleSector; 27 | 28 | public function CircleSectorDrawer(context:AS3GeometryContext, sector:CircleSector, paint:Paint = null) 29 | { 30 | super(context, paint); 31 | addDefinien(_sector = sector); 32 | angles = new AngleHelper(); 33 | helper = new UIArcHelper(); 34 | invalidate(); 35 | } 36 | 37 | public function get sector():CircleSector 38 | { 39 | return _sector; 40 | } 41 | 42 | public function set sector(value:CircleSector):void 43 | { 44 | if (_sector == value) 45 | return; 46 | 47 | removeDefinien(_sector); 48 | _sector = value; 49 | addDefinien(_sector); 50 | invalidate(); 51 | } 52 | 53 | override protected function draw():void 54 | { 55 | var circle:Circle = _sector.from.circle; 56 | var c:Vertex = circle.center; 57 | var radius:Number = circle.radius; 58 | var angle:Number = _sector.from.angle; var sweep:Number = _sector.angle; 59 | 60 | if (isNaN(c.x) || isNaN(c.y) || isNaN(angle) || isNaN(radius) || isNaN(sweep)) 61 | return; 62 | 63 | var x:Number = c.x; 64 | var y:Number = c.y; 65 | 66 | var start:Vertex = helper.arcInitialPosition(x, y, radius, angle); 67 | graphics.moveTo(x, y); 68 | graphics.lineTo(start.x, start.y); 69 | helper.drawArc(graphics, c.x, c.y, radius, angle, sweep); 70 | graphics.lineTo(x, y); 71 | } 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/CircleSegmentDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Circle; 5 | import as3geometry.geom2D.CircleSegment; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.ui.generic.UIDrawer; 8 | import as3geometry.geom2D.util.AngleHelper; 9 | 10 | import alecmce.ui.Paint; 11 | import alecmce.ui.util.UIArcHelper; 12 | 13 | /** 14 | * Draws a circle 15 | * 16 | * (c) 2009 alecmce.com 17 | * 18 | * @author Alec McEachran 19 | */ 20 | public class CircleSegmentDrawer extends UIDrawer 21 | { 22 | private var angles:AngleHelper; 23 | 24 | private var helper:UIArcHelper; 25 | 26 | private var _segment:CircleSegment; 27 | 28 | public function CircleSegmentDrawer(context:AS3GeometryContext, segment:CircleSegment, paint:Paint = null) 29 | { 30 | super(context, paint); 31 | addDefinien(_segment = segment); 32 | angles = new AngleHelper(); 33 | helper = new UIArcHelper(); 34 | invalidate(); 35 | } 36 | 37 | public function get segment():CircleSegment 38 | { 39 | return _segment; 40 | } 41 | 42 | public function set segment(value:CircleSegment):void 43 | { 44 | if (_segment == value) 45 | return; 46 | 47 | removeDefinien(_segment); 48 | _segment = value; 49 | addDefinien(_segment); 50 | invalidate(); 51 | } 52 | 53 | override protected function draw():void 54 | { 55 | var circle:Circle = _segment.from.circle; 56 | var c:Vertex = circle.center; 57 | var radius:Number = circle.radius; 58 | var angle:Number = _segment.from.angle; var sweep:Number = _segment.angle; 59 | 60 | if (isNaN(c.x) || isNaN(c.y) || isNaN(angle) || isNaN(radius) || isNaN(sweep)) 61 | return; 62 | 63 | var x:Number = c.x; 64 | var y:Number = c.y; 65 | 66 | var start:Vertex = helper.arcInitialPosition(x, y, radius, angle); 67 | graphics.moveTo(start.x, start.y); 68 | helper.drawArc(graphics, c.x, c.y, radius, angle, sweep); 69 | } 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/DEFAULT_PAINT.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import alecmce.ui.Paint; 4 | import alecmce.ui.paint.SolidPaint; 5 | 6 | public const DEFAULT_PAINT:Paint = new SolidPaint(0x00FFFFFF, 0xFF000000, 2); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/LineDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import as3geometry.geom2D.ui.generic.UIDrawer; 4 | import as3geometry.AS3GeometryContext; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.LineType; 7 | import as3geometry.geom2D.Vertex; 8 | 9 | import alecmce.ui.Paint; 10 | 11 | import flash.display.Graphics; 12 | import flash.events.Event; 13 | 14 | /** 15 | * 16 | * 17 | * (c) 2009 alecmce.com 18 | * 19 | * @author Alec McEachran 20 | */ 21 | public class LineDrawer extends UIDrawer 22 | { 23 | 24 | private var _line:Line; 25 | 26 | private var _diagonal:Number; 27 | 28 | private var _drawPending:Boolean; 29 | 30 | public function LineDrawer(context:AS3GeometryContext, line:Line, paint:Paint = null) 31 | { 32 | super(context, paint); 33 | addDefinien(_line = line); 34 | 35 | _drawPending = false; 36 | 37 | addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 38 | } 39 | 40 | private function onAddedToStage(event:Event):void 41 | { 42 | removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); 43 | _diagonal = calculateDiagonal(); 44 | 45 | if (_drawPending) 46 | draw(); 47 | } 48 | 49 | private function calculateDiagonal():Number 50 | { 51 | var w:int = stage.stageWidth; 52 | var h:int = stage.stageHeight; 53 | 54 | return Math.sqrt(w * w + h * h); 55 | } 56 | 57 | public function get line():Line 58 | { 59 | return _line; 60 | } 61 | 62 | public function set line(value:Line):void 63 | { 64 | if (_line == value) 65 | return; 66 | 67 | removeDefinien(_line); 68 | addDefinien(_line = value); 69 | invalidate(); 70 | } 71 | 72 | override protected function draw():void 73 | { 74 | if (!stage) 75 | { 76 | _drawPending = true; 77 | return; 78 | } 79 | 80 | _drawPending = false; 81 | 82 | var a:Vertex = _line.a; var b:Vertex = _line.b; 83 | 84 | switch (_line.type) 85 | { 86 | case LineType.LINE: 87 | drawLine(graphics, a, b); 88 | break; 89 | case LineType.RAY: 90 | drawRay(graphics, a, b); 91 | break; 92 | case LineType.SEGMENT: 93 | drawSegment(graphics, a, b); 94 | break; 95 | } 96 | } 97 | 98 | 99 | private function drawSegment(graphics:Graphics, a:Vertex, b:Vertex):void 100 | { 101 | graphics.moveTo(a.x, a.y); graphics.lineTo(b.x, b.y); 102 | } 103 | 104 | private function drawRay(graphics:Graphics, a:Vertex, b:Vertex):void 105 | { 106 | graphics.moveTo(a.x, a.y); 107 | 108 | var i:Number = b.x - a.x; 109 | var j:Number = b.y - a.y; 110 | 111 | var length:Number = Math.sqrt(i * i + j * j); 112 | var multiplier:Number = _diagonal / length; 113 | 114 | i *= multiplier; j *= multiplier; 115 | 116 | graphics.lineTo(b.x + i, b.y + j); 117 | } 118 | 119 | private function drawLine(graphics:Graphics, a:Vertex, b:Vertex):void 120 | { 121 | var i:Number = b.x - a.x; 122 | var j:Number = b.y - a.y; 123 | 124 | var length:Number = Math.sqrt(i * i + j * j); 125 | var multiplier:Number = _diagonal / length; 126 | 127 | i *= multiplier; 128 | j *= multiplier; 129 | 130 | graphics.moveTo(a.x - i, a.y - j); 131 | graphics.lineTo(b.x + i, b.y + j); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/PolygonDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import as3geometry.geom2D.ui.generic.UIDrawer; 4 | import as3geometry.AS3GeometryContext; 5 | import as3geometry.geom2D.Polygon; 6 | import as3geometry.geom2D.Vertex; 7 | 8 | import alecmce.ui.Paint; 9 | 10 | /** 11 | * Draws a polygon on a Euclidean plane 12 | * 13 | * (c) 2009 alecmce.com 14 | * 15 | * @author Alec McEachran 16 | */ 17 | public class PolygonDrawer extends UIDrawer 18 | { 19 | 20 | private var _polygon:Polygon; 21 | 22 | public function PolygonDrawer(context:AS3GeometryContext, polygon:Polygon, paint:Paint = null) 23 | { 24 | super(context, paint); 25 | addDefinien(_polygon = polygon); 26 | invalidate(); 27 | } 28 | 29 | public function get polygon():Polygon 30 | { 31 | return _polygon; 32 | } 33 | 34 | public function set polygon(value:Polygon):void 35 | { 36 | if (_polygon == value) 37 | return; 38 | 39 | removeDefinien(_polygon); 40 | _polygon = value; 41 | addDefinien(_polygon); 42 | invalidate(); 43 | } 44 | 45 | override protected function draw():void 46 | { 47 | var v:Vertex = polygon.getVertex(0); 48 | graphics.moveTo(v.x, v.y); 49 | 50 | var i:int = _polygon.countVertices; 51 | while (--i > -1) 52 | { 53 | v = _polygon.getVertex(i); 54 | graphics.lineTo(v.x, v.y); 55 | } 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/PolygonsDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.AdditiveCollection; 5 | import as3geometry.geom2D.CollectionOfPolygons; 6 | import as3geometry.geom2D.Polygon; 7 | import as3geometry.geom2D.ui.generic.UIDrawer; 8 | 9 | import alecmce.ui.Paint; 10 | 11 | import flash.utils.Dictionary; 12 | 13 | /** 14 | * 15 | * 16 | * (c) 2009 alecmce.com 17 | * 18 | * @author Alec McEachran 19 | */ 20 | public class PolygonsDrawer extends UIDrawer 21 | { 22 | 23 | private var _polygons:CollectionOfPolygons; 24 | 25 | private var _drawers:Dictionary; 26 | 27 | public function PolygonsDrawer(context:AS3GeometryContext, polygons:CollectionOfPolygons, paint:Paint = null) 28 | { 29 | super(context, paint); 30 | _drawers = new Dictionary(); 31 | 32 | addDefinien(_polygons = polygons); 33 | addAdditiveListeners(_polygons); 34 | generateDrawersForExistingPolygons(); 35 | } 36 | 37 | 38 | private function generateDrawersForExistingPolygons():void 39 | { 40 | var i:uint = _polygons.countPolygons; 41 | while (--i > -1) 42 | { 43 | var polygon:Polygon = _polygons.getPolygon(i); 44 | createPolygonDrawer(polygon); 45 | } 46 | } 47 | 48 | private function addAdditiveListeners(polygons:CollectionOfPolygons):void 49 | { 50 | var additive:AdditiveCollection = polygons as AdditiveCollection; 51 | if (!additive) 52 | return; 53 | 54 | additive.added.add(onPolygonAdded); 55 | additive.removed.add(onPolygonRemoved); 56 | } 57 | 58 | private function onPolygonAdded(polygon:Polygon):void 59 | { 60 | createPolygonDrawer(polygon); 61 | } 62 | 63 | private function onPolygonRemoved(polygon:Polygon):void 64 | { 65 | var drawer:PolygonDrawer = _drawers[polygon]; 66 | if (!drawer) 67 | return; 68 | 69 | removeChild(drawer); 70 | delete _drawers[polygon]; 71 | } 72 | 73 | private function createPolygonDrawer(polygon:Polygon):void 74 | { 75 | var drawer:PolygonDrawer = new PolygonDrawer(context, polygon, paint); 76 | 77 | addChild(drawer); 78 | _drawers[polygon] = drawer; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/TriangleDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Triangle; 5 | import as3geometry.geom2D.ui.generic.UIDrawer; 6 | 7 | import alecmce.ui.Paint; 8 | 9 | /** 10 | * 11 | * 12 | * (c) 2009 alecmce.com 13 | * 14 | * @author Alec McEachran 15 | */ 16 | public class TriangleDrawer extends UIDrawer 17 | { 18 | 19 | private var _triangle:Triangle; 20 | 21 | public function TriangleDrawer(context:AS3GeometryContext, triangle:Triangle, paint:Paint = null) 22 | { 23 | super(context, paint); 24 | addDefinien(_triangle = triangle); 25 | invalidate(); 26 | } 27 | 28 | public function get triangle():Triangle 29 | { 30 | return _triangle; 31 | } 32 | 33 | public function set triangle(value:Triangle):void 34 | { 35 | if (_triangle == value) 36 | return; 37 | 38 | removeDefinien(_triangle); 39 | _triangle = value; 40 | addDefinien(_triangle); 41 | invalidate(); 42 | } 43 | 44 | override protected function draw():void 45 | { 46 | graphics.moveTo(triangle.a.x, triangle.a.y); 47 | graphics.lineTo(triangle.b.x, triangle.b.y); 48 | graphics.lineTo(triangle.c.x, triangle.c.y); 49 | graphics.lineTo(triangle.a.x, triangle.a.y); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/VertexDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Vertex; 5 | import as3geometry.geom2D.ui.generic.UIDrawer; 6 | 7 | import alecmce.ui.Paint; 8 | 9 | /** 10 | * 11 | * 12 | * (c) 2009 alecmce.com 13 | * 14 | * @author Alec McEachran 15 | */ 16 | public class VertexDrawer extends UIDrawer 17 | { 18 | private var _vertex:Vertex; 19 | 20 | private var _radius:uint; 21 | 22 | public function VertexDrawer(context:AS3GeometryContext, vertex:Vertex, radius:uint = 4, paint:Paint = null) 23 | { 24 | super(context, paint); 25 | _radius = radius; 26 | addDefinien(_vertex = vertex); 27 | invalidate(); 28 | } 29 | 30 | public function get vertex():Vertex 31 | { 32 | return _vertex; 33 | } 34 | 35 | public function set vertex(value:Vertex):void 36 | { 37 | if (_vertex == value) 38 | return; 39 | 40 | removeDefinien(_vertex); 41 | _vertex = value; 42 | addDefinien(_vertex); 43 | invalidate(); 44 | } 45 | 46 | public function get radius():uint 47 | { 48 | return _radius; 49 | } 50 | 51 | public function set radius(value:uint):void 52 | { 53 | if (_radius == value) 54 | return; 55 | 56 | _radius = value; 57 | invalidate(); 58 | } 59 | 60 | override protected function draw():void 61 | { 62 | if (isNaN(_vertex.x) || isNaN(_vertex.y)) 63 | return; 64 | 65 | graphics.drawCircle(_vertex.x, _vertex.y, _radius); 66 | var p:Paint = paint; 67 | p.beginPaint(graphics); 68 | graphics.drawCircle(_vertex.x, _vertex.y, _radius); 69 | p.endPaint(graphics); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/generic/UIDrawer.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui.generic 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | 5 | import alecmce.ui.Paint; 6 | 7 | /** 8 | * 9 | * 10 | * (c) 2009 alecmce.com 11 | * 12 | * @author Alec McEachran 13 | */ 14 | public class UIDrawer extends UIMutableSprite 15 | { 16 | public function UIDrawer(context:AS3GeometryContext, paint:Paint = null) 17 | { 18 | super(context, paint); 19 | invalidate(); 20 | } 21 | 22 | final override public function set x(value:Number):void 23 | { 24 | // do nothing 25 | } 26 | 27 | final override public function set y(value:Number):void 28 | { 29 | // do nothing 30 | } 31 | 32 | override public function resolve():void 33 | { 34 | super.resolve(); 35 | 36 | var p:Paint = paint; 37 | graphics.clear(); 38 | p.beginPaint(graphics); 39 | draw(); 40 | p.endPaint(graphics); 41 | } 42 | 43 | protected function draw():void 44 | { 45 | 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/generic/UIMutableSprite.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui.generic 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | import alecmce.invalidation.signals.InvalidationSignal; 5 | 6 | import as3geometry.AS3GeometryContext; 7 | import as3geometry.abstract.Mutable; 8 | import as3geometry.geom2D.ui.DEFAULT_PAINT; 9 | 10 | import alecmce.ui.Paint; 11 | 12 | import flash.display.Sprite; 13 | 14 | /** 15 | * 16 | * 17 | * (c) 2009 alecmce.com 18 | * 19 | * @author Alec McEachran 20 | */ 21 | public class UIMutableSprite extends Sprite implements Invalidates 22 | { 23 | private var _paint:Paint; 24 | protected var _redraw:Boolean; 25 | 26 | private var _isInvalid:Boolean; 27 | private var _invalidated:InvalidationSignal; 28 | private var _context:AS3GeometryContext; 29 | 30 | public function UIMutableSprite(context:AS3GeometryContext, paint:Paint) 31 | { 32 | _context = context; 33 | _paint = paint; 34 | _redraw = true; 35 | _invalidated = new InvalidationSignal(); 36 | _context.invalidationManager.register(this); 37 | _isInvalid = false; 38 | } 39 | 40 | public function get paint():Paint 41 | { 42 | return _paint ||= DEFAULT_PAINT; 43 | } 44 | 45 | public function set paint(paint:Paint):void 46 | { 47 | _paint = paint; 48 | _redraw = true; 49 | invalidate(); 50 | } 51 | 52 | public function get context():AS3GeometryContext 53 | { 54 | return _context; 55 | } 56 | 57 | protected function addDefinien(definien:*):void 58 | { 59 | var abstract:Mutable = definien; 60 | if (abstract) 61 | _context.invalidationManager.addDependency(abstract, this); 62 | } 63 | 64 | protected function removeDefinien(definien:*):void 65 | { 66 | var abstract:Mutable = definien; 67 | if (abstract) 68 | _context.invalidationManager.removeDependency(abstract, this); 69 | } 70 | 71 | public function invalidate(resolveImmediately:Boolean = false):void 72 | { 73 | _isInvalid = true; 74 | _invalidated.dispatch(this, resolveImmediately); 75 | } 76 | 77 | public function resolve():void 78 | { 79 | _isInvalid = false; 80 | 81 | if (_redraw) 82 | { 83 | _redraw = false; 84 | redraw(); 85 | } 86 | } 87 | 88 | protected function redraw():void 89 | { 90 | 91 | } 92 | 93 | public function get invalidated():InvalidationSignal 94 | { 95 | return _invalidated; 96 | } 97 | 98 | public function get isInvalid():Boolean 99 | { 100 | return false; 101 | } 102 | 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/vertices/UIVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui.vertices 2 | { 3 | import alecmce.invalidation.Invalidates; 4 | 5 | import as3geometry.AS3GeometryContext; 6 | import as3geometry.geom2D.InteractiveVertex; 7 | import as3geometry.geom2D.ui.generic.UIMutableSprite; 8 | 9 | import alecmce.ui.Paint; 10 | 11 | /** 12 | * 13 | * 14 | * (c) 2009 alecmce.com 15 | * 16 | * @author Alec McEachran 17 | */ 18 | public class UIVertex extends UIMutableSprite implements InteractiveVertex, Invalidates 19 | { 20 | private var _workingX:Number; 21 | 22 | private var _workingY:Number; 23 | 24 | private var _radius:uint; 25 | 26 | public function UIVertex(context:AS3GeometryContext, paint:Paint = null, radius:uint = 4) 27 | { 28 | super(context, paint); 29 | _radius = radius; 30 | invalidate(); 31 | } 32 | 33 | override public function set x(value:Number):void 34 | { 35 | if (_workingX == value) return; 36 | 37 | _workingX = value; 38 | invalidate(); 39 | } 40 | 41 | override public function set y(value:Number):void 42 | { 43 | if (_workingY == value) 44 | return; 45 | 46 | _workingY = value; 47 | invalidate(); 48 | } 49 | 50 | public function set(x:Number, y:Number):void 51 | { 52 | _workingX = x; 53 | _workingY = y; 54 | invalidate(); 55 | } 56 | 57 | public function get radius():uint 58 | { 59 | return _radius; 60 | } 61 | 62 | public function set radius(radius:uint):void 63 | { 64 | _radius = radius; 65 | _redraw = true; 66 | invalidate(); 67 | } 68 | 69 | override public function resolve():void 70 | { 71 | super.resolve(); 72 | 73 | super.x = _workingX; 74 | super.y = _workingY; 75 | } 76 | 77 | 78 | override protected function redraw():void 79 | { 80 | var p:Paint = paint; 81 | graphics.clear(); 82 | p.beginPaint(graphics); 83 | graphics.drawCircle(0, 0, _radius); 84 | p.endPaint(graphics); 85 | } 86 | 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/vertices/UIVertexOnCircle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui.vertices 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Circle; 5 | import as3geometry.geom2D.InteractiveVertex; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.VertexOnCircle; 8 | import as3geometry.geom2D.ui.generic.UIMutableSprite; 9 | import as3geometry.geom2D.util.AngleHelper; 10 | 11 | import alecmce.ui.Paint; 12 | 13 | /** 14 | * 15 | * 16 | * (c) 2009 alecmce.com 17 | * 18 | * @author Alec McEachran 19 | */ 20 | public class UIVertexOnCircle extends UIMutableSprite implements VertexOnCircle, InteractiveVertex 21 | { 22 | private var _circle:Circle; 23 | 24 | private var _helper:AngleHelper; 25 | 26 | private var _tempX:Number; 27 | 28 | private var _tempY:Number; 29 | 30 | private var _radius:uint; 31 | 32 | private var _angle:Number; 33 | 34 | private var _positionSet:Boolean; 35 | 36 | public function UIVertexOnCircle(context:AS3GeometryContext, circle:Circle, angle:Number, paint:Paint = null, radius:uint = 4) 37 | { 38 | super(context, paint); 39 | addDefinien(_circle = circle); 40 | 41 | _angle = angle; 42 | _positionSet = false; 43 | _helper = new AngleHelper(); 44 | _radius = radius; 45 | 46 | invalidate(true); 47 | } 48 | 49 | override public function set x(value:Number):void 50 | { 51 | _tempX = value; 52 | _positionSet = true; 53 | invalidate(); 54 | } 55 | 56 | override public function set y(value:Number):void 57 | { 58 | _tempY = value; 59 | _positionSet = true; 60 | invalidate(); 61 | } 62 | 63 | public function set(x:Number, y:Number):void 64 | { 65 | _tempX = x; 66 | _tempY = y; 67 | _positionSet = true; 68 | invalidate(); 69 | } 70 | 71 | public function get circle():Circle 72 | { 73 | return _circle; 74 | } 75 | 76 | public function get angle():Number 77 | { 78 | return _angle; 79 | } 80 | 81 | public function set angle(angle:Number):void 82 | { 83 | _angle = angle; 84 | 85 | var center:Vertex = _circle.center; 86 | var radius:Number = _circle.radius; 87 | 88 | super.x = center.x + Math.cos(_angle) * radius; 89 | super.y = center.y + Math.sin(_angle) * radius; 90 | 91 | invalidate(); 92 | } 93 | 94 | override public function resolve():void 95 | { 96 | super.resolve(); 97 | 98 | var center:Vertex = _circle.center; 99 | var radius:Number = _circle.radius; 100 | 101 | var cx:Number = center.x; 102 | var cy:Number = center.y; 103 | 104 | if (_positionSet) 105 | { 106 | _positionSet = false; 107 | _angle = Math.atan2(_tempY - cy, _tempX - cx); 108 | } 109 | 110 | super.x = cx + Math.cos(_angle) * radius; 111 | super.y = cy + Math.sin(_angle) * radius; 112 | } 113 | 114 | 115 | override protected function redraw():void 116 | { 117 | var p:Paint = paint; 118 | graphics.clear(); 119 | p.beginPaint(graphics); 120 | graphics.drawCircle(0, 0, _radius); 121 | p.endPaint(graphics); 122 | } 123 | 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/ui/vertices/UIVertexOnParabola.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.ui.vertices 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Line; 5 | import as3geometry.geom2D.Parabola; 6 | import as3geometry.geom2D.SpatialVector; 7 | import as3geometry.geom2D.Vertex; 8 | import as3geometry.geom2D.VertexOnParabola; 9 | import as3geometry.geom2D.ui.generic.UIMutableSprite; 10 | import as3geometry.geom2D.util.ParabolaHelper; 11 | 12 | import alecmce.ui.Paint; 13 | 14 | public class UIVertexOnParabola extends UIMutableSprite implements VertexOnParabola 15 | { 16 | private var _parabola:Parabola; 17 | 18 | private var _helper:ParabolaHelper; 19 | 20 | private var _tempX:Number; 21 | 22 | private var _tempY:Number; 23 | 24 | private var _radius:uint; 25 | 26 | private var _parameter:Number; 27 | 28 | private var _positionSet:Boolean; 29 | private var _fromResolve:Boolean; 30 | 31 | public function UIVertexOnParabola(context:AS3GeometryContext, parabola:Parabola, parameter:Number, paint:Paint = null, radius:uint = 4) 32 | { 33 | super(context, paint); 34 | addDefinien(_parabola = parabola); 35 | 36 | _parameter = parameter; 37 | _positionSet = false; 38 | _helper = new ParabolaHelper(); 39 | _radius = radius; 40 | 41 | invalidate(true); 42 | } 43 | 44 | override public function set x(value:Number):void 45 | { 46 | _tempX = value; 47 | 48 | if (_fromResolve) 49 | { 50 | super.y = value; 51 | return; 52 | } 53 | 54 | _positionSet = true; 55 | invalidate(); 56 | } 57 | 58 | override public function set y(value:Number):void 59 | { 60 | _tempY = value; 61 | 62 | if (_fromResolve) 63 | { 64 | super.x = value; 65 | return; 66 | } 67 | 68 | _positionSet = true; 69 | invalidate(); 70 | } 71 | 72 | public function set(x:Number, y:Number):void 73 | { 74 | _tempX = x; 75 | _tempY = y; 76 | 77 | if (_fromResolve) 78 | { 79 | super.x = x; 80 | super.y = y; 81 | return; 82 | } 83 | 84 | _positionSet = true; 85 | invalidate(); 86 | } 87 | 88 | public function get parabola():Parabola 89 | { 90 | return _parabola; 91 | } 92 | 93 | public function get parameter():Number 94 | { 95 | return _parameter; 96 | } 97 | 98 | public function set parameter(value:Number):void 99 | { 100 | _parameter = value; 101 | 102 | var vertex:Vertex = _helper.vertexFromParameter(_parabola, value); 103 | super.x = vertex.x; 104 | super.y = vertex.y; 105 | 106 | invalidate(); 107 | } 108 | 109 | override public function resolve():void 110 | { 111 | super.resolve(); 112 | 113 | if (_positionSet) 114 | { 115 | _positionSet = false; 116 | 117 | var line:Line = _parabola.directrix; 118 | var a:Vertex = line.a; 119 | var v:SpatialVector = line.vector; 120 | 121 | var i:Number = v.i; 122 | var j:Number = v.j; 123 | var n:Number = _tempX - a.x; 124 | var m:Number = _tempY - a.y; 125 | 126 | _parameter = (n * i + m * j) / (i * i + j * j); 127 | } 128 | 129 | _fromResolve = true; 130 | _helper.vertexFromParameter(_parabola, _parameter, this); 131 | _fromResolve = false; 132 | } 133 | 134 | override protected function redraw():void 135 | { 136 | var p:Paint = paint; 137 | graphics.clear(); 138 | p.beginPaint(graphics); 139 | graphics.drawCircle(0, 0, _radius); 140 | p.endPaint(graphics); 141 | } 142 | 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/util/AngleHelper.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.util 2 | { 3 | import as3geometry.geom2D.Vertex; 4 | 5 | /** 6 | * Contains functions to calculate angles in various forms 7 | * 8 | * (c) 2009 alecmce.com 9 | * 10 | * @author Alec McEachran 11 | */ 12 | public class AngleHelper 13 | { 14 | 15 | private const TO_RADIANS:Number = Math.PI / 180; 16 | private const TO_DEGREES:Number = 180 / Math.PI; 17 | 18 | /** 19 | * find the (directed) angle between the vector [aI,aJ] and [bI,bJ] 20 | */ 21 | public function directedAngleFromVectors(aI:Number, aJ:Number, bI:Number, bJ:Number):Number 22 | { 23 | var angA:Number = -Math.atan2(aJ, aI); 24 | var cosA:Number = Math.cos(angA); 25 | var sinA:Number = Math.sin(angA); 26 | 27 | var i:Number = bI * cosA - bJ * sinA; 28 | var j:Number = bI * sinA + bJ * cosA; 29 | 30 | return Math.atan2(j, i); 31 | } 32 | 33 | public function directedAngleFromVertices(center:Vertex, a:Vertex, b:Vertex):Number 34 | { 35 | var aI:Number = a.x - center.x; var aJ:Number = a.y - center.y; var bI:Number = b.x - center.x; var bJ:Number = b.y - center.y; 36 | 37 | return directedAngleFromVectors(aI, aJ, bI, bJ); 38 | } 39 | 40 | public function toDegrees(radians:Number):Number 41 | { 42 | return radians * TO_DEGREES; 43 | } 44 | 45 | public function toRadians(degrees:Number):Number 46 | { 47 | return degrees * TO_RADIANS; 48 | } 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/util/LineHelper.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.util 2 | { 3 | import as3geometry.geom2D.Line; 4 | import as3geometry.geom2D.SpatialVector; 5 | import as3geometry.geom2D.Vertex; 6 | 7 | /** 8 | * Contains functions to calculate properties of lines 9 | * 10 | * (c) 2009 alecmce.com 11 | * 12 | * @author Alec McEachran 13 | */ 14 | public class LineHelper 15 | { 16 | 17 | public function isColinearByVertices(lineA:Vertex, lineB:Vertex, vertex:Vertex):Boolean 18 | { 19 | var j:Number = lineB.x - lineA.x; 20 | var i:Number = lineB.y - lineA.y; 21 | 22 | return j * (vertex.x - lineA.x) == i * (vertex.y - lineA.y); 23 | } 24 | 25 | public function isColinear(line:Line, vertex:Vertex):Boolean 26 | { 27 | var a:Vertex = line.a; 28 | var v:SpatialVector = line.vector; 29 | 30 | return v.j * (vertex.x - a.x) == v.i * (vertex.y - a.y); 31 | } 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/util/ParabolaHelper.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.util 2 | { 3 | import as3geometry.geom2D.InteractiveVertex; 4 | import as3geometry.geom2D.Line; 5 | import as3geometry.geom2D.Parabola; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.vertices.ImmutableVertex; 8 | 9 | public class ParabolaHelper 10 | { 11 | 12 | public function vertexFromParameter(parabola:Parabola, t:Number, target:InteractiveVertex = null):Vertex 13 | { 14 | var line:Line = parabola.directrix; 15 | 16 | var a:Vertex = line.a; 17 | var ax:Number = a.x; 18 | var ay:Number = a.y; 19 | 20 | var b:Vertex = line.b; 21 | var bx:Number = b.x; 22 | var by:Number = b.y; 23 | 24 | var c:Vertex = parabola.focus; 25 | var cx:Number = c.x; 26 | var cy:Number = c.y; 27 | 28 | var ab_x:Number = bx - ax; 29 | var ab_y:Number = by - ay; 30 | 31 | // d is the point on the line ab defined by t 32 | var dx:Number = ax + ab_x * t; 33 | var dy:Number = ay + ab_y * t; 34 | 35 | var dc_x:Number = dx - cx; 36 | var dc_y:Number = dy - cy; 37 | 38 | var n:Number = (dc_x * dc_x + dc_y * dc_y) / (2 * (ab_x * dc_y - ab_y * dc_x)); 39 | var ex:Number = dx + ab_y * n; 40 | var ey:Number = dy - ab_x * n; 41 | 42 | if (target) 43 | { 44 | target.set(ex, ey); 45 | return target; 46 | } 47 | 48 | return new ImmutableVertex(ex, ey); 49 | } 50 | 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/util/PolygonHelper.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.util 2 | { 3 | import as3geometry.geom2D.Line; 4 | import as3geometry.geom2D.Polygon; 5 | import as3geometry.geom2D.Vertex; 6 | 7 | /** 8 | * A collection of methods that are used to determine the properties of Polygons 9 | * 10 | * (c) 2009 alecmce.com 11 | * 12 | * @author Alec McEachran 13 | */ 14 | public class PolygonHelper 15 | { 16 | private const APPROXIMATE_ZERO:Number = 0.0001; 17 | 18 | public function polygonContains(polygon:Polygon, vertex:Vertex):Boolean 19 | { 20 | var angleSum:Number = 0; 21 | var len:uint = polygon.countVertices; 22 | 23 | var lineHelper:LineHelper = new LineHelper(); 24 | var angleHelper:AngleHelper = new AngleHelper(); 25 | 26 | for (var i:uint = 0; i < len; i++) 27 | { 28 | var line:Line = polygon.getEdge(i); 29 | if (lineHelper.isColinear(line, vertex)) 30 | return true; 31 | 32 | angleSum += angleHelper.directedAngleFromVertices(vertex, line.a, line.b); 33 | } 34 | 35 | if (angleSum < 0) 36 | return angleSum < -APPROXIMATE_ZERO; 37 | else 38 | return angleSum > APPROXIMATE_ZERO; 39 | } 40 | 41 | public function vertexPolygonContains(vertices:Array, vertex:Vertex):Boolean 42 | { 43 | var angleSum:Number = 0; 44 | var len:uint = vertices.length; 45 | 46 | var lineHelper:LineHelper = new LineHelper(); 47 | var angleHelper:AngleHelper = new AngleHelper(); 48 | 49 | var a:Vertex = vertices[len - 1]; 50 | for (var i:uint = 0; i < len; i++) 51 | { 52 | var b:Vertex = vertices[i]; 53 | 54 | if (lineHelper.isColinearByVertices(a, b, vertex)) 55 | return true; 56 | 57 | angleSum += angleHelper.directedAngleFromVertices(vertex, a, b); 58 | a = b; 59 | } 60 | 61 | if (angleSum < 0) 62 | return angleSum < -APPROXIMATE_ZERO; 63 | else 64 | return angleSum > APPROXIMATE_ZERO; 65 | } 66 | 67 | public function isPolygonClockwise(polygon:Polygon):Boolean 68 | { 69 | var value:Number = 0; 70 | var count:uint = polygon.countVertices; 71 | 72 | var a:Vertex = polygon.getVertex(0); 73 | for (var i:uint = 1; i < count; i++) 74 | { 75 | var b:Vertex = polygon.getVertex(i); 76 | value += a.x * b.y - b.x * a.y; 77 | a = b; 78 | } 79 | 80 | return value < 0; 81 | } 82 | 83 | /** 84 | * This method will fail if the vertices are not Vector, but the different 85 | * types of input Vector preclude generic-typing. 86 | */ 87 | public function isVertexPolygonClockwise(vertices:Array, count:int = -1):Boolean 88 | { 89 | var value:Number = 0; 90 | 91 | if (count == -1) 92 | count = vertices.length; 93 | 94 | var a:Vertex = vertices[0]; 95 | for (var i:uint = 1; i < count; i++) 96 | { 97 | var b:Vertex = vertices[i]; 98 | value += a.x * b.y - b.x * a.y; 99 | a = b; 100 | } 101 | 102 | return value < 0; 103 | } 104 | 105 | 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/vectors/ImmutableSpatialVector.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.vectors 2 | { 3 | import as3geometry.geom2D.SpatialVector; 4 | 5 | /** 6 | * Defines a vector that describes a translation on a cartesian plane 7 | * 8 | * (c) 2009 alecmce.com 9 | * 10 | * @author Alec McEachran 11 | */ 12 | public class ImmutableSpatialVector implements SpatialVector 13 | { 14 | 15 | private var i_:Number; 16 | 17 | private var j_:Number; 18 | 19 | private var length_:Number; 20 | 21 | 22 | public function ImmutableSpatialVector(i:Number, j:Number) 23 | { 24 | i_ = i; 25 | j_ = j; 26 | length_ = i_ * i_ + j_ * j_; 27 | } 28 | 29 | public function get i():Number 30 | { 31 | return i_; 32 | } 33 | 34 | public function get j():Number 35 | { 36 | return j_; 37 | } 38 | 39 | public function get length():Number 40 | { 41 | return length_; 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/vertices/ImmutableVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.vertices 2 | { 3 | import as3geometry.geom2D.Vertex; 4 | 5 | /** 6 | * Defines a vertex on a cartesian plane 7 | * 8 | * (c) 2009 alecmce.com 9 | * 10 | * @author Alec McEachran 11 | */ 12 | public class ImmutableVertex implements Vertex 13 | { 14 | 15 | private var _x:Number; 16 | 17 | private var _y:Number; 18 | 19 | 20 | public function ImmutableVertex(x:Number, y:Number) 21 | { 22 | _x = x; 23 | _y = y; 24 | } 25 | 26 | public function get x():Number 27 | { 28 | return _x; 29 | } 30 | 31 | public function get y():Number 32 | { 33 | return _y; 34 | } 35 | 36 | 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/vertices/IndependentVertex.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.vertices 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.InteractiveVertex; 6 | 7 | /** 8 | * Defines an independent vertex on a cartesian plane the position of which 9 | * can be changed by setting its x and y values or by using the set method 10 | * 11 | * (c) 2009 alecmce.com 12 | * 13 | * @author Alec McEachran 14 | */ 15 | public class IndependentVertex extends Mutable implements InteractiveVertex 16 | { 17 | 18 | private var _x:Number; 19 | private var _y:Number; 20 | 21 | public function IndependentVertex(context:AS3GeometryContext, x:Number, y:Number) 22 | { 23 | super(context); 24 | 25 | _x = x; 26 | _y = y; 27 | } 28 | 29 | public function set x(value:Number):void 30 | { 31 | if (_x == value) 32 | return; 33 | 34 | _x = value; 35 | invalidate(); 36 | } 37 | 38 | public function get x():Number 39 | { 40 | return _x; 41 | } 42 | 43 | public function set y(value:Number):void 44 | { 45 | if (_y == value) 46 | return; 47 | 48 | _y = value; 49 | invalidate(); 50 | } 51 | 52 | public function get y():Number 53 | { 54 | return _y; 55 | } 56 | 57 | 58 | public function set(x:Number, y:Number):void 59 | { 60 | _x = x; 61 | _y = y; 62 | invalidate(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/vertices/ProjectVertexToCircle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.vertices 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Circle; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.VertexOnCircle; 8 | 9 | /** 10 | * Creates a vertex that lies on a circle by projecting a vertex onto the surface 11 | * of the circle 12 | * 13 | * (c) 2010 alecmce.com 14 | * 15 | * @author Alec McEachran 16 | */ 17 | public class ProjectVertexToCircle extends Mutable implements VertexOnCircle 18 | { 19 | private var _circle:Circle; 20 | private var _vertex:Vertex; 21 | 22 | private var _x:Number; 23 | private var _y:Number; 24 | private var _angle:Number; 25 | 26 | public function ProjectVertexToCircle(context:AS3GeometryContext, circle:Circle, vertex:Vertex) 27 | { 28 | super(context); 29 | 30 | addDefinien(_circle = circle); addDefinien(_vertex = vertex); 31 | 32 | invalidate(true); 33 | } 34 | 35 | public function get circle():Circle 36 | { 37 | return _circle; 38 | } 39 | 40 | public function get angle():Number 41 | { 42 | return _angle; 43 | } 44 | 45 | public function get x():Number 46 | { 47 | return _x; 48 | } 49 | 50 | public function get y():Number 51 | { 52 | return _y; 53 | } 54 | 55 | override public function resolve():void 56 | { 57 | var dx:Number = _vertex.x - _circle.center.x; 58 | var dy:Number = _vertex.y - _circle.center.y; 59 | _angle = Math.atan2(dy, dx); 60 | 61 | _x = Math.cos(_angle) * _circle.radius; _y = Math.sin(_angle) * _circle.radius; 62 | } 63 | 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/as3geometry/geom2D/vertices/VertexOnCircle.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.vertices 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.abstract.Mutable; 5 | import as3geometry.geom2D.Circle; 6 | import as3geometry.geom2D.Vertex; 7 | import as3geometry.geom2D.VertexOnCircle; 8 | 9 | /** 10 | * 11 | * 12 | * (c) 2009 alecmce.com 13 | * 14 | * @author Alec McEachran 15 | */ 16 | public class VertexOnCircle extends Mutable implements VertexOnCircle 17 | { 18 | private var _circle:Circle; 19 | private var _angle:Number; 20 | 21 | private var _x:Number; private var _y:Number; 22 | private var _recalculateAngle:Boolean; 23 | 24 | public function VertexOnCircle(context:AS3GeometryContext, circle:Circle, angle:Number) 25 | { 26 | super(context); 27 | addDefinien(_circle = circle); 28 | _angle = angle; 29 | invalidate(); 30 | } 31 | 32 | public function get circle():Circle 33 | { 34 | return _circle; 35 | } 36 | 37 | public function get angle():Number 38 | { 39 | return _angle; 40 | } 41 | 42 | public function set angle(value:Number):void 43 | { 44 | _angle = value; 45 | invalidate(); 46 | } 47 | 48 | public function get x():Number 49 | { 50 | return _x; 51 | } 52 | 53 | public function get y():Number 54 | { 55 | return _y; 56 | } 57 | 58 | override public function resolve():void 59 | { 60 | super.resolve(); 61 | 62 | var center:Vertex = _circle.center; 63 | 64 | if (_recalculateAngle) 65 | { 66 | _angle = Math.atan2(_y - center.y, _x - center.x); 67 | _recalculateAngle = false; 68 | } 69 | 70 | var radius:Number = _circle.radius; 71 | _x = center.x + radius * Math.cos(_angle); _y = center.y + radius * Math.sin(_angle); 72 | } 73 | 74 | public function set(x:Number, y:Number):void 75 | { 76 | _x = x; 77 | _y = y; 78 | _recalculateAngle = true; 79 | invalidate(); 80 | } 81 | 82 | public function set x(value:Number):void 83 | { 84 | _x = value; 85 | _recalculateAngle = true; 86 | invalidate(); 87 | } 88 | 89 | public function set y(value:Number):void 90 | { 91 | _y = value; 92 | _recalculateAngle = true; 93 | invalidate(); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/examples/CircleSectorByVertices.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Circle; 4 | import as3geometry.geom2D.CircleSector; 5 | import as3geometry.geom2D.circle.MutableCircleSector; 6 | import as3geometry.geom2D.circle.MutableCircleWithRadialVertex; 7 | import as3geometry.geom2D.ui.CircleDrawer; 8 | import as3geometry.geom2D.ui.CircleSectorDrawer; 9 | import as3geometry.geom2D.ui.vertices.UIVertex; 10 | import as3geometry.geom2D.ui.vertices.UIVertexOnCircle; 11 | 12 | import alecmce.ui.interactive.DragMechanism; 13 | import alecmce.ui.paint.SolidPaint; 14 | 15 | /** 16 | * UI test verifies MutableCircleSector class 17 | * 18 | * (c) 2009 alecmce.com 19 | * 20 | * @author Alec McEachran 21 | */ 22 | [SWF(backgroundColor="#FFFFFF", frameRate="31", width="640", height="480")] 23 | public class CircleSectorByVertices extends ExampleBaseSprite 24 | { 25 | private var vertexPaint:SolidPaint; 26 | private var circlePaint:SolidPaint; 27 | private var rightSectorPaint:SolidPaint; 28 | private var leftSectorPaint:SolidPaint; 29 | 30 | private var dragMechanism:DragMechanism; 31 | 32 | private var a:UIVertex; 33 | private var b:UIVertex; 34 | private var c:UIVertexOnCircle; 35 | private var d:UIVertexOnCircle; 36 | 37 | private var circle:Circle; 38 | private var circleDrawer:CircleDrawer; 39 | 40 | private var rightSector:CircleSector; 41 | private var rightSectorDrawer:CircleSectorDrawer; 42 | 43 | private var leftSector:CircleSector; 44 | private var leftSectorDrawer:CircleSectorDrawer; 45 | 46 | 47 | override protected function init():void 48 | { 49 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 50 | circlePaint = new SolidPaint(0x0, 0xFF000000, 2); 51 | rightSectorPaint = new SolidPaint(0x66FF0000, 0xFF, 2); 52 | leftSectorPaint = new SolidPaint(0x661E90FF, 0xFF, 2); 53 | 54 | dragMechanism = new DragMechanism(); 55 | 56 | a = new UIVertex(_context, vertexPaint); 57 | dragMechanism.apply(a); 58 | a.x = 275; 59 | a.y = 200; 60 | 61 | b = new UIVertex(_context, vertexPaint); 62 | dragMechanism.apply(b); 63 | b.x = 450; 64 | b.y = 180; 65 | 66 | circle = new MutableCircleWithRadialVertex(_context, a, b); 67 | circleDrawer = new CircleDrawer(_context, circle, circlePaint); 68 | 69 | c = new UIVertexOnCircle(_context, circle, Math.PI * 0.2, vertexPaint); 70 | dragMechanism.apply(c); 71 | 72 | d = new UIVertexOnCircle(_context, circle, Math.PI, vertexPaint); 73 | dragMechanism.apply(d); 74 | 75 | rightSector = new MutableCircleSector(_context, c, d, true); 76 | rightSectorDrawer = new CircleSectorDrawer(_context, rightSector, rightSectorPaint); 77 | 78 | leftSector = new MutableCircleSector(_context, c, d, false); 79 | leftSectorDrawer = new CircleSectorDrawer(_context, leftSector, leftSectorPaint); 80 | 81 | addChild(circleDrawer); 82 | addChild(rightSectorDrawer); 83 | addChild(leftSectorDrawer); 84 | 85 | addChild(a); 86 | addChild(b); 87 | addChild(c); 88 | addChild(d); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/examples/CircleSegmentByVertices.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Circle; 4 | import as3geometry.geom2D.CircleSegment; 5 | import as3geometry.geom2D.circle.MutableCircleSegment; 6 | import as3geometry.geom2D.circle.MutableCircleWithRadialVertex; 7 | import as3geometry.geom2D.ui.CircleDrawer; 8 | import as3geometry.geom2D.ui.CircleSegmentDrawer; 9 | import as3geometry.geom2D.ui.vertices.UIVertex; 10 | import as3geometry.geom2D.ui.vertices.UIVertexOnCircle; 11 | 12 | import alecmce.ui.interactive.DragMechanism; 13 | import alecmce.ui.paint.SolidPaint; 14 | 15 | /** 16 | * UI test verifies MutableVertexOnCircle class 17 | * 18 | * (c) 2009 alecmce.com 19 | * 20 | * @author Alec McEachran 21 | */ 22 | [SWF(backgroundColor="#FFFFFF", frameRate="31", width="800", height="600")] 23 | public class CircleSegmentByVertices extends ExampleBaseSprite 24 | { 25 | private var vertexPaint:SolidPaint; 26 | private var circlePaint:SolidPaint; 27 | private var rightSegmentPaint:SolidPaint; private var leftSegmentPaint:SolidPaint; 28 | 29 | private var dragMechanism:DragMechanism; 30 | 31 | private var a:UIVertex; 32 | private var b:UIVertex; 33 | private var c:UIVertexOnCircle; 34 | private var d:UIVertexOnCircle; 35 | 36 | private var circle:Circle; 37 | private var circleDrawer:CircleDrawer; 38 | 39 | private var rightSegment:CircleSegment; 40 | private var rightSegmentDrawer:CircleSegmentDrawer; 41 | 42 | private var leftSegment:CircleSegment; 43 | private var leftSegmentDrawer:CircleSegmentDrawer; 44 | 45 | 46 | override protected function init():void 47 | { 48 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 49 | circlePaint = new SolidPaint(0x0, 0xFF000000, 2); 50 | rightSegmentPaint = new SolidPaint(0x66FF0000, 0xFF, 2); leftSegmentPaint = new SolidPaint(0x661E90FF, 0xFF, 2); 51 | 52 | dragMechanism = new DragMechanism(); 53 | 54 | a = new UIVertex(_context, vertexPaint); 55 | dragMechanism.apply(a); 56 | a.x = 275; 57 | a.y = 200; 58 | 59 | b = new UIVertex(_context, vertexPaint); 60 | dragMechanism.apply(b); 61 | b.x = 450; 62 | b.y = 180; 63 | 64 | trace(""); circle = new MutableCircleWithRadialVertex(_context, a, b); trace(""); 65 | circleDrawer = new CircleDrawer(_context, circle, circlePaint); 66 | 67 | c = new UIVertexOnCircle(_context, circle, Math.PI * 0.2, vertexPaint); 68 | dragMechanism.apply(c); 69 | 70 | d = new UIVertexOnCircle(_context, circle, Math.PI, vertexPaint); 71 | dragMechanism.apply(d); 72 | 73 | rightSegment = new MutableCircleSegment(_context, c, d, true); 74 | rightSegmentDrawer = new CircleSegmentDrawer(_context, rightSegment, rightSegmentPaint); 75 | 76 | leftSegment = new MutableCircleSegment(_context, c, d, false); 77 | leftSegmentDrawer = new CircleSegmentDrawer(_context, leftSegment, leftSegmentPaint); 78 | 79 | addChild(circleDrawer); 80 | addChild(rightSegmentDrawer); addChild(leftSegmentDrawer); 81 | 82 | addChild(a); 83 | addChild(b); 84 | addChild(c); 85 | addChild(d); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/examples/CircleSegmentFromCircleAndLine.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Circle; 4 | import as3geometry.geom2D.CircleSegment; 5 | import as3geometry.geom2D.Line; 6 | import as3geometry.geom2D.circle.MutableCircleSegment; 7 | import as3geometry.geom2D.circle.MutableCircleWithRadialVertex; 8 | import as3geometry.geom2D.intersection.IntersectionOfCircleAndLine; 9 | import as3geometry.geom2D.line.MutableLine; 10 | import as3geometry.geom2D.ui.CircleDrawer; 11 | import as3geometry.geom2D.ui.CircleSegmentDrawer; 12 | import as3geometry.geom2D.ui.LineDrawer; 13 | import as3geometry.geom2D.ui.vertices.UIVertex; 14 | 15 | import alecmce.ui.interactive.DragMechanism; 16 | import alecmce.ui.paint.SolidPaint; 17 | 18 | /** 19 | * UI test verifies circle segment classes 20 | * 21 | * (c) 2009 alecmce.com 22 | * 23 | * @author Alec McEachran 24 | */ 25 | [SWF(backgroundColor="#FFFFFF", frameRate="31", width="800", height="600")] 26 | public class CircleSegmentFromCircleAndLine extends ExampleBaseSprite 27 | { 28 | private var vertexPaint:SolidPaint; 29 | private var circlePaint:SolidPaint; 30 | private var rightSegmentPaint:SolidPaint; 31 | private var leftSegmentPaint:SolidPaint; 32 | 33 | private var dragMechanism:DragMechanism; 34 | 35 | private var a:UIVertex; 36 | private var b:UIVertex; 37 | private var c:UIVertex; 38 | private var d:UIVertex; 39 | 40 | private var circle:Circle; 41 | private var circleDrawer:CircleDrawer; 42 | 43 | private var line:Line; 44 | private var lineDrawer:LineDrawer; 45 | 46 | private var rightSegment:CircleSegment; 47 | private var rightSegmentDrawer:CircleSegmentDrawer; 48 | 49 | private var leftSegment:CircleSegment; 50 | private var leftSegmentDrawer:CircleSegmentDrawer; 51 | 52 | override protected function init():void 53 | { 54 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 55 | circlePaint = new SolidPaint(0x0, 0xFF000000, 2); 56 | rightSegmentPaint = new SolidPaint(0x66FF0000, 0xFF, 2); 57 | leftSegmentPaint = new SolidPaint(0x661E90FF, 0xFF, 2); 58 | 59 | dragMechanism = new DragMechanism(); 60 | 61 | a = new UIVertex(_context, vertexPaint); 62 | dragMechanism.apply(a); 63 | a.x = 80; 64 | a.y = 200; 65 | 66 | b = new UIVertex(_context, vertexPaint); 67 | dragMechanism.apply(b); 68 | b.x = 400; 69 | b.y = 180; 70 | 71 | c = new UIVertex(_context, vertexPaint); 72 | dragMechanism.apply(c); 73 | c.x = 275; 74 | c.y = 200; 75 | 76 | d = new UIVertex(_context, vertexPaint); 77 | dragMechanism.apply(d); 78 | d.x = 450; 79 | d.y = 180; 80 | 81 | line = new MutableLine(_context, a, b); 82 | lineDrawer = new LineDrawer(_context, line); 83 | 84 | circle = new MutableCircleWithRadialVertex(_context, c, d); 85 | circleDrawer = new CircleDrawer(_context, circle, circlePaint); 86 | 87 | var intersection:IntersectionOfCircleAndLine = new IntersectionOfCircleAndLine(_context, circle, line); 88 | rightSegment = new MutableCircleSegment(_context, intersection.first, intersection.second, true); 89 | rightSegmentDrawer = new CircleSegmentDrawer(_context, rightSegment, rightSegmentPaint); 90 | 91 | leftSegment = new MutableCircleSegment(_context, intersection.first, intersection.second, false); 92 | leftSegmentDrawer = new CircleSegmentDrawer(_context, leftSegment, leftSegmentPaint); 93 | 94 | addChild(lineDrawer); 95 | addChild(circleDrawer); 96 | addChild(rightSegmentDrawer); 97 | addChild(leftSegmentDrawer); 98 | 99 | addChild(a); 100 | addChild(b); 101 | addChild(c); 102 | addChild(d); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/examples/ExampleBaseSprite.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | 5 | import flash.display.Sprite; 6 | 7 | public class ExampleBaseSprite extends Sprite 8 | { 9 | protected var _context:AS3GeometryContext; 10 | 11 | public function ExampleBaseSprite() 12 | { 13 | _context = new AS3GeometryContext(this); 14 | init(); 15 | } 16 | 17 | public function get context():AS3GeometryContext 18 | { 19 | return _context; 20 | } 21 | 22 | protected function init():void 23 | { 24 | // to be overridden 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/examples/IntersectCircleAndLine.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Circle; 4 | import as3geometry.geom2D.Line; 5 | import as3geometry.geom2D.LineType; 6 | import as3geometry.geom2D.circle.MutableCircleWithRadialVertex; 7 | import as3geometry.geom2D.intersection.IntersectionOfCircleAndLine; 8 | import as3geometry.geom2D.line.MutableLine; 9 | import as3geometry.geom2D.ui.CircleDrawer; 10 | import as3geometry.geom2D.ui.LineDrawer; 11 | import as3geometry.geom2D.ui.VertexDrawer; 12 | import as3geometry.geom2D.ui.vertices.UIVertex; 13 | 14 | import alecmce.ui.interactive.DragMechanism; 15 | import alecmce.ui.paint.SolidPaint; 16 | 17 | /** 18 | * UI test verifies IntersectionOfCircleAndLine class 19 | * 20 | * (c) 2009 alecmce.com 21 | * 22 | * @author Alec McEachran 23 | */ 24 | public class IntersectCircleAndLine extends ExampleBaseSprite 25 | { 26 | private var vertexPaint:SolidPaint; 27 | private var intersectionPaint:SolidPaint; 28 | private var circlePaint:SolidPaint; 29 | 30 | private var dragMechanism:DragMechanism; 31 | 32 | private var a:UIVertex; 33 | private var b:UIVertex; 34 | private var c:UIVertex; private var d:UIVertex; 35 | 36 | private var circle:Circle; 37 | private var circleDrawer:CircleDrawer; 38 | 39 | private var line:Line; 40 | private var lineDrawer:LineDrawer; 41 | 42 | private var intersections:IntersectionOfCircleAndLine; 43 | 44 | private var n:VertexDrawer; private var m:VertexDrawer; 45 | 46 | override protected function init():void 47 | { 48 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 49 | circlePaint = new SolidPaint(0x66FFEE00, 0xFF0000CD, 2); 50 | intersectionPaint = new SolidPaint(0xFF0000CD, 0xFF, 2); 51 | 52 | dragMechanism = new DragMechanism(); 53 | 54 | a = new UIVertex(_context, vertexPaint); 55 | dragMechanism.apply(a); 56 | a.x = 80; 57 | a.y = 200; 58 | 59 | b = new UIVertex(_context, vertexPaint); 60 | dragMechanism.apply(b); 61 | b.x = 400; 62 | b.y = 180; 63 | 64 | c = new UIVertex(_context, vertexPaint); 65 | dragMechanism.apply(c); 66 | c.x = 300; 67 | c.y = 140; 68 | 69 | d = new UIVertex(_context, vertexPaint); 70 | dragMechanism.apply(d); 71 | d.x = 340; 72 | d.y = 260; 73 | 74 | line = new MutableLine(_context, a, b, LineType.SEGMENT); 75 | lineDrawer = new LineDrawer(_context, line); 76 | 77 | circle = new MutableCircleWithRadialVertex(_context, c, d); 78 | circleDrawer = new CircleDrawer(_context, circle, circlePaint); 79 | 80 | intersections = new IntersectionOfCircleAndLine(_context, circle, line); 81 | n = new VertexDrawer(_context, intersections.first, 5, intersectionPaint); m = new VertexDrawer(_context, intersections.second, 5, intersectionPaint); 82 | addChild(circleDrawer); addChild(lineDrawer); 83 | 84 | addChild(n); addChild(m); 85 | 86 | addChild(a); 87 | addChild(b); 88 | addChild(c); 89 | addChild(d); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/examples/IntersectLineAndLine.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Line; 4 | import as3geometry.geom2D.LineType; 5 | import as3geometry.geom2D.line.IntersectionOfTwoLinesVertex; 6 | import as3geometry.geom2D.line.MutableLine; 7 | import as3geometry.geom2D.ui.LineDrawer; 8 | import as3geometry.geom2D.ui.VertexDrawer; 9 | import as3geometry.geom2D.ui.vertices.UIVertex; 10 | 11 | import alecmce.ui.interactive.DragMechanism; 12 | import alecmce.ui.paint.SolidPaint; 13 | 14 | /** 15 | * UI test verifies IntersectionOfTwoLinesVertex 16 | * 17 | * (c) 2009 alecmce.com 18 | * 19 | * @author Alec McEachran 20 | */ 21 | public class IntersectLineAndLine extends ExampleBaseSprite 22 | { 23 | private var vertexPaint:SolidPaint; 24 | private var intersectionPaint:SolidPaint; 25 | 26 | private var dragMechanism:DragMechanism; 27 | 28 | private var a:UIVertex; 29 | private var b:UIVertex; 30 | private var c:UIVertex; 31 | private var d:UIVertex; 32 | 33 | private var lineA:Line; 34 | private var lineADrawer:LineDrawer; 35 | 36 | private var lineB:Line; 37 | private var lineBDrawer:LineDrawer; 38 | 39 | private var intersection:IntersectionOfTwoLinesVertex; 40 | private var n:VertexDrawer; 41 | 42 | public function IntersectLineAndLine() 43 | { 44 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 45 | intersectionPaint = new SolidPaint(0xFF0000CD, 0xFF, 2); 46 | 47 | dragMechanism = new DragMechanism(); 48 | 49 | a = new UIVertex(_context, vertexPaint); 50 | dragMechanism.apply(a); 51 | a.x = 80; 52 | a.y = 200; 53 | 54 | b = new UIVertex(_context, vertexPaint); 55 | dragMechanism.apply(b); 56 | b.x = 400; 57 | b.y = 180; 58 | 59 | c = new UIVertex(_context, vertexPaint); 60 | dragMechanism.apply(c); 61 | c.x = 300; 62 | c.y = 140; 63 | 64 | d = new UIVertex(_context, vertexPaint); 65 | dragMechanism.apply(d); 66 | d.x = 340; 67 | d.y = 260; 68 | 69 | lineA = new MutableLine(_context, a, b, LineType.SEGMENT); 70 | lineADrawer = new LineDrawer(_context, lineA); 71 | 72 | lineB = new MutableLine(_context, c, d, LineType.RAY); 73 | lineBDrawer = new LineDrawer(_context, lineB); 74 | 75 | intersection = new IntersectionOfTwoLinesVertex(_context, lineA, lineB); 76 | n = new VertexDrawer(_context, intersection, 5, intersectionPaint); 77 | 78 | addChild(lineADrawer); 79 | addChild(lineBDrawer); 80 | addChild(a); 81 | addChild(b); 82 | addChild(c); 83 | addChild(d); 84 | 85 | addChild(n); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/examples/IntersectTwoQuadrilaterals.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Polygon; 4 | import as3geometry.geom2D.polygons.MutablePolygon; 5 | import as3geometry.geom2D.polygons.intersection.IntersectionOfTwoPolygons; 6 | import as3geometry.geom2D.ui.PolygonDrawer; 7 | import as3geometry.geom2D.ui.PolygonsDrawer; 8 | import as3geometry.geom2D.ui.vertices.UIVertex; 9 | 10 | import alecmce.ui.interactive.DragMechanism; 11 | import alecmce.ui.paint.SolidPaint; 12 | 13 | /** 14 | * UI test verifies IntersectionOfCircleAndLine class 15 | * 16 | * (c) 2009 alecmce.com 17 | * 18 | * @author Alec McEachran 19 | */ 20 | public class IntersectTwoQuadrilaterals extends ExampleBaseSprite 21 | { 22 | private var vertexPaint:SolidPaint; 23 | private var intersectionPaint:SolidPaint; 24 | 25 | private var dragMechanism:DragMechanism; 26 | 27 | private var a:UIVertex; 28 | private var b:UIVertex; private var c:UIVertex; 29 | private var d:UIVertex; 30 | 31 | private var e:UIVertex; 32 | private var f:UIVertex; 33 | private var g:UIVertex; 34 | private var h:UIVertex; 35 | 36 | private var polygonA:Polygon; 37 | private var polygonADrawer:PolygonDrawer; 38 | 39 | private var polygonB:Polygon; 40 | private var polygonBDrawer:PolygonDrawer; 41 | 42 | private var intersections:IntersectionOfTwoPolygons; private var intersectionsDrawer:PolygonsDrawer; 43 | 44 | override protected function init():void 45 | { 46 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 47 | intersectionPaint = new SolidPaint(0x66FFEE00, 0xFF000000, 2); 48 | 49 | dragMechanism = new DragMechanism(); 50 | 51 | a = new UIVertex(_context, vertexPaint); 52 | dragMechanism.apply(a); 53 | a.x = 100; 54 | a.y = 50; 55 | 56 | b = new UIVertex(_context, vertexPaint); 57 | dragMechanism.apply(b); 58 | b.x = 300; 59 | b.y = 50; 60 | 61 | c = new UIVertex(_context, vertexPaint); 62 | dragMechanism.apply(c); 63 | c.x = 300; 64 | c.y = 250; 65 | 66 | d = new UIVertex(_context, vertexPaint); 67 | dragMechanism.apply(d); 68 | d.x = 100; 69 | d.y = 250; 70 | 71 | e = new UIVertex(_context, vertexPaint); 72 | dragMechanism.apply(e); 73 | e.x = 200; 74 | e.y = 150; 75 | 76 | f = new UIVertex(_context, vertexPaint); 77 | dragMechanism.apply(f); 78 | f.x = 400; 79 | f.y = 150; 80 | 81 | g = new UIVertex(_context, vertexPaint); 82 | dragMechanism.apply(g); 83 | g.x = 400; 84 | g.y = 350; 85 | 86 | h = new UIVertex(_context, vertexPaint); 87 | dragMechanism.apply(h); 88 | h.x = 200; 89 | h.y = 350; 90 | 91 | var vector:Array; 92 | 93 | vector = [a,b,c,d]; 94 | polygonA = new MutablePolygon(_context, vector); 95 | polygonADrawer = new PolygonDrawer(_context, polygonA); 96 | 97 | vector = [e,f,g,h]; 98 | polygonB = new MutablePolygon(_context, vector); 99 | polygonBDrawer = new PolygonDrawer(_context, polygonB); 100 | 101 | intersections = new IntersectionOfTwoPolygons(_context, polygonA, polygonB); 102 | intersectionsDrawer = new PolygonsDrawer(_context, intersections, intersectionPaint); 103 | addChild(intersectionsDrawer); addChild(polygonADrawer); addChild(polygonBDrawer); 104 | 105 | addChild(a); 106 | addChild(b); 107 | addChild(c); 108 | addChild(d); 109 | 110 | addChild(e); 111 | addChild(f); 112 | addChild(g); 113 | addChild(h); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/examples/IntersectTwoQuadrilateralsWithOppositeDirections.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Polygon; 4 | import as3geometry.geom2D.polygons.MutablePolygon; 5 | import as3geometry.geom2D.polygons.intersection.IntersectionOfTwoPolygons; 6 | import as3geometry.geom2D.ui.PolygonDrawer; 7 | import as3geometry.geom2D.ui.PolygonsDrawer; 8 | import as3geometry.geom2D.ui.vertices.UIVertex; 9 | 10 | import alecmce.ui.interactive.DragMechanism; 11 | import alecmce.ui.paint.SolidPaint; 12 | 13 | /** 14 | * UI test verifies IntersectionOfCircleAndLine class 15 | * 16 | * (c) 2009 alecmce.com 17 | * 18 | * @author Alec McEachran 19 | */ 20 | [SWF(backgroundColor="#FFFFFF", frameRate="100", width="800", height="600")] 21 | public class IntersectTwoQuadrilateralsWithOppositeDirections extends ExampleBaseSprite 22 | { 23 | private var vertexPaint:SolidPaint; 24 | private var intersectionPaint:SolidPaint; 25 | 26 | private var dragMechanism:DragMechanism; 27 | 28 | private var a:UIVertex; 29 | private var b:UIVertex; 30 | private var c:UIVertex; private var d:UIVertex; 31 | 32 | private var e:UIVertex; 33 | private var f:UIVertex; 34 | private var g:UIVertex; 35 | private var h:UIVertex; 36 | 37 | private var polygonA:Polygon; 38 | private var polygonADrawer:PolygonDrawer; 39 | 40 | private var polygonB:Polygon; 41 | private var polygonBDrawer:PolygonDrawer; 42 | 43 | private var intersections:IntersectionOfTwoPolygons; 44 | private var intersectionsDrawer:PolygonsDrawer; 45 | override protected function init():void 46 | { 47 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 48 | intersectionPaint = new SolidPaint(0x66FFEE00, 0xFF000000, 2); 49 | 50 | dragMechanism = new DragMechanism(); 51 | 52 | a = new UIVertex(_context, vertexPaint); 53 | dragMechanism.apply(a); 54 | a.x = 100; 55 | a.y = 50; 56 | 57 | b = new UIVertex(_context, vertexPaint); 58 | dragMechanism.apply(b); 59 | b.x = 300; 60 | b.y = 50; 61 | 62 | c = new UIVertex(_context, vertexPaint); 63 | dragMechanism.apply(c); 64 | c.x = 300; 65 | c.y = 250; 66 | 67 | d = new UIVertex(_context, vertexPaint); 68 | dragMechanism.apply(d); 69 | d.x = 100; 70 | d.y = 250; 71 | 72 | e = new UIVertex(_context, vertexPaint); 73 | dragMechanism.apply(e); 74 | e.x = 200; 75 | e.y = 150; 76 | 77 | f = new UIVertex(_context, vertexPaint); 78 | dragMechanism.apply(f); 79 | f.x = 200; 80 | f.y = 350; 81 | 82 | g = new UIVertex(_context, vertexPaint); 83 | dragMechanism.apply(g); 84 | g.x = 400; 85 | g.y = 350; 86 | 87 | h = new UIVertex(_context, vertexPaint); 88 | dragMechanism.apply(h); 89 | h.x = 400; 90 | h.y = 150; 91 | 92 | var vector:Array; 93 | 94 | vector = [a,b,c,d]; 95 | polygonA = new MutablePolygon(_context, vector); 96 | polygonADrawer = new PolygonDrawer(_context, polygonA); 97 | 98 | vector = [e,f,g,h]; 99 | polygonB = new MutablePolygon(_context, vector); 100 | polygonBDrawer = new PolygonDrawer(_context, polygonB); 101 | 102 | intersections = new IntersectionOfTwoPolygons(_context, polygonA, polygonB); 103 | intersectionsDrawer = new PolygonsDrawer(_context, intersections, intersectionPaint); 104 | addChild(intersectionsDrawer); addChild(polygonADrawer); addChild(polygonBDrawer); 105 | 106 | addChild(a); 107 | addChild(b); 108 | addChild(c); 109 | addChild(d); 110 | 111 | addChild(e); 112 | addChild(f); 113 | addChild(g); 114 | addChild(h); 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/examples/ParabolaFromLineAndVertex.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Line; 4 | import as3geometry.geom2D.Parabola; 5 | import as3geometry.geom2D.line.MutableLine; 6 | import as3geometry.geom2D.parabola.MutableParabola; 7 | import as3geometry.geom2D.ui.LineDrawer; 8 | import as3geometry.geom2D.ui.ParabolaDrawer; 9 | import as3geometry.geom2D.ui.vertices.UIVertex; 10 | 11 | import alecmce.ui.Paint; 12 | import alecmce.ui.interactive.DragMechanism; 13 | import alecmce.ui.paint.SolidPaint; 14 | 15 | [SWF(backgroundColor="#FFFFFF", frameRate="31", width="640", height="480")] 16 | public class ParabolaFromLineAndVertex extends ExampleBaseSprite 17 | { 18 | private var vertexPaint:SolidPaint; 19 | private var linePaint:Paint; 20 | 21 | private var dragMechanism:DragMechanism; 22 | 23 | private var a:UIVertex; 24 | private var b:UIVertex; 25 | private var c:UIVertex; 26 | 27 | private var line:Line; 28 | private var lineDrawer:LineDrawer; 29 | 30 | private var parabola:Parabola; 31 | private var parabolaDrawer:ParabolaDrawer; 32 | 33 | public function ParabolaFromLineAndVertex() 34 | { 35 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 36 | linePaint = new SolidPaint(0, 0xFF000000, 2); 37 | 38 | dragMechanism = new DragMechanism(); 39 | 40 | a = new UIVertex(_context, vertexPaint); 41 | dragMechanism.apply(a); 42 | a.x = 120; 43 | a.y = 300; 44 | 45 | b = new UIVertex(_context, vertexPaint); 46 | dragMechanism.apply(b); 47 | b.x = 400; 48 | b.y = 400; 49 | 50 | c = new UIVertex(_context, vertexPaint); 51 | dragMechanism.apply(c); 52 | c.x = 300; 53 | c.y = 250; 54 | 55 | line = new MutableLine(_context, a, b); 56 | lineDrawer = new LineDrawer(_context, line); 57 | 58 | parabola = new MutableParabola(_context, c, line); 59 | parabolaDrawer = new ParabolaDrawer(_context, parabola, linePaint); 60 | 61 | addChild(lineDrawer); 62 | addChild(parabolaDrawer); 63 | 64 | addChild(a); addChild(b); addChild(c); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/examples/ParabolaFromSegmentAndVertex.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Line; 4 | import as3geometry.geom2D.LineType; 5 | import as3geometry.geom2D.Parabola; 6 | import as3geometry.geom2D.line.MutableLine; 7 | import as3geometry.geom2D.parabola.MutableParabola; 8 | import as3geometry.geom2D.ui.LineDrawer; 9 | import as3geometry.geom2D.ui.ParabolaDrawer; 10 | import as3geometry.geom2D.ui.vertices.UIVertex; 11 | 12 | import alecmce.ui.Paint; 13 | import alecmce.ui.interactive.DragMechanism; 14 | import alecmce.ui.paint.SolidPaint; 15 | 16 | [SWF(backgroundColor="#FFFFFF", frameRate="31", width="640", height="480")] 17 | public class ParabolaFromSegmentAndVertex extends ExampleBaseSprite 18 | { 19 | private var vertexPaint:SolidPaint; 20 | private var linePaint:Paint; 21 | 22 | private var dragMechanism:DragMechanism; 23 | 24 | private var a:UIVertex; 25 | private var b:UIVertex; 26 | private var c:UIVertex; 27 | 28 | private var line:Line; 29 | private var lineDrawer:LineDrawer; 30 | 31 | private var parabola:Parabola; 32 | private var parabolaDrawer:ParabolaDrawer; 33 | 34 | public function ParabolaFromSegmentAndVertex() 35 | { 36 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 37 | linePaint = new SolidPaint(0, 0xFF000000, 2); 38 | 39 | dragMechanism = new DragMechanism(); 40 | 41 | a = new UIVertex(_context, vertexPaint); 42 | dragMechanism.apply(a); 43 | a.x = 120; 44 | a.y = 300; 45 | 46 | b = new UIVertex(_context, vertexPaint); 47 | dragMechanism.apply(b); 48 | b.x = 400; 49 | b.y = 400; 50 | 51 | c = new UIVertex(_context, vertexPaint); 52 | dragMechanism.apply(c); 53 | c.x = 300; 54 | c.y = 250; 55 | 56 | line = new MutableLine(_context, a, b, LineType.SEGMENT); 57 | lineDrawer = new LineDrawer(_context, line); 58 | 59 | parabola = new MutableParabola(_context, c, line); 60 | parabolaDrawer = new ParabolaDrawer(_context, parabola, linePaint); 61 | 62 | addChild(lineDrawer); 63 | addChild(parabolaDrawer); 64 | 65 | addChild(a); 66 | addChild(b); 67 | addChild(c); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/examples/ThreePoints.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Circle; 4 | import as3geometry.geom2D.Line; 5 | import as3geometry.geom2D.LineType; 6 | import as3geometry.geom2D.Triangle; 7 | import as3geometry.geom2D.circle.MutableCircle; 8 | import as3geometry.geom2D.circle.MutableCircleWithRadialVertex; 9 | import as3geometry.geom2D.line.MutableLine; 10 | import as3geometry.geom2D.polygons.MutableTriangle; 11 | import as3geometry.geom2D.ui.CircleDrawer; 12 | import as3geometry.geom2D.ui.LineDrawer; 13 | import as3geometry.geom2D.ui.TriangleDrawer; 14 | import as3geometry.geom2D.ui.vertices.UIVertex; 15 | 16 | import alecmce.ui.interactive.DragMechanism; 17 | import alecmce.ui.paint.SolidPaint; 18 | 19 | /** 20 | * An example of the current state of the as3geometry library. 21 | * 22 | * (c) 2009 alecmce.com 23 | * 24 | * @author Alec McEachran 25 | */ 26 | [SWF(backgroundColor="#FFFFFF", frameRate="100", width="800", height="600")] 27 | public class ThreePoints extends ExampleBaseSprite 28 | { 29 | private var vertexPaint:SolidPaint; 30 | private var circlePaint:SolidPaint; 31 | private var trianglePaint:SolidPaint; 32 | 33 | private var dragMechanism:DragMechanism; 34 | 35 | private var a:UIVertex; 36 | private var b:UIVertex; 37 | private var c:UIVertex; 38 | 39 | private var circle:Circle; 40 | private var circleDrawer:CircleDrawer; 41 | 42 | private var circle2:Circle; 43 | private var circleDrawer2:CircleDrawer; 44 | 45 | private var line:Line; 46 | private var lineDrawer:LineDrawer; 47 | 48 | private var segment:Line; 49 | private var segmentDrawer:LineDrawer; 50 | 51 | private var ray:Line; 52 | private var rayDrawer:LineDrawer; 53 | 54 | private var triangle:Triangle; 55 | private var triangleDrawer:TriangleDrawer; 56 | 57 | override protected function init():void 58 | { 59 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 60 | circlePaint = new SolidPaint(0x66FFEE00, 0xFF0000CD, 2); 61 | trianglePaint = new SolidPaint(0x661E90FF, 0, -1); 62 | 63 | dragMechanism = new DragMechanism(); 64 | 65 | a = new UIVertex(_context, vertexPaint); 66 | dragMechanism.apply(a); 67 | a.x = 80; 68 | a.y = 200; 69 | 70 | b = new UIVertex(_context, vertexPaint); 71 | dragMechanism.apply(b); 72 | b.x = 400; 73 | b.y = 180; 74 | 75 | c = new UIVertex(_context, vertexPaint); 76 | dragMechanism.apply(c); 77 | c.x = 300; 78 | c.y = 340; 79 | 80 | circle = new MutableCircle(_context, a, 50); 81 | circleDrawer = new CircleDrawer(_context, circle, circlePaint); 82 | 83 | circle2 = new MutableCircleWithRadialVertex(_context, b, c); 84 | circleDrawer2 = new CircleDrawer(_context, circle2, circlePaint); 85 | 86 | line = new MutableLine(_context, a, b); 87 | lineDrawer = new LineDrawer(_context, line); 88 | 89 | segment = new MutableLine(_context, b, c, LineType.SEGMENT); 90 | segmentDrawer = new LineDrawer(_context, segment); 91 | 92 | ray = new MutableLine(_context, c, a, LineType.RAY); 93 | rayDrawer = new LineDrawer(_context, ray); 94 | 95 | triangle = new MutableTriangle(_context, a, b, c); 96 | triangleDrawer = new TriangleDrawer(_context, triangle, trianglePaint); 97 | 98 | addChild(triangleDrawer); 99 | addChild(circleDrawer); 100 | addChild(lineDrawer); 101 | addChild(segmentDrawer); 102 | addChild(rayDrawer); 103 | addChild(circleDrawer2); 104 | addChild(a); 105 | addChild(b); 106 | addChild(c); 107 | } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/examples/VertexOnParabolaExample.as: -------------------------------------------------------------------------------- 1 | package examples 2 | { 3 | import as3geometry.geom2D.Line; 4 | import as3geometry.geom2D.Parabola; 5 | import as3geometry.geom2D.line.MutableLine; 6 | import as3geometry.geom2D.parabola.MutableParabola; 7 | import as3geometry.geom2D.ui.LineDrawer; 8 | import as3geometry.geom2D.ui.ParabolaDrawer; 9 | import as3geometry.geom2D.ui.vertices.UIVertex; 10 | import as3geometry.geom2D.ui.vertices.UIVertexOnParabola; 11 | 12 | import alecmce.ui.Paint; 13 | import alecmce.ui.interactive.DragMechanism; 14 | import alecmce.ui.paint.SolidPaint; 15 | 16 | [SWF(backgroundColor="#FFFFFF", frameRate="31", width="640", height="480")] 17 | public class VertexOnParabolaExample extends ExampleBaseSprite 18 | { 19 | private var vertexPaint:SolidPaint; 20 | private var linePaint:Paint; 21 | private var constrainedVertexPaint:Paint; 22 | 23 | private var dragMechanism:DragMechanism; 24 | 25 | private var a:UIVertex; 26 | private var b:UIVertex; 27 | private var c:UIVertex; 28 | private var d:UIVertexOnParabola; 29 | 30 | private var line:Line; 31 | private var lineDrawer:LineDrawer; 32 | 33 | private var parabola:Parabola; 34 | private var parabolaDrawer:ParabolaDrawer; 35 | 36 | public function VertexOnParabolaExample() 37 | { 38 | vertexPaint = new SolidPaint(0xFFFF0000, 0xFF000000, 2); 39 | linePaint = new SolidPaint(0, 0xFF000000, 2); 40 | constrainedVertexPaint = new SolidPaint(0xFFFFEE00, 0xFF000000, 2); 41 | 42 | dragMechanism = new DragMechanism(); 43 | 44 | a = new UIVertex(_context, vertexPaint); 45 | dragMechanism.apply(a); 46 | a.set(100, 300); 47 | 48 | b = new UIVertex(_context, vertexPaint); 49 | dragMechanism.apply(b); 50 | b.set(340,380); 51 | 52 | c = new UIVertex(_context, vertexPaint); 53 | dragMechanism.apply(c); 54 | c.set(320 + 50, 240 - 50); 55 | 56 | line = new MutableLine(_context, a, b); 57 | lineDrawer = new LineDrawer(_context, line); 58 | 59 | parabola = new MutableParabola(_context, c, line); 60 | parabolaDrawer = new ParabolaDrawer(_context, parabola, linePaint); 61 | 62 | d = new UIVertexOnParabola(_context, parabola, 0.5, constrainedVertexPaint); 63 | dragMechanism.apply(d); 64 | 65 | addChild(lineDrawer); 66 | addChild(parabolaDrawer); 67 | 68 | addChild(a); addChild(b); addChild(c); addChild(d); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /test/AllTests.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import alecmce.data.AllDataTests; 4 | import alecmce.invalidation.AllInvalidationTests; 5 | import alecmce.math.AllMathTests; 6 | 7 | [Suite] 8 | public class AllTests 9 | { 10 | public var invalidation:AllInvalidationTests; 11 | public var data:AllDataTests; 12 | public var math:AllMathTests; 13 | //public var as3geometry:AllGeometryTests; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/ProjectTestRunner.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import asunit.core.TextCore; 4 | 5 | import flash.display.Sprite; 6 | 7 | public class ProjectTestRunner extends Sprite 8 | { 9 | 10 | public function ProjectTestRunner() 11 | { 12 | var core:TextCore = new TextCore(); 13 | core.start(AllTests, null, this); 14 | } 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/alecmce/data/AllDataTests.as: -------------------------------------------------------------------------------- 1 | package alecmce.data 2 | { 3 | import alecmce.data.graph.AllDataGraphTests; 4 | 5 | [Suite] 6 | public class AllDataTests 7 | { 8 | public var graph:AllDataGraphTests; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/alecmce/data/graph/AllDataGraphTests.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | import alecmce.data.graph.algorithms.AllDataGraphAlgorithmsTests; 4 | 5 | [Suite] 6 | public class AllDataGraphTests 7 | { 8 | public var algorithms:AllDataGraphAlgorithmsTests; 9 | public var graph:GraphTest; public var directedGraph:DirectedGraphTest; 10 | public var directedAcyclicGraph:DirectedAcyclicGraphTest; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/alecmce/data/graph/DirectedAcyclicGraphTest.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | 4 | public class DirectedAcyclicGraphTest 5 | { 6 | private var graph:DirectedAcyclicGraph; 7 | 8 | private var a:Object; 9 | private var b:Object; 10 | private var c:Object; 11 | 12 | [Before] 13 | public function before():void 14 | { 15 | a = new MockGraphNode("a"); 16 | b = new MockGraphNode("b"); 17 | c = new MockGraphNode("c"); 18 | graph = new DirectedAcyclicGraph(); 19 | } 20 | 21 | [After] 22 | public function after():void 23 | { 24 | a = null; 25 | b = null; 26 | c = null; 27 | 28 | graph = null; 29 | } 30 | 31 | [Test(expects="Error")] 32 | public function cyclic_associations():void 33 | { 34 | graph.joinNodes(a, b); 35 | graph.joinNodes(b, c); 36 | graph.joinNodes(c, a); 37 | } 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/alecmce/data/graph/DirectedGraphTest.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | import asunit.asserts.assertFalse; 4 | import asunit.asserts.assertTrue; 5 | 6 | /** 7 | * @author amceachran 8 | */ 9 | public class DirectedGraphTest 10 | { 11 | private var graph:DirectedGraph; 12 | 13 | private var a:Object; 14 | private var b:Object; 15 | private var c:Object; 16 | 17 | [Before] 18 | public function before():void 19 | { 20 | a = new MockGraphNode("a"); 21 | b = new MockGraphNode("b"); 22 | c = new MockGraphNode("c"); 23 | graph = new DirectedGraph(); 24 | } 25 | 26 | [After] 27 | public function after():void 28 | { 29 | a = null; b = null; c = null; 30 | 31 | graph = null; 32 | } 33 | 34 | [Test] 35 | public function simple_association_is_unidirectional():void 36 | { 37 | graph.joinNodes(a, b); 38 | assertTrue(graph.areJoined(a, b)); assertFalse(graph.areJoined(b, a)); 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/alecmce/data/graph/GraphTest.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | import asunit.asserts.assertTrue; 4 | 5 | /** 6 | * @author amceachran 7 | */ 8 | public class GraphTest 9 | { 10 | private var graph:Graph; 11 | 12 | private var a:Object; 13 | private var b:Object; 14 | private var c:Object; 15 | 16 | [Before] 17 | public function before():void 18 | { 19 | a = new MockGraphNode("a"); 20 | b = new MockGraphNode("b"); 21 | c = new MockGraphNode("c"); 22 | graph = new Graph(); 23 | } 24 | 25 | [After] 26 | public function after():void 27 | { 28 | a = null; b = null; c = null; 29 | 30 | graph = null; 31 | } 32 | 33 | [Test] 34 | public function simple_association():void 35 | { 36 | graph.joinNodes(a, b); 37 | assertTrue(graph.areJoined(a, b)); assertTrue(graph.areJoined(b, a)); 38 | } 39 | 40 | [Test] 41 | public function divergent_associations():void 42 | { 43 | graph.joinNodes(a, b); 44 | graph.joinNodes(a, c); 45 | 46 | assertTrue(graph.areJoined(a, b)); assertTrue(graph.areJoined(a, c)); 47 | } 48 | 49 | [Test] 50 | public function convergent_associations():void 51 | { 52 | graph.joinNodes(a, b); graph.joinNodes(c, b); 53 | 54 | assertTrue(graph.areJoined(a, b)); 55 | assertTrue(graph.areJoined(c, b)); 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /test/alecmce/data/graph/MockGraphNode.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph 2 | { 3 | public class MockGraphNode 4 | { 5 | private var _id:String; 6 | 7 | public function MockGraphNode(id:String) 8 | { 9 | _id = id; 10 | } 11 | 12 | public function toString():String 13 | { 14 | return _id; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/alecmce/data/graph/algorithms/AllDataGraphAlgorithmsTests.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph.algorithms 2 | { 3 | 4 | [Suite] 5 | public class AllDataGraphAlgorithmsTests 6 | { 7 | public var dijkstra:DijkstraTest; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/alecmce/data/graph/algorithms/DijkstraTest.as: -------------------------------------------------------------------------------- 1 | package alecmce.data.graph.algorithms 2 | { 3 | import alecmce.data.graph.DirectedGraph; 4 | import alecmce.data.graph.MockGraphNode; 5 | 6 | import asunit.asserts.assertEquals; 7 | import asunit.asserts.assertSame; 8 | 9 | public class DijkstraTest 10 | { 11 | 12 | private var graph:DirectedGraph; 13 | private var algorithm:Dijkstra; 14 | 15 | private var a:Object; 16 | private var b:Object; 17 | private var c:Object; 18 | 19 | [Before] 20 | public function before():void 21 | { 22 | graph = new DirectedGraph(); 23 | a = new MockGraphNode("a"); 24 | b = new MockGraphNode("b"); 25 | c = new MockGraphNode("c"); 26 | algorithm = new Dijkstra(); 27 | } 28 | 29 | [After] 30 | public function after():void 31 | { 32 | a = null; 33 | b = null; 34 | c = null; 35 | 36 | algorithm = null; 37 | graph = null; 38 | } 39 | 40 | private function basicJoin():void 41 | { 42 | graph.joinNodes(a, b, 2); 43 | graph.joinNodes(b, c, 3); 44 | } 45 | 46 | [Test] 47 | public function basic_join_test_cost():void 48 | { 49 | basicJoin(); 50 | algorithm.apply(graph, a); 51 | assertEquals(5, algorithm.getCost(c)); 52 | } 53 | 54 | [Test] 55 | public function basic_join_test_route():void 56 | { 57 | basicJoin(); 58 | algorithm.apply(graph, a); 59 | 60 | var route:Vector. = algorithm.getRoute(c); 61 | assertSame(a, route[0]); assertSame(b, route[1]); assertSame(c, route[2]); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /test/alecmce/invalidation/AllInvalidationTests.as: -------------------------------------------------------------------------------- 1 | package alecmce.invalidation 2 | { 3 | 4 | [Suite] 5 | public class AllInvalidationTests 6 | { 7 | public var invalidate:InvalidateTest; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/alecmce/invalidation/ExampleInvalidator.as: -------------------------------------------------------------------------------- 1 | package alecmce.invalidation 2 | { 3 | import alecmce.invalidation.signals.InvalidationSignal; 4 | 5 | public class ExampleInvalidator implements Invalidates 6 | { 7 | private var _id:String; 8 | private var _isInvalid:Boolean; 9 | private var _invalidated:InvalidationSignal; 10 | 11 | public function ExampleInvalidator(id:String) 12 | { 13 | _id = id; 14 | _isInvalid = false; 15 | _invalidated = new InvalidationSignal(); 16 | } 17 | 18 | public function invalidate(resolve:Boolean = false):void 19 | { 20 | if (_isInvalid) 21 | return; 22 | 23 | _isInvalid = true; 24 | _invalidated.dispatch(this); 25 | } 26 | 27 | public function get invalidated():InvalidationSignal 28 | { 29 | return _invalidated; 30 | } 31 | 32 | public function get isInvalid():Boolean 33 | { 34 | return _isInvalid; 35 | } 36 | 37 | public function resolve():void 38 | { 39 | _isInvalid = false; 40 | } 41 | 42 | public function toString():String 43 | { 44 | return _id; 45 | } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/alecmce/invalidation/InvalidateTest.as: -------------------------------------------------------------------------------- 1 | package alecmce.invalidation 2 | { 3 | import asunit.asserts.assertFalse; 4 | import asunit.asserts.assertTrue; 5 | 6 | public class InvalidateTest 7 | { 8 | private var a:Invalidates; 9 | private var b:Invalidates; 10 | private var c:Invalidates; 11 | private var manager:InvalidationManager; 12 | 13 | [Before] 14 | public function before():void 15 | { 16 | manager = new InvalidationManager(); 17 | a = new ExampleInvalidator("a"); b = new ExampleInvalidator("b"); c = new ExampleInvalidator("c"); 18 | } 19 | 20 | [After] 21 | public function after():void 22 | { 23 | manager = null; 24 | a = null; b = null; 25 | } 26 | 27 | [Test] 28 | public function simple_invalidation():void 29 | { 30 | a.invalidate(); 31 | assertTrue(a.isInvalid); 32 | 33 | a.resolve(); 34 | assertFalse(a.isInvalid); 35 | } 36 | 37 | [Test] 38 | public function simple_invalidation_cycle():void 39 | { 40 | manager.register(a); 41 | a.invalidate(); 42 | 43 | manager.resolve(); 44 | assertFalse(a.isInvalid); 45 | } 46 | 47 | [Test] 48 | public function simple_invalidation_dependency_cycle():void 49 | { 50 | manager.register(a); 51 | manager.register(b); 52 | manager.addDependency(a, b); 53 | 54 | a.invalidate(); 55 | assertTrue(b.isInvalid); 56 | 57 | manager.resolve(); 58 | assertFalse(b.isInvalid); 59 | } 60 | 61 | [Test] 62 | public function registration_is_inferred_by_dependencies():void 63 | { 64 | manager.addDependency(a, b); 65 | 66 | a.invalidate(); 67 | assertTrue(b.isInvalid); 68 | } 69 | 70 | [Test] 71 | public function dependency_is_transitive():void 72 | { 73 | manager.register(a); 74 | manager.register(b); 75 | manager.register(c); 76 | manager.addDependency(a, b); manager.addDependency(b, c); 77 | 78 | a.invalidate(); 79 | assertTrue(c.isInvalid); 80 | 81 | manager.resolve(); 82 | assertFalse(a.isInvalid); 83 | assertFalse(b.isInvalid); 84 | assertFalse(c.isInvalid); 85 | } 86 | 87 | [Test(expects="Error")] 88 | public function dependencies_cannot_be_circular():void 89 | { 90 | manager.register(a); 91 | manager.register(b); 92 | manager.register(c); 93 | manager.addDependency(a, b); manager.addDependency(b, c); manager.addDependency(c, a); 94 | } 95 | 96 | [Test] 97 | public function dependencies_can_be_removed():void 98 | { 99 | manager.addDependency(a, b); 100 | manager.removeDependency(a, b); 101 | 102 | a.invalidate(); 103 | assertFalse(b.isInvalid); 104 | } 105 | 106 | [Test] 107 | public function invalidators_can_be_removed():void 108 | { 109 | manager.addDependency(a, b); 110 | manager.unregister(a); 111 | 112 | a.invalidate(); 113 | assertFalse(b.isInvalid); } 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /test/alecmce/math/AllMathTests.as: -------------------------------------------------------------------------------- 1 | package alecmce.math 2 | { 3 | [Suite] 4 | public class AllMathTests 5 | { 6 | public var primes:PrimesTest; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/alecmce/math/PrimesTest.as: -------------------------------------------------------------------------------- 1 | package alecmce.math 2 | { 3 | import asunit.asserts.assertEquals; 4 | import asunit.asserts.assertFalse; 5 | import asunit.asserts.assertTrue; 6 | public class PrimesTest 7 | { 8 | private var primes:Primes; 9 | 10 | [Before] 11 | public function before():void 12 | { 13 | primes = new Primes(); 14 | } 15 | 16 | [After] 17 | public function after():void 18 | { 19 | primes = null; 20 | } 21 | 22 | [Test] 23 | public function test_isPrime():void 24 | { 25 | assertTrue(primes.isPrime(7919)); 26 | assertFalse(primes.isPrime(100000)); 27 | } 28 | 29 | [Test] 30 | public function test_prime_factors():void 31 | { 32 | var factors:Vector. = primes.primeFactors(30); 33 | assertEquals(3, factors.length); assertEquals(2, factors[0]); 34 | assertEquals(3, factors[1]); assertEquals(5, factors[2]); 35 | } 36 | 37 | [Test] 38 | public function test_factors_and_resolve_roundtrip():void 39 | { 40 | var factors:Vector. = primes.primeFactors(30); 41 | assertEquals(30, primes.resolve(factors)); 42 | } 43 | 44 | [Test] 45 | public function highest_common_factors():void 46 | { 47 | var hcf:Vector. = primes.highestCommonFactor(Vector.([30,50])); 48 | assertEquals(2, hcf.length); 49 | assertEquals(2, hcf[0]); 50 | assertEquals(5, hcf[1]); 51 | } 52 | 53 | [Test] 54 | public function lowest_common_multiple():void 55 | { 56 | var lcm:Vector. = primes.lowestCommonMultiple(Vector.([15, 18])); 57 | assertEquals(4, lcm.length); assertEquals(2, lcm[0]); assertEquals(3, lcm[1]); assertEquals(3, lcm[2]); assertEquals(5, lcm[3]); 58 | } 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /test/as3geometry/AS3GeometryTestRunner.as: -------------------------------------------------------------------------------- 1 | package as3geometry 2 | { 3 | import asunit.runners.TestRunner; 4 | 5 | public class AS3GeometryTestRunner extends TestRunner 6 | { 7 | public function AS3GeometryTestRunner() 8 | { 9 | run(as3geometry.AllGeometryTests); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/as3geometry/AllGeometryTests.as: -------------------------------------------------------------------------------- 1 | package as3geometry 2 | { 3 | import as3geometry.geom2D.AllGeom2DTests; 4 | 5 | [Suite] 6 | public class AllGeometryTests 7 | { 8 | public var geom2DAllTests:AllGeom2DTests; } 9 | } 10 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/AllGeom2DTests.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D 2 | { 3 | import as3geometry.geom2D.util.AllUtilTests; 4 | import as3geometry.geom2D.immutable.AllImmutableTests; 5 | import as3geometry.geom2D.intersection.AllIntersectionTests; 6 | import as3geometry.geom2D.mutable.AllMutableTests; 7 | 8 | [Suite] 9 | public class AllGeom2DTests 10 | { 11 | public var immutableTests:AllImmutableTests; public var intersectionTests:AllIntersectionTests; public var mutableTests:AllMutableTests; public var utilTests:AllUtilTests; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/immutable/AllImmutableTests.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.immutable 2 | { 3 | [Suite] 4 | public class AllImmutableTests 5 | { 6 | public var immutableCircleTest:ImmutableCircleTest; public var immutableLineTest:ImmutableLineTest; public var immutablePolygonTest:ImmutablePolygonTest; public var immutableTriangleTest:ImmutableTriangleTest; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/immutable/ImmutableCircleTest.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.immutable 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.circle.ImmutableCircle; 6 | import as3geometry.geom2D.vertices.IndependentVertex; 7 | 8 | import asunit.asserts.fail; 9 | 10 | import flash.display.Sprite; 11 | 12 | public class ImmutableCircleTest 13 | { 14 | private var circle:ImmutableCircle; 15 | private var context:AS3GeometryContext; 16 | 17 | [Inject] 18 | public var sprite:Sprite; 19 | 20 | [Before] 21 | public function setup():void 22 | { 23 | context = new AS3GeometryContext(sprite); 24 | } 25 | 26 | [After] 27 | public function tearDown():void 28 | { 29 | circle = null; 30 | } 31 | 32 | [Test] 33 | public function mutableErrorIsThrown():void 34 | { 35 | var a:IndependentVertex = new IndependentVertex(context, 1, 1); 36 | 37 | try 38 | { 39 | circle = new ImmutableCircle(a, 2); 40 | } 41 | catch (error:MutabilityError) 42 | { 43 | return; 44 | } 45 | 46 | fail("ImmutableCircle should throw a mutability error if a mutable vertex is used as its centre"); 47 | } 48 | 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/immutable/ImmutableLineTest.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.immutable 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.line.ImmutableLine; 6 | import as3geometry.geom2D.vertices.ImmutableVertex; 7 | import as3geometry.geom2D.vertices.IndependentVertex; 8 | 9 | import asunit.asserts.fail; 10 | 11 | import flash.display.Sprite; 12 | 13 | public class ImmutableLineTest 14 | { 15 | [Inject] 16 | public var sprite:Sprite; 17 | 18 | private var line:ImmutableLine; 19 | private var context:AS3GeometryContext; 20 | 21 | 22 | [Before] 23 | public function setup():void 24 | { 25 | context = new AS3GeometryContext(sprite); 26 | } 27 | 28 | [After] 29 | public function tearDown():void 30 | { 31 | line = null; 32 | } 33 | 34 | [Test] 35 | public function mutableErrorIsThrown_parameterA():void 36 | { 37 | var a:IndependentVertex = new IndependentVertex(context, 1, 1); 38 | var b:ImmutableVertex = new ImmutableVertex(0, 0); 39 | 40 | try 41 | { 42 | line = new ImmutableLine(a, b); 43 | } 44 | catch (error:MutabilityError) 45 | { 46 | return; 47 | } 48 | 49 | fail("ImmutableLine should throw a mutability error if a mutable vertex is used as a defining point"); 50 | } 51 | 52 | [Test] 53 | public function mutableErrorIsThrown_parameterB():void 54 | { 55 | var a:ImmutableVertex = new ImmutableVertex(0, 0); 56 | var b:IndependentVertex = new IndependentVertex(context, 1, 1); 57 | 58 | try 59 | { 60 | line = new ImmutableLine(a, b); 61 | } 62 | catch (error:MutabilityError) 63 | { 64 | return; 65 | } 66 | 67 | fail("ImmutableLine should throw a mutability error if a mutable vertex is used as a defining point"); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/immutable/ImmutablePolygonTest.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.immutable 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.Polygon; 6 | import as3geometry.geom2D.polygons.ImmutablePolygon; 7 | import as3geometry.geom2D.vertices.ImmutableVertex; 8 | import as3geometry.geom2D.vertices.IndependentVertex; 9 | 10 | import asunit.asserts.assertFalse; 11 | import asunit.asserts.assertTrue; 12 | import asunit.asserts.fail; 13 | 14 | import flash.display.Sprite; 15 | 16 | public class ImmutablePolygonTest 17 | { 18 | [Inject] 19 | public var sprite:Sprite; 20 | 21 | private var polygon:ImmutablePolygon; 22 | private var context:AS3GeometryContext; 23 | 24 | [Before] 25 | public function setup():void 26 | { 27 | context = new AS3GeometryContext(sprite); 28 | } 29 | 30 | [After] 31 | public function tearDown():void 32 | { 33 | polygon = null; 34 | } 35 | 36 | [Test] 37 | public function mutableErrorIsThrown():void 38 | { 39 | var a:IndependentVertex = new IndependentVertex(context, 1, 0); 40 | var b:ImmutableVertex = new ImmutableVertex(1, 1); var c:ImmutableVertex = new ImmutableVertex(0, 1); var d:ImmutableVertex = new ImmutableVertex(0, 0); 41 | var vertices:Array = [a,b,c,d]; 42 | 43 | try 44 | { 45 | polygon = new ImmutablePolygon(vertices); 46 | } 47 | catch (error:MutabilityError) 48 | { 49 | return; 50 | } 51 | 52 | fail("ImmutablePolygon should throw a mutability error if a mutable vertex is used as a defining point"); 53 | } 54 | 55 | [Test] 56 | public function polygonContainsVertex():void 57 | { 58 | var polygon:Polygon = constructSquare(); 59 | assertTrue(polygon.contains(new ImmutableVertex(5, 5))); 60 | } 61 | 62 | [Test] 63 | public function polygonContainsVertexOnEdge():void 64 | { 65 | var polygon:Polygon = constructSquare(); 66 | assertTrue(polygon.contains(new ImmutableVertex(10, 5))); 67 | } 68 | 69 | [Test] 70 | public function polygonContainsVertexOnOtherEdge():void 71 | { 72 | var polygon:Polygon = constructSquare(); 73 | assertTrue(polygon.contains(new ImmutableVertex(0, 5))); 74 | } 75 | 76 | [Test] 77 | public function polygonContainsVertexAtVertex():void 78 | { 79 | var polygon:Polygon = constructSquare(); 80 | assertTrue(polygon.contains(new ImmutableVertex(0, 0))); 81 | } 82 | 83 | [Test] 84 | public function polygonContainsVertexAtOtherVertex():void 85 | { 86 | var polygon:Polygon = constructSquare(); 87 | assertTrue(polygon.contains(new ImmutableVertex(10, 10))); 88 | } 89 | 90 | [Test] 91 | public function polygonDoesntContainVertex():void 92 | { 93 | var polygon:Polygon = constructSquare(); 94 | assertFalse(polygon.contains(new ImmutableVertex(11, 5))); 95 | } 96 | 97 | [Test] 98 | public function polygonDoesntContainAnotherVertex():void 99 | { 100 | var polygon:Polygon = constructSquare(); 101 | assertFalse(polygon.contains(new ImmutableVertex(5, 11))); 102 | } 103 | 104 | private function constructSquare():Polygon 105 | { 106 | var a:ImmutableVertex = new ImmutableVertex(10,0); 107 | var b:ImmutableVertex = new ImmutableVertex(10,10); 108 | var c:ImmutableVertex = new ImmutableVertex(0,10); 109 | var d:ImmutableVertex = new ImmutableVertex(0,0); 110 | 111 | var vertices:Array = [a,b,c,d]; 112 | return new ImmutablePolygon(vertices); 113 | } 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/immutable/ImmutableTriangleTest.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.immutable 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.errors.MutabilityError; 5 | import as3geometry.geom2D.polygons.ImmutableTriangle; 6 | import as3geometry.geom2D.vertices.ImmutableVertex; 7 | import as3geometry.geom2D.vertices.IndependentVertex; 8 | 9 | import asunit.asserts.fail; 10 | 11 | import flash.display.Sprite; 12 | 13 | public class ImmutableTriangleTest 14 | { 15 | [Inject] 16 | public var sprite:Sprite; 17 | 18 | private var triangle:ImmutableTriangle; 19 | private var context:AS3GeometryContext; 20 | 21 | [Before] 22 | public function setup():void 23 | { 24 | context = new AS3GeometryContext(sprite); 25 | } 26 | 27 | [After] 28 | public function tearDown():void 29 | { 30 | triangle = null; 31 | } 32 | 33 | [Test] 34 | public function mutableErrorIsThrown_parameterA():void 35 | { 36 | var a:IndependentVertex = new IndependentVertex(context, 1,1); 37 | var b:ImmutableVertex = new ImmutableVertex(0,0); var c:ImmutableVertex = new ImmutableVertex(2,0); 38 | try 39 | { 40 | triangle = new ImmutableTriangle(a, b, c); 41 | } 42 | catch (error:MutabilityError) 43 | { 44 | return; 45 | } 46 | 47 | fail("ImmutableTriangle should throw a mutability error if a mutable vertex is used as a defining point"); 48 | } 49 | 50 | [Test] 51 | public function mutableErrorIsThrown_parameterB():void 52 | { 53 | var a:ImmutableVertex = new ImmutableVertex(0,5); 54 | var b:IndependentVertex = new IndependentVertex(context,1,1); 55 | var c:ImmutableVertex = new ImmutableVertex(0,0); 56 | 57 | try 58 | { 59 | triangle = new ImmutableTriangle(a, b, c); 60 | } 61 | catch (error:MutabilityError) 62 | { 63 | return; 64 | } 65 | 66 | fail("ImmutableTriangle should throw a mutability error if a mutable vertex is used as a defining point"); 67 | } 68 | 69 | [Test] 70 | public function mutableErrorIsThrown_parameterC():void 71 | { 72 | var a:ImmutableVertex = new ImmutableVertex(0,5); 73 | var b:ImmutableVertex = new ImmutableVertex(0,0); 74 | var c:IndependentVertex = new IndependentVertex(context,1,1); 75 | 76 | try 77 | { 78 | triangle = new ImmutableTriangle(a, b, c); 79 | } 80 | catch (error:MutabilityError) 81 | { 82 | return; 83 | } 84 | 85 | fail("ImmutableTriangle should throw a mutability error if a mutable vertex is used as a defining point"); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/intersection/AllIntersectionTests.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.intersection 2 | { 3 | [Suite] 4 | public class AllIntersectionTests 5 | { 6 | public var twoLines:IntersectionOfTwoLinesVertexTest; public var lineAndPolygon:IntersectionsOfLineAndPolygonTest; public var twoPolygons:IntersectionOfTwoPolygonsTest; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/intersection/IntersectionsOfLineAndPolygonTest.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.intersection 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Line; 5 | import as3geometry.geom2D.LineType; 6 | import as3geometry.geom2D.Polygon; 7 | import as3geometry.geom2D.Vertex; 8 | import as3geometry.geom2D.line.ImmutableLine; 9 | import as3geometry.geom2D.polygons.ImmutablePolygon; 10 | import as3geometry.geom2D.vertices.ImmutableVertex; 11 | 12 | import asunit.asserts.assertEquals; 13 | import asunit.asserts.assertTrue; 14 | 15 | import flash.display.Sprite; 16 | 17 | /** 18 | * 19 | * 20 | * (c) 2009 alecmce.com 21 | * 22 | * @author Alec McEachran 23 | */ 24 | public class IntersectionsOfLineAndPolygonTest 25 | { 26 | [Inject] 27 | public var root:Sprite; 28 | 29 | private var context:AS3GeometryContext; 30 | private var line:Line; 31 | private var polygon:Polygon; 32 | private var intersections:IntersectionsOfLineAndPolygon; 33 | 34 | [Before] 35 | public function before():void 36 | { 37 | context = new AS3GeometryContext(root); 38 | } 39 | 40 | [After] 41 | public function after():void 42 | { 43 | line = null; 44 | polygon = null; 45 | intersections = null; 46 | } 47 | 48 | [Test] 49 | public function squareWithHorizontalLine():void 50 | { 51 | generateSquare(); 52 | 53 | var a:Vertex = new ImmutableVertex(0, 5); var b:Vertex = new ImmutableVertex(10, 5); 54 | line = new ImmutableLine(a, b); 55 | 56 | intersections = new IntersectionsOfLineAndPolygon(context, polygon, line); 57 | var vertices:Array = intersections.actualIntersections; 58 | 59 | a = vertices[0]; 60 | b = vertices[1]; 61 | 62 | assertEquals(2, a.x); assertEquals(5, a.y); assertEquals(8, b.x); assertEquals(5, b.y); 63 | } 64 | 65 | 66 | [Test] 67 | public function squareWithVerticalLine():void 68 | { 69 | generateSquare(); 70 | 71 | var a:Vertex = new ImmutableVertex(5, 0); 72 | var b:Vertex = new ImmutableVertex(5, 10); 73 | line = new ImmutableLine(a, b); 74 | 75 | intersections = new IntersectionsOfLineAndPolygon(context, polygon, line); 76 | var vertices:Array = intersections.actualIntersections; 77 | 78 | a = vertices[0]; 79 | b = vertices[1]; 80 | 81 | assertEquals(5, a.x); 82 | assertEquals(2, a.y); 83 | assertEquals(5, b.x); 84 | assertEquals(8, b.y); 85 | } 86 | 87 | 88 | [Test] 89 | public function squareWithSmallLine():void 90 | { 91 | generateSquare(); 92 | 93 | var a:Vertex = new ImmutableVertex(0, 4); 94 | var b:Vertex = new ImmutableVertex(4, 4); 95 | line = new ImmutableLine(a, b, LineType.SEGMENT); 96 | 97 | intersections = new IntersectionsOfLineAndPolygon(context, polygon, line); 98 | var vertices:Array = intersections.actualIntersections; 99 | 100 | a = vertices[0]; 101 | b = vertices[1]; 102 | 103 | assertEquals(2, a.x); 104 | assertEquals(4, a.y); 105 | trace(b); 106 | assertTrue(isNaN(b.x)); 107 | assertTrue(isNaN(b.y)); 108 | } 109 | 110 | 111 | private function generateSquare():void 112 | { 113 | var vertices:Array = []; 114 | vertices[0] = new ImmutableVertex(2, 2); 115 | vertices[1] = new ImmutableVertex(8, 2); 116 | vertices[2] = new ImmutableVertex(8, 8); 117 | vertices[3] = new ImmutableVertex(2, 8); 118 | 119 | polygon = new ImmutablePolygon(vertices); 120 | } 121 | 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/mutable/AllMutableTests.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.mutable 2 | { 3 | [Suite] 4 | public class AllMutableTests 5 | { 6 | public var mutableAngle:MutableAnglesFromVectorsTest; } 7 | } 8 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/mutable/MutableAnglesFromVectorsTest.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.mutable 2 | { 3 | import as3geometry.AS3GeometryContext; 4 | import as3geometry.geom2D.Angle; 5 | import as3geometry.geom2D.angle.MutableAngleFromVectors; 6 | import as3geometry.geom2D.vectors.ImmutableSpatialVector; 7 | 8 | import asunit.asserts.assertEquals; 9 | 10 | import flash.display.Sprite; 11 | 12 | public class MutableAnglesFromVectorsTest 13 | { 14 | [Inject] 15 | public var root:Sprite; 16 | 17 | private var context:AS3GeometryContext; 18 | private var a:ImmutableSpatialVector; 19 | private var b:ImmutableSpatialVector; 20 | 21 | private var angle:Angle; 22 | 23 | [Before] 24 | public function before():void 25 | { 26 | context = new AS3GeometryContext(root); 27 | } 28 | 29 | [After] 30 | public function after():void 31 | { 32 | context = null; 33 | a = null; 34 | b = null; 35 | angle = null; 36 | } 37 | 38 | [Test] 39 | public function test90Degrees():void 40 | { 41 | a = new ImmutableSpatialVector(10, 0); 42 | b = new ImmutableSpatialVector(0, 10); 43 | angle = new MutableAngleFromVectors(context, a, b); 44 | 45 | assertEquals(90, angle.degrees); 46 | } 47 | 48 | [Test] 49 | public function test90DegreesNegative():void 50 | { 51 | a = new ImmutableSpatialVector(10, 0); 52 | b = new ImmutableSpatialVector(0, 10); 53 | angle = new MutableAngleFromVectors(context, b, a); 54 | 55 | assertEquals(-90, angle.degrees); 56 | } 57 | 58 | [Test] 59 | public function testAngleAcrossZeroLine():void 60 | { 61 | a = new ImmutableSpatialVector(5,-5); 62 | b = new ImmutableSpatialVector(5,5); 63 | angle = new MutableAngleFromVectors(context, a, b); 64 | 65 | assertEquals(90, angle.degrees); 66 | } 67 | 68 | [Test] 69 | public function testNegativeAngleAcrossZeroLine():void 70 | { 71 | a = new ImmutableSpatialVector(5,-5); 72 | b = new ImmutableSpatialVector(5,5); 73 | angle = new MutableAngleFromVectors(context, b, a); 74 | 75 | assertEquals(-90, angle.degrees); 76 | } 77 | 78 | [Test] 79 | public function testRoundtrip():void 80 | { 81 | var ang:Number = Math.PI / 3; 82 | 83 | var cos:Number = Math.cos(ang); 84 | var sin:Number = Math.sin(ang); 85 | a = new ImmutableSpatialVector(5 * cos, 5 * sin); 86 | 87 | cos = Math.cos(2 * ang); 88 | sin = Math.sin(2 * ang); 89 | b = new ImmutableSpatialVector(3 * cos, 3 * sin); 90 | 91 | angle = new MutableAngleFromVectors(context, a, b); 92 | assertEquals(ang, angle.radians); 93 | } 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/util/AllUtilTests.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.util 2 | { 3 | [Suite] 4 | public class AllUtilTests 5 | { 6 | public var polygonHelper:PolygonHelperTest; } 7 | } 8 | -------------------------------------------------------------------------------- /test/as3geometry/geom2D/util/PolygonHelperTest.as: -------------------------------------------------------------------------------- 1 | package as3geometry.geom2D.util 2 | { 3 | import as3geometry.geom2D.Polygon; 4 | import as3geometry.geom2D.polygons.ImmutablePolygon; 5 | import as3geometry.geom2D.vertices.ImmutableVertex; 6 | 7 | import asunit.asserts.assertFalse; 8 | import asunit.asserts.assertTrue; 9 | 10 | /** 11 | * 12 | * 13 | * (c) 2009 alecmce.com 14 | * 15 | * @author Alec McEachran 16 | */ 17 | public class PolygonHelperTest 18 | { 19 | private var helper:PolygonHelper; 20 | 21 | [Before] 22 | public function setUp():void 23 | { 24 | helper = new PolygonHelper(); 25 | } 26 | 27 | [After] 28 | public function tearDown():void 29 | { 30 | helper = null; 31 | } 32 | 33 | [Test] 34 | public function polygonIsAnticlockwise():void 35 | { 36 | var vertices:Array = []; vertices[0] = new ImmutableVertex(0, 0); vertices[1] = new ImmutableVertex(10, 0); vertices[2] = new ImmutableVertex(10, 10); 37 | vertices[3] = new ImmutableVertex(0, 10); 38 | 39 | var polygon:Polygon = new ImmutablePolygon(vertices); 40 | 41 | assertFalse(helper.isPolygonClockwise(polygon)); 42 | } 43 | 44 | [Test] 45 | public function polygonIsClockwise():void 46 | { 47 | var vertices:Array = []; 48 | vertices[0] = new ImmutableVertex(0, 0); 49 | vertices[1] = new ImmutableVertex(0, 10); 50 | vertices[2] = new ImmutableVertex(10, 10); 51 | vertices[3] = new ImmutableVertex(10, 0); 52 | 53 | var polygon:Polygon = new ImmutablePolygon(vertices); 54 | 55 | assertTrue(helper.isPolygonClockwise(polygon)); 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tmp/QuadraticBezier.as: -------------------------------------------------------------------------------- 1 | package com.alecmce.maths.geom.line 2 | { 3 | import org.osflash.signals.Signal; 4 | 5 | import flash.geom.Point; 6 | 7 | public class QuadraticBezier 8 | { 9 | private static const TWO_PI:Number = 2 * Math.PI; 10 | 11 | private var _sX:Number; private var _sY:Number; 12 | 13 | private var _fX:Number; private var _fY:Number; 14 | 15 | private var _cX:Number; private var _cY:Number; 16 | 17 | private var _scX:Number; 18 | private var _scY:Number; 19 | 20 | private var _cfX:Number; 21 | private var _cfY:Number; 22 | 23 | private var _changed:Signal; 24 | 25 | public function QuadraticBezier(sX:Number, sY:Number, fX:Number, fY:Number, cX:Number, cY:Number) 26 | { 27 | _sX = sX; 28 | _sY = sY; 29 | _fX = fX; 30 | _fY = fY; 31 | _cX = cX; 32 | _cY = cY; 33 | 34 | _scX = _cX - _sX; _scY = _cY - _sY; _cfX = _fX - _cX; _cfY = _fY - _cY; 35 | 36 | _changed = new Signal(); 37 | } 38 | 39 | public function position(value:Number):Point 40 | { 41 | var s2cX:Number = _sX + _scX * value; 42 | var s2cY:Number = _sY + _scY * value; 43 | var c2fX:Number = _cX + _cfX * value; 44 | var c2fY:Number = _cY + _cfY * value; 45 | 46 | return new Point(s2cX + (c2fX - s2cX) * value, s2cY + (c2fY - s2cY) * value); 47 | } 48 | 49 | public function cache(positions:Vector.):Vector. 50 | { 51 | var count:uint = positions.length; 52 | var result:Vector. = new Vector.(count, true); 53 | 54 | for (var i:int = 0;i < count;i++) 55 | result[i] = position(positions[i]); 56 | 57 | return result; 58 | } 59 | 60 | public function cacheVectors(positions:Vector.):Vector. 61 | { 62 | var count:uint = positions.length; 63 | var result:Vector. = new Vector.(count, true); 64 | var p:Point = position(positions[0]); 65 | 66 | for (var i:int = 1; i < count; i++) 67 | { 68 | var q:Point = position(positions[i]); 69 | var v:Point = new Point(q.x - p.x, q.y - p.y); 70 | result[i] = v; 71 | 72 | p = q; 73 | } 74 | 75 | return result; 76 | } 77 | 78 | public function variation(s:Number, f:Number, c:Number):QuadraticBezier 79 | { 80 | var angle:Number = Math.random() * TWO_PI; 81 | 82 | var sX:Number = _sX + Math.cos(angle) * s; var sY:Number = _sY + Math.sin(angle) * s; 83 | 84 | var fX:Number = _fX + Math.cos(angle) * f; 85 | var fY:Number = _fY + Math.sin(angle) * f; 86 | 87 | var cX:Number = _cX + Math.cos(angle) * c; 88 | var cY:Number = _cY + Math.sin(angle) * c; 89 | 90 | return new QuadraticBezier(sX, sY, fX, fY, cX, cY); 91 | } 92 | 93 | public function setStart(x:Number, y:Number):void 94 | { 95 | _sX = x; 96 | _sY = y; 97 | 98 | _scX = _cX - _sX; 99 | _scY = _cY - _sY; 100 | 101 | _changed.dispatch(); 102 | } 103 | 104 | public function setControl(x:Number, y:Number):void 105 | { 106 | _cX = x; 107 | _cY = y; 108 | 109 | _scX = _cX - _sX; 110 | _scY = _cY - _sY; 111 | _cfX = _fX - _cX; 112 | _cfY = _fY - _cY; 113 | 114 | _changed.dispatch(); 115 | } 116 | 117 | public function setFinish(x:Number, y:Number):void 118 | { 119 | _fX = x; 120 | _fY = y; 121 | 122 | _cfX = _fX - _cX; 123 | _cfY = _fY - _cY; 124 | 125 | _changed.dispatch(); 126 | } 127 | 128 | public function get sX():Number 129 | { 130 | return _sX; 131 | } 132 | 133 | public function get sY():Number 134 | { 135 | return _sY; 136 | } 137 | 138 | public function get fX():Number 139 | { 140 | return _fX; 141 | } 142 | 143 | public function get fY():Number 144 | { 145 | return _fY; 146 | } 147 | 148 | public function get cX():Number 149 | { 150 | return _cX; 151 | } 152 | 153 | public function get cY():Number 154 | { 155 | return _cY; 156 | } 157 | 158 | public function get changed():Signal 159 | { 160 | return _changed; 161 | } 162 | } 163 | } --------------------------------------------------------------------------------