fix: use NoFitPolygon.Compute with hull inputs instead of direct ConvexMinkowskiSum
Calling ConvexMinkowskiSum directly with manual reflection produced wrong winding/reference-point handling, causing all pairs to overlap. Route through Compute which handles reflection correctly. Hull inputs keep it fast — few triangles means trivial Clipper union. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,23 +32,17 @@ namespace OpenNest.Engine.BestFit
|
|||||||
if (stationaryResult.Polygon == null)
|
if (stationaryResult.Polygon == null)
|
||||||
return candidates;
|
return candidates;
|
||||||
|
|
||||||
// Use convex hulls for NFP computation — avoids expensive
|
// Use convex hulls for NFP — avoids expensive triangulation of
|
||||||
// triangulation + Clipper2 union for concave parts.
|
// concave parts. Hull inputs produce few triangles, so the
|
||||||
// Convex-convex Minkowski sum is O(n+m) with no boolean ops.
|
// Minkowski sum + Clipper union inside Compute stays fast.
|
||||||
var stationaryPoly = ConvexHull.Compute(stationaryResult.Polygon.Vertices);
|
var stationaryPoly = ConvexHull.Compute(stationaryResult.Polygon.Vertices);
|
||||||
|
|
||||||
// Orbiting polygon: same shape rotated to Part2's angle, then hulled.
|
// Orbiting polygon: same shape rotated to Part2's angle, then hulled.
|
||||||
var rotated = PolygonHelper.RotatePolygon(stationaryResult.Polygon, _part2Rotation);
|
var rotated = PolygonHelper.RotatePolygon(stationaryResult.Polygon, _part2Rotation);
|
||||||
var orbitingPoly = ConvexHull.Compute(rotated.Vertices);
|
var orbitingPoly = ConvexHull.Compute(rotated.Vertices);
|
||||||
|
|
||||||
// Compute NFP directly via convex Minkowski sum — O(n+m), no Clipper union.
|
// Let Compute handle reflection, winding, and Minkowski sum correctly.
|
||||||
// NFP(A, B) = MinkowskiSum(A, -B) for convex polygons.
|
var nfp = NoFitPolygon.Compute(stationaryPoly, orbitingPoly);
|
||||||
var reflected = new Polygon();
|
|
||||||
foreach (var v in orbitingPoly.Vertices)
|
|
||||||
reflected.Vertices.Add(new Vector(-v.X, -v.Y));
|
|
||||||
reflected.Vertices.Reverse(); // maintain CCW winding
|
|
||||||
|
|
||||||
var nfp = NoFitPolygon.ConvexMinkowskiSum(stationaryPoly, reflected);
|
|
||||||
|
|
||||||
if (nfp == null || nfp.Vertices.Count < 3)
|
if (nfp == null || nfp.Vertices.Count < 3)
|
||||||
return candidates;
|
return candidates;
|
||||||
|
|||||||
Reference in New Issue
Block a user