Skip to content

Commit

Permalink
fix: sloan corner cases
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
andywiecko committed Sep 23, 2023
1 parent 243177e commit a8943eb
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 20 deletions.
36 changes: 16 additions & 20 deletions Runtime/Triangulator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
79 changes: 79 additions & 0 deletions Tests/TriangulatorEditorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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))]
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -1338,6 +1416,7 @@ public void SloanMaxItersTest()
RefineMesh = false,
ConstrainEdges = true,
RestoreBoundary = true,
SloanMaxIters = 10,
},
Input =
{
Expand Down

0 comments on commit a8943eb

Please sign in to comment.