Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/backlog/features/E14-F13-every-calculation-named.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The Product Owner asked for no further questions: F13 is done after F10, and bot
| ---------------------------------------------------------------- | ---------- | --------------------------------------------------------------------- | ------ |
| [SP-014](../stories/E14-F13-SP-014-research-f13.md) | Spike | Research for F13: the named calculations and their sources | done |
| [EN-028](../stories/E14-F13-EN-028-name-math-and-geometry.md) | Enabler | Pass 1: name the calculations of `math` and `geometry` | done |
| [EN-029](../stories/E14-F13-EN-029-name-model-and-playground.md) | Enabler | Pass 1: name the calculations of the model, io, render and playground | ready |
| [EN-029](../stories/E14-F13-EN-029-name-model-and-playground.md) | Enabler | Pass 1: name the calculations of the model, io, render and playground | done |
| [CHK-013](../stories/E14-F13-CHK-013-checkpoint-f13.md) | Checkpoint | Checkpoint between the two passes | ready |
| [EN-030](../stories/E14-F13-EN-030-second-pass.md) | Enabler | Pass 2: what pass 1 missed, and the duplicates | ready |
| [AUD-014](../stories/E14-F13-AUD-014-audit-f13.md) | Audit | Audit F13 | ready |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ id: EN-029
epic: E14
feature: F13
title: "Pass 1: name the calculations of the model, io, render and playground"
status: ready
status: done
points: 2
---

Expand All @@ -20,4 +20,8 @@ The same pass on `src/model`, `src/io`, `src/render` and the playground: an inli

One task = one commit, referenced as `EN-029.Tn`.

- [ ] T1 — The calls in the model, io, render and playground (2 h)
- [x] T1 — The calls in the model, io, render and playground (2 h)

## Review

Auditor, before the last commit: every replacement re-derived; fixed — the conversion buttons' test of a flat shape kept as it was (`!hasArea` differs when a fractional product underflows), the TSDoc of `hasArea` and `clamp`, the split point's mirrored handle written as `mirroredHandle`, the folders table. Left inline with its reason: turning by an angle, already two named steps.
2 changes: 1 addition & 1 deletion docs/backlog/stories/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
| [AUD-012](./E14-F12-AUD-012-audit-after-validation.md) | F12 | Audit the changes asked at the validation | done |
| [SP-014](./E14-F13-SP-014-research-f13.md) | F13 | Research for F13: the named calculations and their sources | done |
| [EN-028](./E14-F13-EN-028-name-math-and-geometry.md) | F13 | Pass 1: name the calculations of math and geometry | done |
| [EN-029](./E14-F13-EN-029-name-model-and-playground.md) | F13 | Pass 1: name the calculations of the model, io, render and playground | ready |
| [EN-029](./E14-F13-EN-029-name-model-and-playground.md) | F13 | Pass 1: name the calculations of the model, io, render and playground | done |
| [CHK-013](./E14-F13-CHK-013-checkpoint-f13.md) | F13 | Checkpoint between the two passes | ready |
| [EN-030](./E14-F13-EN-030-second-pass.md) | F13 | Pass 2: what pass 1 missed, and the duplicates | ready |
| [AUD-014](./E14-F13-AUD-014-audit-f13.md) | F13 | Audit F13 | ready |
Expand Down
16 changes: 8 additions & 8 deletions docs/conventions/files.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ Every code folder has an `index.ts` barrel (see [imports.md](./imports.md)). Fol

A code folder holds **modules or domain folders, never both**: beside folders sits only the barrel (and the playground's entry). `local/folder-layout` reports a TypeScript file beside folders at once, in the editor; `tests/folders.test.ts` checks every other file.

| Folder | Domains |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src/math/` | `vector/` (the point, the vector, its products and distance), `angle/` (degrees and radians, directions, signed and central angles), `rotation/` (rotate, quarter turns), `interpolation/` (midpoint, point between), `arithmetic/` (average, modulo), `polynomial/` (the quadratic, its discriminant and roots), `bisection/`, `precision/` (`EPSILON`) |
| `src/geometry/` | `contour/` (arcs, segments, cubics, corners, `cyclicItem`), `corner-radius/` (fillets, clamp, turning angles), `handles/` (a point's handles, curved sides, their box, F12), `regular-polygon/` (regular and stretched), `layout-box/` (alignment, anchor, fit, stretch, size — Q21), `placement/` (straight box, turn — `shapes.md` §1), `curve/` (cubic sides, their box and split, F12), `fillet-side/`, `curve-fillet/` and `curve-contour/` (a fillet beside a curve, ADR-0047), `round-shape/` (the ellipse as four cubics, ADR-0048) |
| `src/model/` | one folder per shape, its type inside (`rectangle/`, `regular-polygon/`, `free-shape/`, `round-shape/`), `shape/` (the three kinds of shape told apart), then `corner-radius/` (`shapes.md` §2), `handles/` (handles' default, validity, typing), `layout-box/` (anchor and size checks), `placement/` (position, angle, turned corners), `selection/` (`interaction.md`) |
| `src/io/` | modules only: the writing of path data, one domain |
| `src/render/` | modules only: the SVG elements, one domain |
| `playground/` | one folder per panel (`toolbar/`, `shape/`, `points/`, `handles/`, `position/`, `drawing/`, `guided-test/`), the steps of the guided tests (`guided-steps/`), the fields every panel reads and writes (`page/`), the wiring of the panels (`mount/`), the tests' actions (`user-actions/`) |
| Folder | Domains |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `src/math/` | `vector/` (the point, the vector, its products and distance), `angle/` (degrees and radians, quarter and half turns, explement, directions, signed and central angles), `rotation/` (rotate, quarter turns), `interpolation/` (midpoint, point between), `arithmetic/` (average, clamp, modulo), `polynomial/` (the quadratic, its discriminant and roots), `bisection/`, `precision/` (`EPSILON`) |
| `src/geometry/` | `contour/` (arcs, segments, cubics, corners, `cyclicItem`), `corner-radius/` (fillets, clamp, turning angles), `handles/` (a point's handles, curved sides, their box, F12), `regular-polygon/` (regular and stretched), `layout-box/` (alignment, anchor, fit, stretch, size, box size, half size, area — Q21), `placement/` (straight box, turn — `shapes.md` §1), `curve/` (cubic sides, their box and split, F12), `fillet-side/`, `curve-fillet/` and `curve-contour/` (a fillet beside a curve, ADR-0047), `round-shape/` (the ellipse as four cubics, ADR-0048) |
| `src/model/` | one folder per shape, its type inside (`rectangle/`, `regular-polygon/`, `free-shape/`, `round-shape/`), `shape/` (the three kinds of shape told apart), then `corner-radius/` (`shapes.md` §2), `handles/` (handles' default, validity, typing), `layout-box/` (anchor and size checks), `placement/` (position, angle, turned corners), `selection/` (`interaction.md`) |
| `src/io/` | modules only: the writing of path data, one domain |
| `src/render/` | modules only: the SVG elements, one domain |
| `playground/` | one folder per panel (`toolbar/`, `shape/`, `points/`, `handles/`, `position/`, `drawing/`, `guided-test/`), the steps of the guided tests (`guided-steps/`), the fields every panel reads and writes (`page/`), the wiring of the panels (`mount/`), the tests' actions (`user-actions/`) |

A shape's type lives in its folder (`free-shape/free-shape.ts`); folders may use each other's types, their value imports go one way (`import-x/no-cycle`). A test of the whole page sits in the folder of the panel it exercises. Why: [ADR-0043](../adr/0043-folders-by-domain.md).

Expand Down
24 changes: 13 additions & 11 deletions docs/research/notes/0016-f13-named-calculations.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ Existing names used where the code wrote them out: `subtract`, `add`, `scale`, `

## Left inline, with the reason

| Calculation | Reason |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `d − floor(d/90)·90` in `turnDirection` | `modulo(d, 90)` differs when `d/90` rounds up |
| `t − end / SAMPLES` in `crossings` | not always equal to the previous grid point |
| the translation of `freeShapeContour`, `dx === 0 ? …` | `add` turns −0 into +0 |
| `(b < 0 ? −1 : 1)` in `quadraticRoots` | a sign with sign(0) = +1, not `Math.sign`; no standard name |
| `cubicVelocity` beside `derivativeCoefficients` | Bernstein and power forms of one derivative round differently: documented, not merged |
| `midpoint` beside `pointBetween(…, 1/2)` | `(a + b)/2` and `a/2 + b/2` differ on overflow and subnormals: both kept |
| the playground's handle bar and inset box | drawings of the playground only; a band and an inset need a derivation of their own |
| one-sided tolerance tests (`radius − effective ≥ EPSILON`) | no standard name |
| evenly spaced samples `(k · T) / n` | no source read for the name; pass 2 |
| Calculation | Reason |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `d − floor(d/90)·90` in `turnDirection` | `modulo(d, 90)` differs when `d/90` rounds up |
| `t − end / SAMPLES` in `crossings` | not always equal to the previous grid point |
| the translation of `freeShapeContour`, `dx === 0 ? …` | `add` turns −0 into +0 |
| `(b < 0 ? −1 : 1)` in `quadraticRoots` | a sign with sign(0) = +1, not `Math.sign`; no standard name |
| `cubicVelocity` beside `derivativeCoefficients` | Bernstein and power forms of one derivative round differently: documented, not merged |
| `midpoint` beside `pointBetween(…, 1/2)` | `(a + b)/2` and `a/2 + b/2` differ on overflow and subnormals: both kept |
| the playground's handle bar and inset box | drawings of the playground only; a band and an inset need a derivation of their own |
| `turnAbout(p, c, turnDirection(α))` in the model | already two named steps: turning by the direction of an angle; a third name would only wrap them |
| `width === 0 \|\| height === 0` in the playground's conversion buttons | `!hasArea` differs when a fractional product underflows |
| one-sided tolerance tests (`radius − effective ≥ EPSILON`) | no standard name |
| evenly spaced samples `(k · T) / n` | no source read for the name; pass 2 |

## Open

Expand Down
7 changes: 4 additions & 3 deletions playground/drawing/create-straight-box-element.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createPathElement, formatSvgNumber } from "../../src";
import { boxSize, createPathElement, formatSvgNumber, halfSize } from "../../src";

