fix(geometry): harden the arc-preserving per-entity offset
GetOffsetPerimeterEntities/GetOffsetPartEntities feed directional-distance loops (FillLinear, Compactor, RotationSlideStrategy) that handle arcs natively. Switching them to Clipper line output (plan option B) made OpenNest.Tests run 48s -> 8m19s, Fill tests ~3x slower, and broke 20 exact-fit tests through tessellation and conservative padding, so they keep the per-entity offset (option A), hardened: - Arc, Circle and Line offsets are now side-symmetric. Right on a CCW arc shrank instead of growing, Right on a CW circle grew, and Right on a line offset to the left and reversed it. Only Left was used on hot paths, so this was latent (SimplifierViewer drew both tolerance bands on one side). - Shape.OffsetEntity closes every gap between consecutive offset pieces: convex non-tangent line/arc corners get a round join about the original corner, lines across a collapsed fillet are mitered, and any other gap (concave arc corner, collapsed entity) is bridged with a line. Before, only line-line corners were joined, so a vertex could slip through. - Zero-area spikes are left in place and documented: they lie inside the offset envelope, which is harmless for directional distance. - OffsetOutward/OffsetInward become internal; PartGeometry is their only caller. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -273,7 +273,10 @@ namespace OpenNest.Geometry
|
||||
|
||||
public override Entity OffsetEntity(double distance, OffsetSide side)
|
||||
{
|
||||
if (side == OffsetSide.Left && Rotation == RotationType.CCW)
|
||||
// The center lies to the left of a CCW circle and to the right of a CW one.
|
||||
var shrinks = (side == OffsetSide.Left) == (Rotation == RotationType.CCW);
|
||||
|
||||
if (shrinks)
|
||||
{
|
||||
return Radius <= distance
|
||||
? null
|
||||
@@ -281,7 +284,7 @@ namespace OpenNest.Geometry
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Circle(center, Radius + distance) { Layer = Layer };
|
||||
return new Circle(center, Radius + distance) { Layer = Layer, Rotation = Rotation };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user