diff --git a/OpenNest.Core/Geometry/Shape.cs b/OpenNest.Core/Geometry/Shape.cs index 21463511..e4cf126a 100644 --- a/OpenNest.Core/Geometry/Shape.cs +++ b/OpenNest.Core/Geometry/Shape.cs @@ -264,10 +264,24 @@ namespace OpenNest.Geometry } /// - /// Converts the shape to a polygon. + /// Maximum chord error, in drawing units, when flattens arcs + /// and circles. Ten times tighter than the spacing/overlap checks' 0.001 because callers + /// use this polygon for area, and an inscribed polygon always reads low. /// - /// - public Polygon ToPolygon(int arcSegments = 1000) + public const double DefaultChordTolerance = 0.0001; + + /// + /// Converts the shape to a polygon, flattening arcs to within + /// . A fixed segment count per arc (formerly 1000) + /// made large arcs no more accurate and small ones needlessly dense: arc-heavy drawings + /// produced hundreds of thousands of vertices every time their area was computed. + /// + public Polygon ToPolygon() => ToPolygonWithTolerance(DefaultChordTolerance); + + /// + /// Converts the shape to a polygon with a fixed number of segments per arc and circle. + /// + public Polygon ToPolygon(int arcSegments) { var polygon = new Polygon(); diff --git a/OpenNest.Core/Geometry/SpacingOutline.cs b/OpenNest.Core/Geometry/SpacingOutline.cs index 8ee0545c..a89e812d 100644 --- a/OpenNest.Core/Geometry/SpacingOutline.cs +++ b/OpenNest.Core/Geometry/SpacingOutline.cs @@ -64,8 +64,8 @@ namespace OpenNest.Geometry public static SpacingOutline Build(ShapeProfile profile, Vector location, double inflateBy) { ArgumentNullException.ThrowIfNull(profile); - // Adaptive tolerance instead of Shape.ToPolygon()'s default (up to 1000 segments per - // arc): arc-heavy real parts otherwise produce thousands of vertices. + // Flatten by chord tolerance, not a fixed segment count: arc-heavy real parts + // otherwise produce thousands of vertices. var region = ClipperBridge.OffsetForValidation( profile, inflateBy > Tolerance.Epsilon ? inflateBy : 0,