Browse Source

Use a more robust parallelism detection

Alessandro Ranellucci 11 years ago
parent
commit
0a88492fdc
5 changed files with 45 additions and 2 deletions
  1. 1 1
      lib/Slic3r/Layer/BridgeDetector.pm
  2. 11 0
      xs/src/Line.cpp
  3. 2 0
      xs/src/Line.hpp
  4. 28 1
      xs/t/10_line.t
  5. 3 0
      xs/xsp/Line.xsp

+ 1 - 1
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;
     

+ 11 - 0
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
 {

+ 2 - 0
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;

+ 28 - 1
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__

+ 3 - 0
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> point_at(double distance);
     Polyline* as_polyline()