Friday, January 2, 2009

2d line intersection test

Once upon a time, long, long ago... I wanted to find out where 2 line segments intersected in 2d.

I played with rise over run and all that dumb crap till I finally found somebuddy who had the math-magic I was looking for.

Here it is translated to haxe:

public static function intersectionTime(
line_0_x0:Float, line_0_y0:Float, line_0_x1:Float, line_0_y1:Float
, line_1_x0:Float, line_1_y0:Float, line_1_x1:Float, line_1_y1:Float
) {
var line_0_xdiff = line_0_x1 - line_0_x0;
var line_0_ydiff = line_0_y1 - line_0_y0;

var line_1_xdiff = line_1_x1 - line_1_x0;
var line_1_ydiff = line_1_y1 - line_1_y0;

var line_1_normal_x = line_1_ydiff;
var line_1_normal_y = -line_1_xdiff;
var l2 = (
line_1_normal_x * line_1_normal_x
+
line_1_normal_y * line_1_normal_y
);
if ( 0 != l2 ) {
l2 = Math.sqrt( l2 );
line_1_normal_x /= l2;
line_1_normal_y /= l2;
}

var denominator = (
-line_1_normal_x * line_0_xdiff
-line_1_normal_y * line_0_ydiff
);

var t = -1.0;
if ( 0 != denominator ) {
var numerator = ( 0
+ line_1_normal_x * ( line_0_x0 - line_1_x0 )
+ line_1_normal_y * ( line_0_y0 - line_1_y0 )
);
t = numerator / denominator;
}
return t;
}


I'm sure you can find some explanation of what it does and why it works, but sometimes... don't you just wanna rip off code?

"So what's the deal?" you ask? Fair enuff. You pass it the end points for two line segments and it returns where along the first segment the intersection would occur (-1 means never, sorry).

If it is between 0 and 1, that means it occurred some where along the first segment.

If you want to see if the intersection (or collision) occurred on both segments, you can then call with the segment orders reversed to see where on the other segment it hit ala:

var t_0 = App.intersectionTime(
line_0_x0, line_0_y0, line_0_x1, line_0_y1
,
line_1_x0, line_1_y0, line_1_x1, line_1_y1
);
var t_1 = App.intersectionTime(
line_1_x0, line_1_y0, line_1_x1, line_1_y1
,
line_0_x0, line_0_y0, line_0_x1, line_0_y1
);

var hit_on_0 = ( t_0 >= 0 && t_0 <= 1 );
var hit_on_1 = ( t_1 >= 0 && t_1 <= 1 );
var real_hit = hit_on_0 && hit_on_1;

var x = line_0_x0 + ( line_0_x1 - line_0_x0 ) * t_0;
var y = line_0_y0 + ( line_0_y1 - line_0_y0 ) * t_0;


Note if "real_hit" is true then x,y will be the coordinates for the actual intersection, otherwise it is where it would have hit on the first line (line_0).

Here you can see it in action.

Grab the code here and look at

./us/versus/them/weeds/App.hx
./us/versus/them/weeds/LineTest.hx


It's not the most optimized way to do things since there is some duplicated computation, but I know you don't wan me to have all the fun!

BTW.... does anyone know when/why these google turkeys stopped allowing the embed tag? Sheesh... Numbskulls! Yes... I am looking it in the mouth...

No comments:

Post a Comment