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 )