An alternative to simplify this type of equation is to use Math::VectorReal. There's a neat formula with vector cross products to solve this problem. It tests for being outside the segment as early as it can.
use strict; use Math::VectorReal; sub Intersection { my( $x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) = @_; my $v0 = vector($x1 - $x0, $y1 - $y0, 0); my $v1 = vector($x2 - $x0, $y2 - $y0, 0); my $v2 = vector($x3 - $x2, $y3 - $y2, 0); # Take vector cross products. Only Z is nonzero. my $a = ($v0 x $v1)->z(); my $b = ($v2 x $v0)->z(); # If |beta| > 1, line intersection outside segment. # Test it this way to avoid division by zero. return undef if abs($a) > abs($b); my $beta; if ($b == 0.0) { # 0/0 case $beta = 0.0; } else { $beta = $a/$b; } # Line intersection outside segment return undef if ($beta < 0.0); # Now check in the other direction $a = ($v2 x $v1)->z(); # |beta| > 1, line intersection outside segment return undef if abs($a) > abs($b); if ($b == 0) { # 0/0 case $beta = 0.0; } else { $beta = $a/$b; } # line intersection outside other side return undef if ($beta < 0.0); # find by parametric equation $px = $x2 + $beta*($x3 - $x2); $py = $y2 + $beta*($y3 - $y2); return [$px, $py]; }
In reply to Re: Re: line segment intersection
by tall_man
in thread line segment intersection
by bobdeath
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |