From 5bed2f84ec67bef5bac7df778161219c348cd41b Mon Sep 17 00:00:00 2001 From: Nathan Curtis Date: Wed, 7 Mar 2007 20:10:11 +0000 Subject: [PATCH] testing for line intersections... this works in at least a reasonably trivial case - it will receive more extensive testing shortly git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4619 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- src/as/com/threerings/util/Line.as | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/as/com/threerings/util/Line.as b/src/as/com/threerings/util/Line.as index 9344288b0..71ead6e38 100644 --- a/src/as/com/threerings/util/Line.as +++ b/src/as/com/threerings/util/Line.as @@ -22,12 +22,17 @@ package com.threerings.util { import flash.geom.Point; +import flash.geom.Matrix; /** * Merely a typed container for two Points. */ public class Line { + public static const INTERSECTION_NORTH :int = 1; + public static const INTERSECTION_SOUTH :int = 2; + public static const DOES_NOT_INTERSECT :int = 3; + public var start :Point; public var stop :Point; @@ -36,5 +41,44 @@ public class Line this.start = start; this.stop = stop; } + + /** + * Tests if the given line intersects this line. If thats all you need to know, testing for + * intersects() != DOES_NOT_INTERSECT is enough. This method rotates both lines so that the + * start point is on the left. If the lines do intersect, it then returns INTERSECTION_NORTH + * if the end point of line is north of this line, INTERSECTION_SOUTH otherwise. + * + * Intersections are inclusive. If one or both points lands on this line, interects will not + * return DOES_NOT_INTERSECT. + */ + public function intersects (line :Line) :int + { + // rotate so that this line is horizontal, with the start on the left, at (0, 0) + var trans :Matrix = new Matrix(); + trans.translate(-start.x, -start.y); + trans.rotate(-Math.atan2(stop.y - start.y, stop.x - start.x)); + var thisLineStop :Point = trans.transformPoint(stop); + var thatLineStart :Point = trans.transformPoint(line.start); + var thatLineStop :Point = trans.transformPoint(line.stop); + if (thatLineStart.y >= 0 && thatLineStop.y <= 0) { + var interp :Point = Point.interpolate(thatLineStart, thatLineStop, thatLineStop.y / + (thatLineStop.y + (-thatLineStart.y))); + if (interp.x >= 0 && interp.x <= thisLineStop.x) { + return INTERSECTION_NORTH; + } else { + return DOES_NOT_INTERSECT; + } + } else if (thatLineStart.y <= 0 && thatLineStop.y >= 0) { + interp = Point.interpolate(thatLineStop, thatLineStart, thatLineStart.y / + (thatLineStart.y + (-thatLineStop.y))); + if (interp.x >= 0 && interp.x <= thisLineStop.x) { + return INTERSECTION_SOUTH; + } else { + return DOES_NOT_INTERSECT; + } + } else { + return DOES_NOT_INTERSECT; + } + } } }