From 3afe846570c365bb218b8ae6e4edc0f21d15515d Mon Sep 17 00:00:00 2001 From: Emmett Lalish Date: Sat, 8 Jun 2024 17:31:33 -0700 Subject: [PATCH] Fixed backward zebra polygon (#834) fixed two more bugs --- src/polygon/src/polygon.cpp | 19 ++++++++++--------- test/polygon_test.cpp | 12 +++++------- test/zebra.cpp | 2 +- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/polygon/src/polygon.cpp b/src/polygon/src/polygon.cpp index 7c3d8ed19..e122893bb 100644 --- a/src/polygon/src/polygon.cpp +++ b/src/polygon/src/polygon.cpp @@ -354,6 +354,13 @@ class EarClip { return left->InsideEdge(left->right, precision, true); } + // Subtly different from !IsConvex because IsConvex will return true for + // colinear non-folded verts, while IsReflex will always check until actual + // certainty is determined. + bool IsReflex(float precision) const { + return !left->InsideEdge(left->right, precision, true); + } + // This function is the core of finding a proper place to keyhole. It runs // on this Vert, which represents the edge from this to right. It returns // an iterator to the vert to connect to (either this or right) and a bool @@ -368,7 +375,8 @@ class EarClip { std::pair InterpY2X(glm::vec2 start, int onTop, float precision) const { const auto none = std::make_pair(left, false); - if (pos.y < start.y && right->pos.y >= start.y) { + if (pos.y < start.y && right->pos.y >= start.y && + (pos.x > start.x - precision || right->pos.x > start.x - precision)) { return std::make_pair(left->right, true); } else if (onTop != 0 && pos.x > start.x - precision && pos.y > start.y - precision && pos.y < start.y + precision && @@ -532,13 +540,6 @@ class EarClip { // triangulations of polygons with holes, due to vert duplication. triangles_.push_back( {ear->left->mesh_idx, ear->mesh_idx, ear->right->mesh_idx}); -#ifdef MANIFOLD_DEBUG - if (params.verbose) { - std::cout << "output tri: " << ear->mesh_idx << ", " - << ear->right->mesh_idx << ", " << ear->left->mesh_idx - << std::endl; - } -#endif } else { PRINT("Topological degenerate!"); } @@ -704,7 +705,7 @@ class EarClip { vert->pos.y * above > start->pos.y * above - precision_ && (inside > 0 || (inside == 0 && vert->pos.x < best->pos.x)) && vert->InsideEdge(edge, precision_, true) && - !vert->IsConvex(precision_)) { + vert->IsReflex(precision_)) { if (vert->pos.y > start->pos.y - precision_ && vert->pos.y < start->pos.y + precision_) { if (onTop > 0 && vert->left->pos.x < vert->pos.x && diff --git a/test/polygon_test.cpp b/test/polygon_test.cpp index f90454bc4..3fd4f6602 100644 --- a/test/polygon_test.cpp +++ b/test/polygon_test.cpp @@ -56,20 +56,18 @@ Polygons Duplicate(Polygons polys) { } void TestPoly(const Polygons &polys, int expectedNumTri, - float precision = -1.0f, bool onlyBasic = false) { + float precision = -1.0f) { PolygonParams().verbose = options.params.verbose; std::vector triangles; EXPECT_NO_THROW(triangles = Triangulate(polys, precision)); EXPECT_EQ(triangles.size(), expectedNumTri) << "Basic"; - if (!onlyBasic) { - EXPECT_NO_THROW(triangles = Triangulate(Turn180(polys), precision)); - EXPECT_EQ(triangles.size(), expectedNumTri) << "Turn 180"; + EXPECT_NO_THROW(triangles = Triangulate(Turn180(polys), precision)); + EXPECT_EQ(triangles.size(), expectedNumTri) << "Turn 180"; - EXPECT_NO_THROW(triangles = Triangulate(Duplicate(polys), precision)); - EXPECT_EQ(triangles.size(), 2 * expectedNumTri) << "Duplicate"; - } + EXPECT_NO_THROW(triangles = Triangulate(Duplicate(polys), precision)); + EXPECT_EQ(triangles.size(), 2 * expectedNumTri) << "Duplicate"; PolygonParams().verbose = false; } diff --git a/test/zebra.cpp b/test/zebra.cpp index 312af6c34..877c27702 100644 --- a/test/zebra.cpp +++ b/test/zebra.cpp @@ -62639,7 +62639,7 @@ TEST(Polygon, Zebra) { {5.59076977, 14.00315}, // {5.59097004, 14.00315}, // }); - TestPoly(polys, 62597, -1, true); + TestPoly(polys, 62597); } TEST(Polygon, Zebra1) {