import type { BoundingBox } from "../../src";

Expand Down Expand Up @@ -73,8 +73,9 @@ function readSideDashes(side: Side): string {
*/
export function createStraightBoxElement(document: Document, box: BoundingBox): SVGPathElement {
// In a box thinner than two lines, the far dashes stay inside it.
const across = Math.min(LINE, (box.maxY - box.minY) / 2);
const along = Math.min(LINE, (box.maxX - box.minX) / 2);
const half = halfSize(boxSize(box));
const across = Math.min(LINE, half.y);
const along = Math.min(LINE, half.x);
const sides: readonly Side[] = [
{ at: box.minY, end: box.maxX, isHorizontal: true, start: box.minX },
{ at: box.maxY - across, end: box.maxX, isHorizontal: true, start: box.minX },
Expand Down
7 changes: 4 additions & 3 deletions playground/drawing/write-straight-box.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { formatSvgNumber } from "../../src";
import { boxSize, formatSvgNumber } from "../../src";
import { writeInputValue, writeText } from "../page";

import type { BoundingBox } from "../../src";
Expand Down Expand Up @@ -33,8 +33,9 @@ export function writeStraightBox(document: Document, box: BoundingBox): void {

const x = formatSvgNumber(box.minX);
const y = formatSvgNumber(box.minY);
const width = formatSvgNumber(box.maxX - box.minX);
const height = formatSvgNumber(box.maxY - box.minY);
const size = boxSize(box);
const width = formatSvgNumber(size.width);
const height = formatSvgNumber(size.height);

writeText(
document,
Expand Down
3 changes: 2 additions & 1 deletion playground/guided-test/show-guided-step.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { clamp } from "../../src";
import { selectElement, writeText } from "../page";

import { writeStepToAddress } from "./write-step-to-address";
Expand All @@ -21,7 +22,7 @@ export function showGuidedStep(
steps: readonly GuidedStep[],
index: number,
): void {
const position = Math.min(Math.max(index, 0), steps.length - 1);
const position = clamp(index, 0, steps.length - 1);
const step = steps.at(position) ?? steps[0];

selectElement(document, "guide").hidden = step === undefined;
Expand Down
6 changes: 3 additions & 3 deletions playground/handles/read-selected-corner.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { hasArea } from "../../src";
import { readSelection } from "../page";

import type { CurveCorner } from "../../src";
Expand Down Expand Up @@ -37,10 +38,9 @@ function readOnlySelected(document: Document): number | undefined {
*/
function readFreeCorner(reading: ShapeReading, index: number): SelectedCorner | undefined {
const corner = reading.corners[index];
// A shape without width or height, a polygon that cannot be converted, gets no switch.
const hasArea = reading.model.width * reading.model.height > 0;

return corner === undefined || !hasArea ? undefined : { corner, index };
// A shape without width or height, a polygon that cannot be converted, gets no switch.
return corner === undefined || !hasArea(reading.model) ? undefined : { corner, index };
}

/**
Expand Down
Loading
Loading