Just a quick note: Keith Hair has a very sweet and useful series of posts about line intersections that have saved me more than a few hours of headbanging. In particular, his line intersection function is a marvelous paste-and-go solution, and I really feel like posting a small optimisation that accelerates the constraint checks at the end, which, as Nicolas Barradeau points out, do need some attention.
Instead of posting the whole function body here, here’s a recipe. First, get the original code from Keith’s post. Then, replace the function declaration with the following:
function lineIntersectLine ( A : Point, B : Point, E : Point, F : Point, ABasSeg : Boolean = true, EFasSeg : Boolean = true ) : Point
Finally, instead of the if (as_seg) block, paste this:
// Deal with rounding errors.
if ( A.x == B.x )
ip.x = A.x;
else if ( E.x == F.x )
ip.x = E.x;
if ( A.y == B.y )
ip.y = A.y;
else if ( E.y == F.y )
ip.y = E.y;
// Constrain to segment.
if ( ABasSeg )
{
if ( ( A.x < B.x ) ? ip.x < A.x || ip.x > B.x : ip.x > A.x || ip.x < B.x )
return null;
if ( ( A.y < B.y ) ? ip.y < A.y || ip.y > B.y : ip.y > A.y || ip.y < B.y )
return null;
}
if ( EFasSeg )
{
if ( ( E.x < F.x ) ? ip.x < E.x || ip.x > F.x : ip.x > E.x || ip.x < F.x )
return null;
if ( ( E.y < F.y ) ? ip.y < E.y || ip.y > F.y : ip.y > E.y || ip.y < F.y )
return null;
}
By having both an ABasSeg and EFasSeg parameters, you’ll be also able to easily intersect segments with lines:


Great!
You can’t know how useful it is to me! ;-)