Math-Geometry-Planar-Offset
view release on metacpan or search on metacpan
lib/Math/Geometry/Planar/Offset.pm view on Meta::CPAN
my $split_time = $first_time;
# first find intersections of adjacent bisectors (if any)
for($n = 0;$n <$npoints;$n++) {
$Ax1 = $points->[$n][0];
$Ay1 = $points->[$n][1];
$Ax2 = $bis_end[$n][0];
$Ay2 = $bis_end[$n][1];
$delAx = $Ax2 - $Ax1;
$delAy = $Ay2 - $Ay1;
# elw: what amateur wrote this!
if($delAx) {
$Am = $delAy / $delAx; $Ab = $Ay1 - $Ax1 * $Am;
}
else {
$Am = "inf";
}
# Check against the next bisector:
$Bx1 = $points->[$n+1-$npoints][0];
$By1 = $points->[$n+1-$npoints][1];
$Bx2 = $bis_end[$n+1-$npoints][0];
$By2 = $bis_end[$n+1-$npoints][1];
$delBx = $Bx2 - $Bx1;
$delBy = $By2 - $By1;
# elw: maybe you are getting closer to zen now:)
if($delBx) {
$Bm = $delBy / $delBx;$Bb = $By1 - $Bx1 * $Bm;
}
else{
$Bm = "inf";
}
if( ($Am == $Bm) || ($Am eq $Bm) ) {
next;
}
# Calculate determinants to find if intersection is within the bisector segment.
if (! _do_cross($Ax1,$Ay1,$Ax2,$Ay2,$Bx1,$By1,$Bx2,$By2) ){
next;
}
# if we have an intersection of the skeleton and only a triangle,
# then it has collapsed to a point:
if($npoints < 4) {
$debug && print "collapsed\n";
return();
}
if($Am eq "inf") { # Slope of first line is infinite, so use Ax1.
$x_int = $Ax1; # Will always be on vertical line.
$y_int = $Bm * $x_int + $Bb;
}
elsif($Bm eq "inf") { # Slope of second line is infinite, so use Bx1.
$x_int = $Bx1;$y_int = $Am * $x_int + $Ab;
}
else {
$x_int = ($Bb - $Ab) / ($Am - $Bm);$y_int = $Am *$x_int + $Ab;
}
# Now, if the lines are not parallel, and the intersection
# happens on the line segments, we are here with
# the x and y coordinates of the intersection of the two lines.
## $debug and printf ("intersection: %6.0f,%6.0f\n",$x_int, $y_int);
# Let's find the time of intersect.
# distance formula with adjustment for speed
$time = sqrt( ($x_int - $points->[$n][0])**2 + ($y_int - $points->[$n][1])**2 ) / $bis_scale[$n];
if( (abs($time) < $first_time) )
# && ( $time / abs($time)== $offset / abs($offset) ) )
{
# note that none of the times loaded here have a sign
$first_time = abs($time);
$join_time = $first_time;
$first_join=$n;
$first_event="join";
}
} # end for n (for each bisector vs next neighbor)
# Time is smallest relevant offset distance before first join.
# first join is address of point to be joined.
# first event is "join" if controlling (could be over-ridden by split)
# If this is the controlling case, create the joined polygon at that offset time
# and make a recursive call.
#
#
# Now to check for intersections of bisectors with edges
# Have to check against all segments except adjacent ones.
# Nothing will happen if it is a triangle.
if($npoints > 3) {
for($n = 0; $n < $npoints; $n++) {
$Ax1 = $points->[$n][0]; # Get bisector endpoints
$Ay1 = $points->[$n][1];
$Ax2 = $bis_end[$n][0];
$Ay2 = $bis_end[$n][1];
$debug && print "starting at $Ax1 $Ay1\n";
$debug && print "bisector toward $Ax2 $Ay2\n";
# I need it to be a ray, so I am just making a really long segment here.
$delAx = 1000* $offset* ($Ax2 - $Ax1);
$delAy = 1000* $offset* ($Ay2 - $Ay1);
$Ax2 = $Ax1+ $delAx;
$Ay2 = $Ay1 + $delAy;
if($delAx) {$Am = $delAy / $delAx; $Ab = $Ay1 - $Ax1 * $Am;}else{$Am = "inf";};
# this loop has to compare to all of the polygon sides except the adjacent ones
for($n2 = 0; $n2 < $npoints; $n2++) {
$time = abs($offset) +1;
# Can't split adjacent segments
if( ($n2 == $n) || ($n2 == $n-1) || ( ($n==0)&&($n2 == $npoints-1) ) ){
next;
}
$debug && print "inner loop at n2 = $n2\n";
$Bx1 = $points->[$n2][0]; # Get edge endpoints
$By1 = $points->[$n2][1];
$Bx2 = $points->[$n2 + 1 - $npoints][0];
$By2 = $points->[$n2+1-$npoints][1];
$delBx = $Bx2 - $Bx1;
$delBy = $By2 - $By1;
if($delBx) {
$Bm = $delBy / $delBx;$Bb = $By1 - $Bx1 * $Bm;
}
else {
$Bm = "inf";
}
if( ($Am == $Bm) || ($Am eq $Bm) ){
next;
}
( run in 3.871 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )