Skip to content

feat(water): the pause lands on the layer the slicer will swap at - #71

Open
danstiner wants to merge 1 commit into
docs-slicingfrom
slicing-pause-z
Open

feat(water): the pause lands on the layer the slicer will swap at#71
danstiner wants to merge 1 commit into
docs-slicingfrom
slicing-pause-z

Conversation

@danstiner

Copy link
Copy Markdown
Owner

Stacked on #70 (which is stacked on #69). Implements what that spec derives.

The bug

The export placed the water pause one layer above the color line; the preview drew it at the line itself. Both were guesses about a grid neither modeled.

  • zLine + layerMm is right only when the line falls in the upper half of its layer, and a full layer late otherwise. Measured on a 0.25 mm first layer: it emits 6.250 where 6.100 was available, handing a whole layer of land to the water color.
  • The preview's bare line is wrong the other way — it draws land green that the print buries in blue. 41.0% of Bora Bora's land at the old defaults.

The change

pauseZ    = top(W + 1)     export print_z — top of the first layer that may print land,
                           the earliest swap leaving every water column its own color
boundaryZ = slice(W + 1)   what the print looks like — that layer's slice plane, half a layer lower

W is the last layer the water's surface reaches. colorChanges now takes the resulting height outright (waterZ) rather than an offset from the line, because that height is the grid's to decide and the line knows nothing about the grid.

First layer height becomes a setting

None of this is computable without it, and the export cannot pin it — writing any key into the project config stub would replace the user's presets (see #70). It is optional in the hash and written only when it differs from the default, so existing links stay byte-identical and decode to the 0.2 they were always assumed to have. Payload: 104 chars at the default, 120 with a custom value.

Defaults move to 0.2 first / 0.1 layer

boundary − zLine is a sawtooth over (0, h]: it shrinks toward zero, then snaps back a full layer the moment the line crosses a slice plane. A whole-mm base lands on a layer top exactly when h divides base − fh, putting the offset at h/2 — not the smallest, but the furthest from that snap in both directions.

grid offset at a 6 mm base distance to the snap Bora Bora boundary land printing water-colored
0.2 / 0.15 0.125 = 0.83·h 0.17·h +10.0 m 41.0%
0.2 / 0.10 0.050 = 0.50·h 0.50·h +4.0 m 16.0%

At 0.15 a 0.025 mm drift in base or exaggeration moves the printed boundary by 10 m of ground. At 0.1 it does not.

Swept all 29 presets at both layer defaults

  • waterAsLand crossing the 1% warning threshold: none
  • groove share moving: none
  • color line moving: 3, all polders — Zeeland −77.59→−52.59, New Orleans −86.19→−61.19, Dead Sea −522.25→−492.25. Their anchor is 2 lifts below the lowest land and a lift is layerMm/K, so a thinner layer needs proportionally less margin. None of their warnings change.

Deferred

water.js still approximates the boundary as one full layer for its lakes groove ceiling and the waterAsLand warning. That over-states it by up to half a layer, so it under-warns rather than over-grooves. Moving it changes warning output, not export geometry, and belongs in its own PR — as does the land-prints-in-the-water-color warning that Bora Bora's 16% currently triggers nothing for.

442 tests pass (7 new), tsc clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YSKNezHjK4jsY8UoP2Bquw

The export placed the water pause one layer above the color line, and the
preview drew it at the line itself. Both were guesses about a grid neither of
them modeled, and docs/specs/slicing.md now says what the grid actually is.

Replaces both with slicing.waterPause(zLine, {layerMm, firstLayerMm}):

  pauseZ    = top(W + 1)    the export's print_z — the top of the first layer
                            that may print land, the earliest swap that
                            leaves every water column its own color
  boundaryZ = slice(W + 1)  what the print then looks like — that layer's
                            slice plane, half a layer lower

where W is the last layer the water's surface reaches. colorChanges takes the
resulting height outright (`waterZ`) instead of an offset from the line,
because that height is the grid's to decide and the line knows nothing about
the grid.

`zLine + layerMm` was right only when the line fell in the upper half of its
layer, and a full layer late otherwise — measured on a 0.25 mm first layer, it
emitted 6.250 where 6.100 was available, handing a whole layer of land to the
water color. The preview's bare line was wrong the other way, drawing land
green that the print buries in blue: 41.0% of Bora Bora's land at the old
defaults.

Adds the first layer height as a setting, since none of this is computable
without it and the export cannot pin it (writing any key into the project
config stub would replace the user's presets — see the spec). Optional in the
hash and written only when it differs from the default, so existing links are
byte-identical and decode to the 0.2 they were always assumed to have.

Defaults move to 0.2 first / 0.1 layer. `boundary − zLine` is a sawtooth over
(0, h]: it shrinks toward zero, then snaps back a full layer the moment the
line crosses a slice plane. A whole-mm base lands on a layer top exactly when
h divides base − fh, which puts the offset at h/2 — not the smallest, but the
furthest from that snap in both directions. At 0.2/0.15 a 6 mm base sits 0.17
of a layer from it, so 0.025 mm of drift in base or exaggeration moves the
printed boundary by 10 m of ground. At 0.2/0.1 it sits dead center, and Bora
Bora's boundary falls from +10.0 m to +4.0 m — 41.0% of its land printing in
the water color down to 16.0%.

Swept all 29 presets at both layer defaults: no preset crosses the 1%
waterAsLand warning threshold, no groove share moves, and only the three
polders' color lines move at all (Zeeland -77.59 to -52.59, New Orleans
-86.19 to -61.19, Dead Sea -522.25 to -492.25) — their anchor is 2 lifts below
the lowest land, and a lift is layerMm/K.

water.js keeps approximating the boundary as one full layer for its lakes
groove ceiling and waterAsLand warning. That over-states it by up to half a
layer, so it under-warns rather than over-grooves; moving it is a warning
change, not an export one, and belongs in its own PR.

442 tests pass (7 new), tsc clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSKNezHjK4jsY8UoP2Bquw
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant