Line-Line Intersection in AS3

I found a bug in my old Line-Line Intersection in C++ post, and after I fixed it I thought it would be a good idea to port it to AS3:
function intersection(p1:Point, p2:Point, p3:Point, p4:Point):Point {
var x1:Number = p1.x, x2:Number = p2.x, x3:Number = p3.x, x4:Number = p4.x;
var y1:Number = p1.y, y2:Number = p2.y, y3:Number = p3.y, y4:Number = p4.y;
var z1:Number= (x1 -x2), z2:Number = (x3 - x4), z3:Number = (y1 - y2), z4:Number = (y3 - y4);
var d:Number = z1 * z4 - z3 * z2;
// If d is zero, there is no intersection
if (d == 0) return null;
// Get the x and y
var pre:Number = (x1*y2 - y1*x2), post:Number = (x3*y4 - y3*x4);
var x:Number = ( pre * z2 - z1 * post ) / d;
var y:Number = ( pre * z4 - z3 * post ) / d;
// Check if the x and y coordinates are within both lines
if ( x < Math.min(x1, x2) || x > Math.max(x1, x2) ||
x < Math.min(x3, x4) || x > Math.max(x3, x4) ) return null;
if ( y < Math.min(y1, y2) || y > Math.max(y1, y2) ||
y < Math.min(y3, y4) || y > Math.max(y3, y4) ) return null;
// Return the point of intersection
return new Point(x, y);
}
You can try it here:
July 13th, 2009 at 8:11 pm
Before using this for something like collision detection in a game, you will want to expand your analysis for the cases where your determinant is zero. A zero determinant (d==0) tells you there is no UNIQUE point of intersection between the lines passing through your points. The lines are either parallel or collinear. But… your function is not a line-line intersection function, it’s really a line segment intersection function, so there are more cases to breakdown when d==0:
You could have a valid intersection if the line segments are collinear and share a point. Consider the simple case where all 4 points are on the same line, and the segments share an endpoint. Your function will return null, but it really should return the intersection point (the common endpoint). Ditto for the completely degenerate case where p1==p2==p3==p4.
In the case where your segments are collinear and overlap by more than an endpoint, the most correct thing to do would be to return the segment that represents the intersection. This will require a more general return type (a segment type, i.e. two points).