diff --git a/src/geometry/arc.test.ts b/src/geometry/arc.test.ts index d5adebe..260151e 100644 --- a/src/geometry/arc.test.ts +++ b/src/geometry/arc.test.ts @@ -32,4 +32,9 @@ describe('flattenArc', () => { const fine = flattenArc([10, 0], [0, 10], [0, 0], false, 0.01); expect(fine.length).toBeGreaterThan(coarse.length); }); + + it('returns a straight segment for a degenerate zero-radius arc', () => { + const pts = flattenArc([5, 5], [5, 5], [5, 5], false, 0.1); + expect(pts).toEqual([[5, 5], [5, 5]]); + }); }); diff --git a/src/geometry/arc.ts b/src/geometry/arc.ts index 326eb15..4b55238 100644 --- a/src/geometry/arc.ts +++ b/src/geometry/arc.ts @@ -16,6 +16,10 @@ export function flattenArc( clockwise: boolean, tolerance = 0.2, ): Vec2[] { + // Degenerate (zero-radius) arc: nothing to sweep, return a straight segment. + const r0 = Math.hypot(start[0] - center[0], start[1] - center[1]); + if (r0 < 1e-9) return [[start[0], start[1]], [end[0], end[1]]]; + const radius = Math.hypot(start[0] - center[0], start[1] - center[1]); const startAngle = Math.atan2(start[1] - center[1], start[0] - center[0]); const endAngle = Math.atan2(end[1] - center[1], end[0] - center[0]); @@ -27,7 +31,7 @@ export function flattenArc( while (sweep <= 0) sweep += 2 * Math.PI; // sweep in (0, 2π] } - const maxStep = radius > tolerance ? 2 * Math.acos(1 - tolerance / radius) : Math.PI / 8; + const maxStep = radius > tolerance ? 2 * Math.acos(1 - tolerance / radius) : Math.PI / 8; // fallback step for tiny radii const steps = Math.max(1, Math.ceil(Math.abs(sweep) / maxStep)); const pts: Vec2[] = [];