perf(core): skip unused crossing points in overlap-only checks
Collision.HasOverlap only needs the verdict, but it went through Check, which also collected crossing points. Triangulation, clipping and hole subtraction now live in one private OverlapRegions method shared by Check and HasOverlap, so verdict arithmetic stays single-sourced; Check output is unchanged. Tests: a frozen copy of the previous Collision is the oracle. 50,000 seeded HasOverlap verdicts and 2,400 bitwise Check results match it, plus containment, contact, hole and input-immutability cases. A Debug-only PerfCounters.CrossingPointScans counter proves HasOverlap no longer scans. Malformed polygons with null outer vertices still throw when the bounding boxes overlap (now ArgumentNullException from triangulation rather than NullReferenceException from ToLines). Measured (Release, same harness in both trees): about 44% less time per overlap-only polygon check, allocations 10.0 -> 7.9 MB per 155-pair sweep. The 169-part serialized corpus layout is byte-identical.
This commit is contained in:
@@ -16,6 +16,7 @@ namespace OpenNest
|
||||
private static long partBoundaryPreparations;
|
||||
private static long partBoundsUpdates;
|
||||
private static long featureBitmaskCells;
|
||||
private static long crossingPointScans;
|
||||
|
||||
public static long FindBestFits => Interlocked.Read(ref findBestFits);
|
||||
public static long OffsetPerimeterEntities => Interlocked.Read(ref offsetPerimeterEntities);
|
||||
@@ -24,6 +25,7 @@ namespace OpenNest
|
||||
public static long PartBoundaryPreparations => Interlocked.Read(ref partBoundaryPreparations);
|
||||
public static long PartBoundsUpdates => Interlocked.Read(ref partBoundsUpdates);
|
||||
public static long FeatureBitmaskCells => Interlocked.Read(ref featureBitmaskCells);
|
||||
public static long CrossingPointScans => Interlocked.Read(ref crossingPointScans);
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public static void CountFindBestFits() => Interlocked.Increment(ref findBestFits);
|
||||
@@ -47,6 +49,9 @@ namespace OpenNest
|
||||
[Conditional("DEBUG")]
|
||||
public static void CountFeatureBitmaskCell() => Interlocked.Increment(ref featureBitmaskCells);
|
||||
|
||||
[Conditional("DEBUG")]
|
||||
public static void CountCrossingPointScan() => Interlocked.Increment(ref crossingPointScans);
|
||||
|
||||
public static void Reset()
|
||||
{
|
||||
Interlocked.Exchange(ref findBestFits, 0);
|
||||
@@ -56,6 +61,7 @@ namespace OpenNest
|
||||
Interlocked.Exchange(ref partBoundaryPreparations, 0);
|
||||
Interlocked.Exchange(ref partBoundsUpdates, 0);
|
||||
Interlocked.Exchange(ref featureBitmaskCells, 0);
|
||||
Interlocked.Exchange(ref crossingPointScans, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user