test: add edge case tests for Collision; update CLAUDE.md

This commit is contained in:
2026-03-29 09:43:31 -04:00
parent b834813889
commit a7c2fcffe6
2 changed files with 26 additions and 1 deletions

View File

@@ -25,7 +25,7 @@ Domain model, geometry, and CNC primitives organized into namespaces:
- **Root** (`namespace OpenNest`): Domain model — `Nest``Plate[]``Part[]``Drawing``Program`. A `Nest` is the top-level container. Each `Plate` has a size, material, quadrant, spacing, and contains placed `Part` instances. Each `Part` references a `Drawing` (the template) and has its own location/rotation. A `Drawing` wraps a CNC `Program`. Also contains utilities: `PartGeometry`, `Align`, `Sequence`, `Timing`.
- **CNC** (`CNC/`, `namespace OpenNest.CNC`): `Program` holds a list of `ICode` instructions (G-code-like: `RapidMove`, `LinearMove`, `ArcMove`, `SubProgramCall`). Programs support absolute/incremental mode conversion, rotation, offset, bounding box calculation, and cloning.
- **Geometry** (`Geometry/`, `namespace OpenNest.Geometry`): Spatial primitives (`Vector`, `Box`, `Size`, `Spacing`, `BoundingBox`, `IBoundable`) and higher-level shapes (`Line`, `Arc`, `Circle`, `Polygon`, `Shape`) used for intersection detection, area calculation, and DXF conversion. Also contains `Intersect` (intersection algorithms), `ShapeBuilder` (entity chaining), `GeometryOptimizer` (line/arc merging), `SpatialQuery` (directional distance, ray casting, box queries), `ShapeProfile` (perimeter/area analysis), `NoFitPolygon`, `InnerFitPolygon`, `ConvexHull`, `ConvexDecomposition`, and `RotatingCalipers`.
- **Geometry** (`Geometry/`, `namespace OpenNest.Geometry`): Spatial primitives (`Vector`, `Box`, `Size`, `Spacing`, `BoundingBox`, `IBoundable`) and higher-level shapes (`Line`, `Arc`, `Circle`, `Polygon`, `Shape`) used for intersection detection, area calculation, and DXF conversion. Also contains `Intersect` (intersection algorithms), `ShapeBuilder` (entity chaining), `GeometryOptimizer` (line/arc merging), `SpatialQuery` (directional distance, ray casting, box queries), `ShapeProfile` (perimeter/area analysis), `NoFitPolygon`, `InnerFitPolygon`, `ConvexHull`, `ConvexDecomposition`, `RotatingCalipers`, and `Collision` (overlap detection with Sutherland-Hodgman polygon clipping and hole subtraction).
- **Converters** (`Converters/`, `namespace OpenNest.Converters`): Bridges between CNC and Geometry — `ConvertProgram` (CNC→Geometry), `ConvertGeometry` (Geometry→CNC), `ConvertMode` (absolute↔incremental).
- **Math** (`Math/`, `namespace OpenNest.Math`): `Angle` (radian/degree conversion), `Tolerance` (floating-point comparison), `Trigonometry`, `Generic` (swap utility), `EvenOdd`, `Rounding` (factor-based rounding). Note: `OpenNest.Math` shadows `System.Math` — use `System.Math` fully qualified where both are needed.
- **CNC/CuttingStrategy** (`CNC/CuttingStrategy/`, `namespace OpenNest.CNC`): `ContourCuttingStrategy` orchestrates cut ordering, lead-ins/lead-outs, and tabs. Includes `LeadIn`/`LeadOut` hierarchies (line, arc, clean-hole variants), `Tab` hierarchy (normal, machine, breaker), and `CuttingParameters`/`AssignmentParameters`/`SequenceParameters` configuration.

View File

@@ -179,6 +179,31 @@ public class CollisionTests
Assert.False(Collision.HasAnyOverlap(new List<Polygon> { a, b }));
}
[Fact]
public void Check_IdenticalSquares_FullOverlap()
{
var a = MakeSquare(0, 0, 1, 1);
var b = MakeSquare(0, 0, 1, 1);
var result = Collision.Check(a, b);
Assert.True(result.Overlaps);
Assert.True(result.OverlapArea > 0.99 && result.OverlapArea < 1.01);
}
[Fact]
public void HasAnyOverlap_SinglePolygon_ReturnsFalse()
{
var a = MakeSquare(0, 0, 1, 1);
Assert.False(Collision.HasAnyOverlap(new List<Polygon> { a }));
}
[Fact]
public void HasAnyOverlap_EmptyList_ReturnsFalse()
{
Assert.False(Collision.HasAnyOverlap(new List<Polygon>()));
}
private static Polygon MakeSquare(double left, double bottom, double right, double top)
{
var p = new Polygon();