fix: guard flattenArc against zero-radius (degenerate) arcs
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7ddaee1454
commit
e475626497
2 changed files with 10 additions and 1 deletions
|
|
@ -32,4 +32,9 @@ describe('flattenArc', () => {
|
||||||
const fine = flattenArc([10, 0], [0, 10], [0, 0], false, 0.01);
|
const fine = flattenArc([10, 0], [0, 10], [0, 0], false, 0.01);
|
||||||
expect(fine.length).toBeGreaterThan(coarse.length);
|
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]]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,10 @@ export function flattenArc(
|
||||||
clockwise: boolean,
|
clockwise: boolean,
|
||||||
tolerance = 0.2,
|
tolerance = 0.2,
|
||||||
): Vec2[] {
|
): 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 radius = Math.hypot(start[0] - center[0], start[1] - center[1]);
|
||||||
const startAngle = Math.atan2(start[1] - center[1], start[0] - center[0]);
|
const startAngle = Math.atan2(start[1] - center[1], start[0] - center[0]);
|
||||||
const endAngle = Math.atan2(end[1] - center[1], end[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π]
|
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 steps = Math.max(1, Math.ceil(Math.abs(sweep) / maxStep));
|
||||||
|
|
||||||
const pts: Vec2[] = [];
|
const pts: Vec2[] = [];
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue