Merge pull request #1107 from obra/nearest_point_index_perf_part_2

Nearest point index perf work part 2
This commit is contained in:
Alessandro Ranellucci 2013-04-08 12:09:49 -07:00
commit 6b989203b4

View file

@ -7,7 +7,7 @@ our @ISA = qw(Exporter);
our @EXPORT_OK = qw(
PI X Y Z A B X1 Y1 X2 Y2 MIN MAX epsilon slope line_atan lines_parallel
line_point_belongs_to_segment points_coincide distance_between_points
comparable_distance_between_points chained_path_items chained_path_points
chained_path_items chained_path_points
line_length midpoint point_in_polygon point_in_segment segment_in_segment
point_is_on_left_of_segment polyline_lines polygon_lines nearest_point
point_along_segment polygon_segment_having_point polygon_has_subsegment
@ -115,11 +115,6 @@ sub distance_between_points {
return sqrt((($p1->[X] - $p2->[X])**2) + ($p1->[Y] - $p2->[Y])**2);
}
sub comparable_distance_between_points {
my ($p1, $p2) = @_;
return (($p1->[X] - $p2->[X])**2) + (($p1->[Y] - $p2->[Y])**2);
}
sub point_line_distance {
my ($point, $line) = @_;
return distance_between_points($point, $line->[A])
@ -248,14 +243,27 @@ sub nearest_point_index {
my ($point, $points) = @_;
my ($nearest_point_index, $distance) = ();
my $point_x = $point->[X];
my $point_y = $point->[Y];
for my $i (0..$#$points) {
my $d = comparable_distance_between_points($point, $points->[$i]);
if (!defined $distance || $d < $distance) {
$nearest_point_index = $i;
$distance = $d;
return $i if $distance < epsilon;
}
my $d = ($point_x - $points->[$i]->[X])**2;
# If the X distance of the candidate is > than the total distance of the
# best previous candidate, we know we don't want it
next if (defined $distance && $d > $distance);
# If the total distance of the candidate is > than the total distance of the
# best previous candidate, we know we don't want it
$d += ($point_y - $points->[$i]->[Y])**2;
next if (defined $distance && $d > $distance);
$nearest_point_index = $i;
$distance = $d;
last if $distance < epsilon;
}
return $nearest_point_index;
}