perf: replace O(p²) startOffset loop with O(p) pass in FindPatternCopyDistance

max(aUpper_i - bLower_j) across all pairs simplifies to
max(aUpper) - min(bLower), computed in a single pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 23:10:44 -04:00
parent 53759c5877
commit 94850795cf

View File

@@ -102,25 +102,23 @@ namespace OpenNest
// Compute a starting offset large enough that every part-pair in
// patternB has its offset geometry beyond patternA's offset geometry.
var startOffset = bboxDim;
// max(aUpper_i - bLower_j) = max(aUpper) - min(bLower).
var maxUpper = double.MinValue;
var minLower = double.MaxValue;
for (var i = 0; i < patternA.Parts.Count; i++)
{
var aUpper = direction == NestDirection.Horizontal
? patternA.Parts[i].BoundingBox.Right : patternA.Parts[i].BoundingBox.Top;
var bb = patternA.Parts[i].BoundingBox;
var upper = direction == NestDirection.Horizontal ? bb.Right : bb.Top;
var lower = direction == NestDirection.Horizontal ? bb.Left : bb.Bottom;
for (var j = 0; j < patternA.Parts.Count; j++)
{
var bLower = direction == NestDirection.Horizontal
? patternA.Parts[j].BoundingBox.Left : patternA.Parts[j].BoundingBox.Bottom;
var required = aUpper - bLower + PartSpacing + Tolerance.Epsilon;
if (required > startOffset)
startOffset = required;
}
if (upper > maxUpper) maxUpper = upper;
if (lower < minLower) minLower = lower;
}
var startOffset = System.Math.Max(bboxDim,
maxUpper - minLower + PartSpacing + Tolerance.Epsilon);
var offset = MakeOffset(direction, startOffset);
// Pre-compute stationary lines for patternA parts.