diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index 5a59828f6..cad94b491 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -187,7 +187,7 @@ sub _medial_axis_voronoi { # being longer than $width / 2 $polygon = $polygon->subdivide($width/2); - push @points, map $_->pp, @$polygon; + push @points, @{$polygon->pp}; } $voronoi = Math::Geometry::Voronoi->new(points => \@points); } @@ -200,10 +200,8 @@ sub _medial_axis_voronoi { # ignore lines going to infinite next if $edge->[1] == -1 || $edge->[2] == -1; - my ($a, $b); - $a = Slic3r::Point->new(@{$vertices->[$edge->[1]]}); - $b = Slic3r::Point->new(@{$vertices->[$edge->[2]]}); - next if !$self->encloses_point_quick($a) || !$self->encloses_point_quick($b); + next if !$self->encloses_point_quick(Slic3r::Point->new(@{$vertices->[$edge->[1]]})) + || !$self->encloses_point_quick(Slic3r::Point->new(@{$vertices->[$edge->[2]]})); push @skeleton_lines, [$edge->[1], $edge->[2]]; } @@ -244,7 +242,7 @@ sub _medial_axis_voronoi { # cleanup $polyline = Slic3r::Geometry::douglas_peucker($polyline, $width / 7); - if (Slic3r::Geometry::same_point($polyline->[0], $polyline->[-1])) { + if ($polyline->[0][X] == $polyline->[-1][X] && $polyline->[0][Y] == $polyline->[-1][Y]) { next if @$polyline == 2; push @result, Slic3r::Polygon->new(@$polyline[0..$#$polyline-1]); } else { diff --git a/lib/Slic3r/Geometry.pm b/lib/Slic3r/Geometry.pm index 1d6ad6ee4..c236b68ac 100644 --- a/lib/Slic3r/Geometry.pm +++ b/lib/Slic3r/Geometry.pm @@ -14,7 +14,7 @@ our @EXPORT_OK = qw( polygon_has_vertex can_connect_points deg2rad rad2deg rotate_points move_points clip_segment_polygon sum_vectors multiply_vector subtract_vectors dot perp polygon_points_visibility - line_intersection bounding_box bounding_box_intersect same_point + line_intersection bounding_box bounding_box_intersect angle3points three_points_aligned line_direction polyline_remove_parallel_continuous_edges polyline_remove_acute_vertices polygon_remove_acute_vertices polygon_remove_parallel_continuous_edges @@ -107,29 +107,11 @@ sub points_coincide { return 0; } -sub same_point { - my ($p1, $p2) = @_; - return $p1->[X] == $p2->[X] && $p1->[Y] == $p2->[Y]; -} - sub distance_between_points { my ($p1, $p2) = @_; return sqrt((($p1->[X] - $p2->[X])**2) + ($p1->[Y] - $p2->[Y])**2); } -sub point_line_distance { - my ($point, $line) = @_; - return distance_between_points($point, $line->[A]) - if same_point($line->[A], $line->[B]); - - my $n = ($line->[B][X] - $line->[A][X]) * ($line->[A][Y] - $point->[Y]) - - ($line->[A][X] - $point->[X]) * ($line->[B][Y] - $line->[A][Y]); - - my $d = sqrt((($line->[B][X] - $line->[A][X]) ** 2) + (($line->[B][Y] - $line->[A][Y]) ** 2)); - - return abs($n) / $d; -} - # this will check whether a point is in a polygon regardless of polygon orientation sub point_in_polygon { my ($point, $polygon) = @_; @@ -795,7 +777,7 @@ sub douglas_peucker { my $dmax = 0; my $index = 0; for my $i (1..$#$points) { - my $d = point_line_distance($points->[$i], [ $points->[0], $points->[-1] ]); + my $d = $points->[$i]->distance_to(Slic3r::Line->new($points->[0], $points->[-1])); if ($d > $dmax) { $index = $i; $dmax = $d; diff --git a/xs/src/Line.cpp b/xs/src/Line.cpp index 612116091..0e4698b7f 100644 --- a/xs/src/Line.cpp +++ b/xs/src/Line.cpp @@ -60,6 +60,12 @@ Line::coincides_with(const Line* line) const return this->a.coincides_with(&line->a) && this->b.coincides_with(&line->b); } +double +Line::distance_to(const Point* point) const +{ + return point->distance_to(this); +} + #ifdef SLIC3RXS void Line::from_SV(SV* line_sv) diff --git a/xs/src/Line.hpp b/xs/src/Line.hpp index 2545cc564..5962970ba 100644 --- a/xs/src/Line.hpp +++ b/xs/src/Line.hpp @@ -6,6 +6,8 @@ namespace Slic3r { +class Line; + class Line { public: @@ -21,6 +23,7 @@ class Line Point* midpoint() const; Point* point_at(double distance) const; bool coincides_with(const Line* line) const; + double distance_to(const Point* point) const; #ifdef SLIC3RXS void from_SV(SV* line_sv); diff --git a/xs/src/Point.cpp b/xs/src/Point.cpp index 777b533f0..28a468f77 100644 --- a/xs/src/Point.cpp +++ b/xs/src/Point.cpp @@ -1,4 +1,5 @@ #include "Point.hpp" +#include "Line.hpp" #include namespace Slic3r { @@ -72,6 +73,17 @@ Point::distance_to(const Point* point) const return sqrt(dx*dx + dy*dy); } +double +Point::distance_to(const Line* line) const +{ + if (line->a.coincides_with(&line->b)) return this->distance_to(&line->a); + + double n = (line->b.x - line->a.x) * (line->a.y - this->y) + - (line->a.x - this->x) * (line->b.y - line->a.y); + + return abs(n) / line->length(); +} + #ifdef SLIC3RXS SV* Point::to_SV_ref() { diff --git a/xs/src/Point.hpp b/xs/src/Point.hpp index 01d6112ee..5023ad663 100644 --- a/xs/src/Point.hpp +++ b/xs/src/Point.hpp @@ -7,6 +7,7 @@ namespace Slic3r { +class Line; class Point; typedef std::vector Points; @@ -23,6 +24,7 @@ class Point int nearest_point_index(const Points points) const; Point* nearest_point(Points points) const; double distance_to(const Point* point) const; + double distance_to(const Line* line) const; #ifdef SLIC3RXS void from_SV(SV* point_sv);