A quick note on line and segment intersection (as3)

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:

Bookmark and Share

3 Responses to “A quick note on line and segment intersection (as3)”


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

  • nice function! I’ve used it in my application, and found a small bug with (almost) horizontal and vertical line segments:

    where
    A = (3.0999999999999996, 3.1499999999999995)
    B = (5, 3.15)

    E = (3.1499999999999995, 5.8500000000000005)
    F = (3.1499999999999995, 3.0999999999999996)

    and
    ip = (3.1499999999999995, 3.149999999999999)

    this line executes and returns null:
    if ( ( A.y < B.y ) ? ip.y B.y : ip.y > A.y || ip.y A.y

    • Hey Jack,
      I see your point – I’ll look into it when I have some time, but sounds like bigtime rounding errors.
      What sort of app runs into this kind of trouble ???? :)
      Thanks for the comment

Leave a Reply