refactor: extract FindCrossing and SplitAtCrossing from RemoveSelfIntersections

Break deeply nested loop structure into focused helper methods,
reducing max nesting from 5 levels to 2. Uses GetRange/AddRange
for cleaner loop building.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 10:20:11 -04:00
parent 90b26babc6
commit bc3f1543ee
+29 -38
View File
@@ -483,63 +483,54 @@ namespace OpenNest.Geometry
if (!IsClosed() || Vertices.Count < 5) if (!IsClosed() || Vertices.Count < 5)
return; return;
bool found = true; while (FindCrossing(out var edgeI, out var edgeJ, out var pt))
while (found)
{ {
found = false; Vertices = SplitAtCrossing(edgeI, edgeJ, pt);
int n = Vertices.Count - 1; // exclude closing vertex }
}
for (int i = 0; i < n && !found; i++) private bool FindCrossing(out int edgeI, out int edgeJ, out Vector pt)
{ {
var a1 = Vertices[i]; var n = Vertices.Count - 1;
var a2 = Vertices[i + 1];
for (int j = i + 2; j < n && !found; j++) for (var i = 0; i < n; i++)
{
for (var j = i + 2; j < n; j++)
{ {
// Skip edges that share a vertex (first and last edge)
if (i == 0 && j == n - 1) if (i == 0 && j == n - 1)
continue; continue;
var b1 = Vertices[j]; if (SegmentsIntersect(Vertices[i], Vertices[i + 1], Vertices[j], Vertices[j + 1], out pt))
var b2 = Vertices[j + 1];
Vector pt;
if (SegmentsIntersect(a1, a2, b1, b2, out pt))
{ {
// Two loops formed by the crossing: edgeI = i;
// Loop A: vertices[0..i], pt, vertices[j+1..n-1], close edgeJ = j;
// Loop B: pt, vertices[i+1..j], close return true;
var loopA = new List<Vector>(); }
}
}
for (int k = 0; k <= i; k++) edgeI = edgeJ = -1;
loopA.Add(Vertices[k]); pt = Vector.Zero;
return false;
}
private List<Vector> SplitAtCrossing(int edgeI, int edgeJ, Vector pt)
{
var n = Vertices.Count - 1;
var loopA = Vertices.GetRange(0, edgeI + 1);
loopA.Add(pt); loopA.Add(pt);
loopA.AddRange(Vertices.GetRange(edgeJ + 1, n - edgeJ - 1));
for (int k = j + 1; k < n; k++)
loopA.Add(Vertices[k]);
loopA.Add(loopA[0]); loopA.Add(loopA[0]);
var loopB = new List<Vector>(); var loopB = new List<Vector> { pt };
loopB.Add(pt); loopB.AddRange(Vertices.GetRange(edgeI + 1, edgeJ - edgeI));
for (int k = i + 1; k <= j; k++)
loopB.Add(Vertices[k]);
loopB.Add(pt); loopB.Add(pt);
var areaA = System.Math.Abs(CalculateArea(loopA)); var areaA = System.Math.Abs(CalculateArea(loopA));
var areaB = System.Math.Abs(CalculateArea(loopB)); var areaB = System.Math.Abs(CalculateArea(loopB));
Vertices = areaA >= areaB ? loopA : loopB; return areaA >= areaB ? loopA : loopB;
found = true;
}
}
}
}
} }
private static bool SegmentsIntersect(Vector a1, Vector a2, Vector b1, Vector b2, out Vector pt) private static bool SegmentsIntersect(Vector a1, Vector a2, Vector b1, Vector b2, out Vector pt)