Browse Source

Fix for undetected convex points. #3458

Alessandro Ranellucci 7 years ago
parent
commit
90de54f2fc
2 changed files with 33 additions and 21 deletions
  1. 11 1
      t/geometry.t
  2. 22 20
      xs/src/libslic3r/Polygon.cpp

+ 11 - 1
t/geometry.t

@@ -2,7 +2,7 @@ use Test::More;
 use strict;
 use warnings;
 
-plan tests => 42;
+plan tests => 44;
 
 BEGIN {
     use FindBin;
@@ -254,4 +254,14 @@ my $polygons = [
     is scalar(@$simplified), 3, 'triangle is never simplified to less than 3 points';
 }
 
+{
+    # Two concave vertices of this polygon have angle = PI*4/3, so this test fails
+    # if epsilon is not used.
+    my $polygon = Slic3r::Polygon->new(
+        [60246458,14802768],[64477191,12360001],[63727343,11060995],[64086449,10853608],[66393722,14850069],[66034704,15057334],[65284646,13758387],[61053864,16200839],[69200258,30310849],[62172547,42483120],[61137680,41850279],[67799985,30310848],[51399866,1905506],[38092663,1905506],[38092663,692699],[52100125,692699],
+    );
+    is scalar(@{$polygon->concave_points(PI*4/3)}), 6, 'expected number of concave points';
+    is scalar(@{$polygon->convex_points(PI*2/3)}), 10, 'expected number of convex points';
+}
+
 __END__

+ 22 - 20
xs/src/libslic3r/Polygon.cpp

@@ -248,23 +248,24 @@ Polygon::wkt() const
 Points
 Polygon::concave_points(double angle) const
 {
-    Points points;
-    angle = 2*PI - angle;
+    angle = 2*PI - angle + EPSILON;
+    const Points &pp = this->points;
+    Points concave;
     
     // check whether first point forms a concave angle
-    if (this->points.front().ccw_angle(this->points.back(), *(this->points.begin()+1)) <= angle)
-        points.push_back(this->points.front());
+    if (pp.front().ccw_angle(pp.back(), *(pp.begin()+1)) <= angle)
+        concave.push_back(pp.front());
     
     // check whether points 1..(n-1) form concave angles
-    for (Points::const_iterator p = this->points.begin()+1; p != this->points.end()-1; ++p) {
-        if (p->ccw_angle(*(p-1), *(p+1)) <= angle) points.push_back(*p);
-    }
+    for (Points::const_iterator p = pp.begin()+1; p != pp.end()-1; ++p)
+        if (p->ccw_angle(*(p-1), *(p+1)) <= angle)
+            concave.push_back(*p);
     
     // check whether last point forms a concave angle
-    if (this->points.back().ccw_angle(*(this->points.end()-2), this->points.front()) <= angle)
-        points.push_back(this->points.back());
+    if (pp.back().ccw_angle(*(pp.end()-2), pp.front()) <= angle)
+        concave.push_back(pp.back());
     
-    return points;
+    return concave;
 }
 
 // find all convex vertices (i.e. having an internal angle smaller than the supplied angle)
@@ -272,23 +273,24 @@ Polygon::concave_points(double angle) const
 Points
 Polygon::convex_points(double angle) const
 {
-    Points points;
-    angle = 2*PI - angle;
+    angle = 2*PI - angle - EPSILON;
+    const Points &pp = this->points;
+    Points convex;
     
     // check whether first point forms a convex angle
-    if (this->points.front().ccw_angle(this->points.back(), *(this->points.begin()+1)) >= angle)
-        points.push_back(this->points.front());
+    if (pp.front().ccw_angle(pp.back(), *(pp.begin()+1)) >= angle)
+        convex.push_back(pp.front());
     
     // check whether points 1..(n-1) form convex angles
-    for (Points::const_iterator p = this->points.begin()+1; p != this->points.end()-1; ++p) {
-        if (p->ccw_angle(*(p-1), *(p+1)) >= angle) points.push_back(*p);
-    }
+    for (Points::const_iterator p = pp.begin()+1; p != pp.end()-1; ++p)
+        if (p->ccw_angle(*(p-1), *(p+1)) >= angle)
+            convex.push_back(*p);
     
     // check whether last point forms a convex angle
-    if (this->points.back().ccw_angle(*(this->points.end()-2), this->points.front()) >= angle)
-        points.push_back(this->points.back());
+    if (pp.back().ccw_angle(*(pp.end()-2), pp.front()) >= angle)
+        convex.push_back(pp.back());
     
-    return points;
+    return convex;
 }
 
 }