Editor's Path Properties section has no 'spike' / 'sharp corner' detection — user creating a path with a sharp angle (e.g., a 10° corner) gets no warning, embroidery on sharp corners is hard #335

Closed
opened 2026-10-04 03:53:55 +00:00 by Mark · 1 comment
Owner

Finding

grep -rn 'sharpCorner\|spikeDetect' src/components/editor/ returns 0. The editor has no sharp corner detection.

A user drawing a path:

  • Creates a sharp 10° corner at a node
  • Doesn't realize this is problematic for embroidery (sharp corners are hard to stitch cleanly)
  • Exports and gets poor results

The fix is to detect sharp corners and warn the user (or visually highlight the corner in red).

Where

  • Path Properties: src/components/editor/EditorRightPanel.tsx
  • canvasRenderer: src/components/editor/canvasRenderer.ts (where the corner is drawn)
  • No detection: grep -rn 'sharpCorner' src/components/editor/ returns 0

Suggested fix shape

  1. Algorithm: in the canvasRenderer, when drawing nodes, check the angle of the corner:
function angleAtNode(nodes: PathNode[], index: number): number {
  const prev = nodes[index - 1];
  const cur = nodes[index];
  const next = nodes[index + 1];
  if (!prev || !next) return 180;
  const v1 = { x: cur.x - prev.x, y: cur.y - prev.y };
  const v2 = { x: next.x - cur.x, y: next.y - cur.y };
  return Math.acos(dot(v1, v2) / (length(v1) * length(v2))) * (180 / Math.PI);
}
  1. Visual highlight: if the angle is < 30°, draw the node in red:
if (angle < 30) {
  ctx.fillStyle = '#DC2626';
} else {
  ctx.fillStyle = isSelected ? '#E6A948' : '#1A1A1A';
}
  1. Path Properties section: a small "X sharp corners detected" warning with a "List" button to see them.

  2. Auto-fix: a "Smooth sharp corners" button that applies a 30° minimum angle.

Severity

Low. The user can spot sharp corners visually. Power users with production embroidery notice.

Discovered by

Gap analysis (2026-10-02) of editor validation.

  • #260 (open) — Hoop size mismatch. Same validation family.
  • #326 (open) — Node count goal. Same validation family.
  • Figma/Illustrator have "Find sharp corners." The editor's gap is the parallel.
## Finding `grep -rn 'sharpCorner\|spikeDetect' src/components/editor/` returns 0. The editor has no sharp corner detection. A user drawing a path: - Creates a sharp 10° corner at a node - Doesn't realize this is problematic for embroidery (sharp corners are hard to stitch cleanly) - Exports and gets poor results The fix is to detect sharp corners and warn the user (or visually highlight the corner in red). ## Where - Path Properties: `src/components/editor/EditorRightPanel.tsx` - canvasRenderer: `src/components/editor/canvasRenderer.ts` (where the corner is drawn) - No detection: `grep -rn 'sharpCorner' src/components/editor/` returns 0 ## Suggested fix shape 1. **Algorithm**: in the canvasRenderer, when drawing nodes, check the angle of the corner: ```ts function angleAtNode(nodes: PathNode[], index: number): number { const prev = nodes[index - 1]; const cur = nodes[index]; const next = nodes[index + 1]; if (!prev || !next) return 180; const v1 = { x: cur.x - prev.x, y: cur.y - prev.y }; const v2 = { x: next.x - cur.x, y: next.y - cur.y }; return Math.acos(dot(v1, v2) / (length(v1) * length(v2))) * (180 / Math.PI); } ``` 2. **Visual highlight**: if the angle is < 30°, draw the node in red: ```ts if (angle < 30) { ctx.fillStyle = '#DC2626'; } else { ctx.fillStyle = isSelected ? '#E6A948' : '#1A1A1A'; } ``` 3. **Path Properties section**: a small "X sharp corners detected" warning with a "List" button to see them. 4. **Auto-fix**: a "Smooth sharp corners" button that applies a 30° minimum angle. ## Severity Low. The user can spot sharp corners visually. Power users with production embroidery notice. ## Discovered by Gap analysis (2026-10-02) of editor validation. ## Related - #260 (open) — Hoop size mismatch. Same validation family. - #326 (open) — Node count goal. Same validation family. - Figma/Illustrator have "Find sharp corners." The editor's gap is the parallel.
Author
Owner

Shipped in 37f5f61:

  • Canvas: interior nodes with angle < 30° now paint red via snapSettings.showSharpCornerWarning (default ON per constants.ts).
  • Right panel (Path Properties): new Sharp Corner Detection section with a one-line warning (X sharp corners detected (below 30°)) and a Smooth sharp corners (30°) button. The button fans out across every selected path in one setPaths + pushHistory dispatch.
  • Snap Settings: Show Sharp Corner Warning toggle gates the canvas visual without affecting the right-panel warning + button.
  • Geometry helpers (geometry.ts): angleAtNode, findSharpCorners, smoothSharpCorners. Smoothing moves the offending anchor onto the chord midpoint of prev/next — preserves node ids and bezier handles, no-op on clean paths. Closed paths cover wraparound corners.

27 new tests: 19 in geometry.test.ts pin the math + smoothing, 8 in issue-335.test.tsx pin the panel contract (rendering, hide-on-omit, count copy, button disabled on clean path, toggle in Snap Settings). All tests pass; build + lint clean.

Caveat: the bulk smoothing pass currently writes a single history entry per selected path's nodes array. Multi-path selections still produce one setPaths + pushHistory, matching the existing simplify / jitter / offset pattern.

Shipped in 37f5f61: - **Canvas**: interior nodes with angle < 30° now paint red via `snapSettings.showSharpCornerWarning` (default ON per `constants.ts`). - **Right panel (Path Properties)**: new Sharp Corner Detection section with a one-line warning (`X sharp corners detected (below 30°)`) and a `Smooth sharp corners (30°)` button. The button fans out across every selected path in one `setPaths + pushHistory` dispatch. - **Snap Settings**: `Show Sharp Corner Warning` toggle gates the canvas visual without affecting the right-panel warning + button. - **Geometry helpers** (`geometry.ts`): `angleAtNode`, `findSharpCorners`, `smoothSharpCorners`. Smoothing moves the offending anchor onto the chord midpoint of prev/next — preserves node ids and bezier handles, no-op on clean paths. Closed paths cover wraparound corners. 27 new tests: 19 in `geometry.test.ts` pin the math + smoothing, 8 in `issue-335.test.tsx` pin the panel contract (rendering, hide-on-omit, count copy, button disabled on clean path, toggle in Snap Settings). All tests pass; build + lint clean. Caveat: the bulk smoothing pass currently writes a single history entry per selected path's nodes array. Multi-path selections still produce one setPaths + pushHistory, matching the existing simplify / jitter / offset pattern.
Mark closed this issue 2026-10-05 04:42:42 +00:00
Sign in to join this conversation.
No description provided.