From a8943eb58528054496bfe5cd121aaa97cbb1cc4a Mon Sep 17 00:00:00 2001 From: andywiecko Date: Fri, 22 Sep 2023 18:03:26 +0200 Subject: [PATCH] fix: sloan corner cases This commit resolves a bug related to the Sloan algorithm. Prior to this fix, constraints tended to become stuck in "simple" cases. Additional test cases were added to address this issue. --- Runtime/Triangulator.cs | 36 +++++++-------- Tests/TriangulatorEditorTests.cs | 79 ++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 20 deletions(-) diff --git a/Runtime/Triangulator.cs b/Runtime/Triangulator.cs index aab5ad8..0cce396 100644 --- a/Runtime/Triangulator.cs +++ b/Runtime/Triangulator.cs @@ -1478,31 +1478,27 @@ private void TryApplyConstraint(int i) var q1 = triangles[t1].UnsafeOtherPoint(e); var swapped = new Edge(q0, q1); - if (!intersections.IsEmpty()) + var (e0, e1) = e; + var (p0, p1, p2, p3) = (outputPositions[e0], outputPositions[q0], outputPositions[e1], outputPositions[q1]); + if (!IsConvexQuadrilateral(p0, p1, p2, p3)) { - if (!c.ContainsCommonPointWith(swapped) && EdgeEdgeIntersection(c, swapped)) - { - intersections.Enqueue(eId); - continue; - } - - var (e0, e1) = e; - var (p0, p1, p2, p3) = (outputPositions[e0], outputPositions[q0], outputPositions[e1], outputPositions[q1]); - if (!IsConvexQuadrilateral(p0, p1, p2, p3)) - { - intersections.Enqueue(eId); - continue; - } - - var id = internalConstraints.BinarySearch(swapped); - if (id >= 0) - { - satisfied[id] = true; - } + intersections.Enqueue(eId); + continue; } UnsafeSwapEdge(e); edges[eId] = swapped; + + if (!c.ContainsCommonPointWith(swapped) && EdgeEdgeIntersection(c, swapped)) + { + intersections.Enqueue(eId); + } + + var id = internalConstraints.BinarySearch(swapped); + if (id >= 0) + { + satisfied[id] = true; + } } satisfied[i] = true; diff --git a/Tests/TriangulatorEditorTests.cs b/Tests/TriangulatorEditorTests.cs index 488699c..f787dec 100644 --- a/Tests/TriangulatorEditorTests.cs +++ b/Tests/TriangulatorEditorTests.cs @@ -283,6 +283,81 @@ public void DelaunayTriangulationWithRefinementTest() (9, 8, 3), } }, + // 4 5 6 7 + // * * * ,* + // ..; + // ..; + // ..; + // ; + // * * * * + // 0 1 2 3 + new(new[] + { + math.float2(0, 0), + math.float2(1, 0), + math.float2(2, 0), + math.float2(3, 0), + math.float2(0, 3), + math.float2(1, 3), + math.float2(2, 3), + math.float2(3, 3), + }, + new[] { 0, 7 } + ) + { + TestName = "Test case 4", + ExpectedResult = new[] + { + (0, 5, 6), + (0, 6, 7), + (5, 0, 4), + (7, 1, 0), + (7, 2, 1), + (7, 3, 2), + } + }, + // 8 9 10 11 + // * * * * + // ..; + // 5 * ..; * 7 + // ..; + // 4 * ..; * 6 + // ..; + // * * * * + // 0 1 2 3 + new(new[] + { + math.float2(0, 0), + math.float2(1, 0), + math.float2(2, 0), + math.float2(3, 0), + math.float2(0, 1), + math.float2(0, 2), + math.float2(3, 1), + math.float2(3, 2), + math.float2(0, 3), + math.float2(1, 3), + math.float2(2, 3), + math.float2(3, 3), + }, + new[]{ 0, 11 } + ) + { + TestName = "Test case 5", + ExpectedResult = new[] + { + (0, 4, 10), + (0, 10, 11), + (6, 3, 2), + (7, 1, 0), + (7, 2, 1), + (7, 6, 2), + (9, 4, 5), + (9, 5, 8), + (9, 10, 4), + (11, 7, 0) + } + } }; [Test, TestCaseSource(nameof(edgeConstraintsTestData))] @@ -1280,6 +1355,9 @@ public void SloanMaxItersTest() // Input for this test is grabbed from issue #30 from @mduvergey user. // https://github.com/andywiecko/BurstTriangulator/issues/30 // This test tests editor hanging problem reported in issue #30 and #31. + // + // UPDATE: Thanks to the recent fix, this input will no longer cause the algorithm to hang, + // unless "max iters" are intentionally reduced. float2[] points = { new float2(14225.59f, -2335.27f), new float2(13380.24f, -2344.72f), new float2(13197.35f, -2119.65f), @@ -1338,6 +1416,7 @@ public void SloanMaxItersTest() RefineMesh = false, ConstrainEdges = true, RestoreBoundary = true, + SloanMaxIters = 10, }, Input = {