diff --git a/lib/Slic3r/Layer/BridgeDetector.pm b/lib/Slic3r/Layer/BridgeDetector.pm index fb27bee56..c616909d4 100644 --- a/lib/Slic3r/Layer/BridgeDetector.pm +++ b/lib/Slic3r/Layer/BridgeDetector.pm @@ -247,7 +247,7 @@ sub unsupported_edges { # split into individual segments and filter out edges parallel to the bridging angle @$unsupported = map $_->as_polyline, - grep { abs($_->direction - $angle) < epsilon } + grep $_->parallel_to($angle), map @{$_->lines}, @$unsupported; diff --git a/xs/src/Line.cpp b/xs/src/Line.cpp index 5583eb1ca..8efa4442a 100644 --- a/xs/src/Line.cpp +++ b/xs/src/Line.cpp @@ -111,6 +111,17 @@ Line::direction() const : atan2; } +bool +Line::parallel_to(double angle) const { + double diff = abs(this->direction() - angle); + return (diff < EPSILON) || (abs(diff - PI) < EPSILON); +} + +bool +Line::parallel_to(const Line &line) const { + return this->parallel_to(line.direction()); +} + Vector Line::vector() const { diff --git a/xs/src/Line.hpp b/xs/src/Line.hpp index 9773338b7..e33c1970c 100644 --- a/xs/src/Line.hpp +++ b/xs/src/Line.hpp @@ -28,6 +28,8 @@ class Line Point point_at(double distance) const; bool coincides_with(const Line &line) const; double distance_to(const Point &point) const; + bool parallel_to(double angle) const; + bool parallel_to(const Line &line) const; double atan2_() const; double direction() const; Vector vector() const; diff --git a/xs/t/10_line.t b/xs/t/10_line.t index c44093b9d..dc1ad7dc7 100644 --- a/xs/t/10_line.t +++ b/xs/t/10_line.t @@ -4,7 +4,10 @@ use strict; use warnings; use Slic3r::XS; -use Test::More tests => 6; +use Test::More tests => 34; + +use constant PI => 4 * atan2(1, 1); +use constant EPSILON => 1E-4; my $points = [ [100, 100], @@ -37,4 +40,28 @@ isa_ok $line->[0], 'Slic3r::Point::Ref', 'line point is blessed'; ], 'translate'; } +foreach my $base_angle (0, PI/4, PI/2, PI) { + my $line = Slic3r::Line->new([0,0], [100,0]); + $line->rotate($base_angle, [0,0]); + ok $line->parallel_to_line($line->clone), 'line is parallel to self'; + ok $line->parallel_to($line->direction), 'line is parallel to its direction'; + ok $line->parallel_to($line->direction + PI), 'line is parallel to its direction + PI'; + ok $line->parallel_to($line->direction - PI), 'line is parallel to its direction - PI'; + { + my $line2 = $line->clone; + $line2->reverse; + ok $line->parallel_to_line($line2), 'line is parallel to its opposite'; + } + { + my $line2 = $line->clone; + $line2->rotate(+EPSILON/2, [0,0]); + ok $line->parallel_to_line($line2), 'line is parallel within epsilon'; + } + { + my $line2 = $line->clone; + $line2->rotate(-EPSILON/2, [0,0]); + ok $line->parallel_to_line($line2), 'line is parallel within epsilon'; + } +} + __END__ diff --git a/xs/xsp/Line.xsp b/xs/xsp/Line.xsp index a1927d57c..c18006980 100644 --- a/xs/xsp/Line.xsp +++ b/xs/xsp/Line.xsp @@ -25,6 +25,9 @@ double length(); double atan2_(); double direction(); + bool parallel_to(double angle); + bool parallel_to_line(Line* line) + %code{% RETVAL = THIS->parallel_to(*line); %}; Point* midpoint(); Clone point_at(double distance); Polyline* as_polyline()