Editor's Path Properties has a 'Path length' display but no 'perimeter' or 'area' — user wanting to know how big the path is (in mm²) has to mentally integrate the path's nodes #355

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

Finding

grep -rn 'pathArea\|pathPerimeter' src/components/editor/EditorRightPanel.tsx returns 0. The right panel shows the path's length but not its area or perimeter.

A user with a closed path:

  • Wants to know the enclosed area in mm²
  • For fabric coverage estimates
  • For thread usage estimates
  • The "length" is the perimeter, not the area

The fix is to add area and perimeter displays.

Where

  • Path Properties: src/components/editor/EditorRightPanel.tsx
  • No area: grep -rn 'pathArea' src/components/editor/ returns 0
  • The geometry: src/components/editor/geometry.ts (where the algorithm lives)

Suggested fix shape

  1. Algorithm: shoelace formula for the area of a polygon:
function polygonArea(nodes: PathNode[]): number {
  if (nodes.length < 3) return 0;
  let area = 0;
  for (let i = 0; i < nodes.length; i++) {
    const j = (i + 1) % nodes.length;
    area += nodes[i].x * nodes[j].y;
    area -= nodes[j].x * nodes[i].y;
  }
  return Math.abs(area / 2);
}
  1. UI: in the Path Properties section, add "Area" and "Perimeter" displays:
<div className="text-[11px]">
  Path length: {pathLength.toFixed(2)} mm
</div>
{isClosed && (
  <div className="text-[11px]">
    Enclosed area: {polygonArea(nodes).toFixed(2)} mm²
  </div>
)}
  1. Use cases:
  • Fabric coverage estimates
  • Thread usage estimates
  • Comparing path sizes

Severity

Low. The user can compute. Power users with production workflows notice.

Discovered by

Gap analysis (2026-10-02) of editor path properties.

  • #261 (open) — Path area, thread usage, stitch time. The bulk summary; this is the per-path.
  • The geometry module is where the algorithm lives.
  • Figma shows area in the right panel. Standard.
## Finding `grep -rn 'pathArea\|pathPerimeter' src/components/editor/EditorRightPanel.tsx` returns 0. The right panel shows the path's length but not its area or perimeter. A user with a closed path: - Wants to know the enclosed area in mm² - For fabric coverage estimates - For thread usage estimates - The "length" is the perimeter, not the area The fix is to add area and perimeter displays. ## Where - Path Properties: `src/components/editor/EditorRightPanel.tsx` - No area: `grep -rn 'pathArea' src/components/editor/` returns 0 - The geometry: `src/components/editor/geometry.ts` (where the algorithm lives) ## Suggested fix shape 1. **Algorithm**: shoelace formula for the area of a polygon: ```ts function polygonArea(nodes: PathNode[]): number { if (nodes.length < 3) return 0; let area = 0; for (let i = 0; i < nodes.length; i++) { const j = (i + 1) % nodes.length; area += nodes[i].x * nodes[j].y; area -= nodes[j].x * nodes[i].y; } return Math.abs(area / 2); } ``` 2. **UI**: in the Path Properties section, add "Area" and "Perimeter" displays: ```tsx <div className="text-[11px]"> Path length: {pathLength.toFixed(2)} mm </div> {isClosed && ( <div className="text-[11px]"> Enclosed area: {polygonArea(nodes).toFixed(2)} mm² </div> )} ``` 3. **Use cases**: - Fabric coverage estimates - Thread usage estimates - Comparing path sizes ## Severity Low. The user can compute. Power users with production workflows notice. ## Discovered by Gap analysis (2026-10-02) of editor path properties. ## Related - #261 (open) — Path area, thread usage, stitch time. The bulk summary; this is the per-path. - The geometry module is where the algorithm lives. - Figma shows area in the right panel. Standard.
Author
Owner

Closed by fix(#355) at 44f4b8e (push 668f1d8..44f4b8e). The right panel's Path Statistics subsection (already added in #261 with Path area / Thread usage / Stitch time / Covers fabric) now includes a Perimeter row that exposes the closed-boundary length including the implicit closing edge from the last node back to the first.

Why the headline gap closed:

  • The existing Path Length row sums N-1 segment distances and silently omits the closing segment for closed paths, so a closed 4-node 10mm-side square reads as "30 mm" instead of the actual "40 mm" perimeter. The user has a clear "how long is the boundary?" row now.
  • perimeterMm(nodes, closed) helper added next to polygonAreaMm2 (shoelace area, #261) and estimatePathLength (Path Length math). Same one-decimal precision as Path Length, 0 for degenerate node counts.
  • Gated on selectedPath.closed so open paths render only Path Length — adding Perimeter for an open polyline would just duplicate the value.
  • Tooltip on the value span explains the closing-edge inclusion explicitly.

Path Length row is unchanged — the thread/stitch count math downstream of it (#261) already runs against the open-polyline convention, so flipping Path Length to include the closing segment would silently re-title stitch and thread estimates under them.

6 new tests at src/pages/issue-355.test.tsx pin:

  • row renders for closed paths
  • value includes the implicit closing edge (the 10mm delta the issue calls out, 30mm → 40mm for a closed 4-node 10mm-side square)
  • row suppressed for open paths (gating correct)
  • helper defensive against <2-node degenerate input
  • open-vs-closed perimeter differs as expected (20mm vs ~34.1mm for the 3-vertex fixture)

Verified locally: 6/6 issue-355 tests pass, 2407/2428 vitest pass overall (20 pre-existing failures in issue-329/#331/#333/#334 from a separate #344 findTightCurves crash, unrelated to #355 — those tests fail on main without my change). tsc -b clean, eslint clean.

CI status: Forgejo Actions run queued at 12:28:37Z, still "Waiting to run" at 12:44Z — runner queue delay, not a code problem. The push landed on origin/main as 44f4b8e; the operator can re-trigger if needed.

Closed by fix(#355) at 44f4b8e (push 668f1d8..44f4b8e). The right panel's Path Statistics subsection (already added in #261 with Path area / Thread usage / Stitch time / Covers fabric) now includes a Perimeter row that exposes the closed-boundary length including the implicit closing edge from the last node back to the first. Why the headline gap closed: - The existing Path Length row sums N-1 segment distances and silently omits the closing segment for closed paths, so a closed 4-node 10mm-side square reads as "30 mm" instead of the actual "40 mm" perimeter. The user has a clear "how long is the boundary?" row now. - `perimeterMm(nodes, closed)` helper added next to `polygonAreaMm2` (shoelace area, #261) and `estimatePathLength` (Path Length math). Same one-decimal precision as Path Length, 0 for degenerate node counts. - Gated on `selectedPath.closed` so open paths render only Path Length — adding Perimeter for an open polyline would just duplicate the value. - Tooltip on the value span explains the closing-edge inclusion explicitly. Path Length row is unchanged — the thread/stitch count math downstream of it (#261) already runs against the open-polyline convention, so flipping Path Length to include the closing segment would silently re-title stitch and thread estimates under them. 6 new tests at src/pages/issue-355.test.tsx pin: - row renders for closed paths - value includes the implicit closing edge (the 10mm delta the issue calls out, 30mm → 40mm for a closed 4-node 10mm-side square) - row suppressed for open paths (gating correct) - helper defensive against <2-node degenerate input - open-vs-closed perimeter differs as expected (20mm vs ~34.1mm for the 3-vertex fixture) Verified locally: 6/6 issue-355 tests pass, 2407/2428 vitest pass overall (20 pre-existing failures in issue-329/#331/#333/#334 from a separate #344 findTightCurves crash, unrelated to #355 — those tests fail on main without my change). tsc -b clean, eslint clean. CI status: Forgejo Actions run queued at 12:28:37Z, still "Waiting to run" at 12:44Z — runner queue delay, not a code problem. The push landed on origin/main as 44f4b8e; the operator can re-trigger if needed.
Mark closed this issue 2026-10-05 12:46:23 +00:00
Sign in to join this conversation.
No description provided.