Pin the whiteboard geometry, and record what the poison arm disproved

Three properties, each with the arm that catches its own defect: the bounded
set's gap survives projection, the drawing stays inside the Mercator clamp, and
a radius expressed in map units doubles with every zoom level.

The first arm taught me something I had assumed the opposite of. It narrowed the
gap to a tenth of a percent expecting the margins to go negative. They stayed
positive: the projection is conformal, so it preserves the ratio exactly, and a
narrow gap survives just as an eight percent one does. There is no distortion for
it to be eaten by.

So "the gap survives projection" is close to a tautology, and a check resting on
it alone would look like a guard while testing almost nothing. What can actually
fail is the ordering of the constants, and that is what the arm now poisons. The
narrowing case is kept as a passing assertion rather than deleted, because the
fact that it is safe is worth stating: the boundary cannot be eroded by the
projection, only by someone editing the numbers.

The clamp arm holds for every chart at once. The ceiling belongs to
extentFraction alone, not to a chart's extent — the scale is extentFraction over
extent and the outermost point sits at the extent, so the product is always the
fraction. Asserted across four extents, identical to three decimals.
This commit is contained in:
Doxa Maps 2026-09-28 17:04:03 +00:00
parent 092585af6c
commit 16fd9c6207

View file

@ -0,0 +1,111 @@
#!/usr/bin/env node
/**
* check-gospel-whiteboard — the geometry the set charts depend on once they are drawn on a map.
*
* Three properties, each with the arm that would catch its own defect. None of them is about
* whether the chart renders; all three are about it rendering something TRUE.
*
* 1. THE BOUNDED SET'S GAP SURVIVES PROJECTION. Inside points sit within 0.92r and outside
* beyond 1.12r, and nothing may land on the boundary — a dot on the line is the one thing a
* bounded set cannot express. Asserted on PROJECTED coordinates. Note what the arm below
* found: the projection is conformal, so it preserves the ratio EXACTLY and a narrowed gap
* survives just as a wide one does. The boundary cannot be eroded by the projection, only by
* someone editing the constants — which is therefore what the arm poisons.
* 2. THE DRAWING STAYS INSIDE THE MERCATOR CLAMP. Shape does not degrade with extentFraction —
* the projection is the exact inverse of the renderer's transform, measured at 0.000% aspect
* error, and an earlier claim of mine that it did was an artefact of my own harness. What
* does bite is latitude: engines clamp near 85 degrees.
* 3. A RADIUS IN MAP UNITS DOUBLES WITH EVERY ZOOM LEVEL. circle-radius is screen pixels, so a
* boundary that does not scale is correct at one zoom and wrong at every other.
*
* ★ THE CEILING IS A PROPERTY OF extentFraction ALONE, not of a chart's extent: the scale is
* extentFraction/extent and the outermost point is at u = extent, so the product is always
* extentFraction. A consumer cannot buy headroom against the clamp by choosing a bigger extent,
* and one assertion covers every chart.
*/
import { layoutBoundedSet } from '../plugin-designs/gospel-internet/src/boundedSet.js'
import { degreesToPixelRadius, dishRadiusDegrees, toFeatureCollection, centeredSetFeatures }
from '../plugin-designs/gospel-internet/src/setChartFeatures.js'
import { layoutCenteredSet, ringRadii } from '../plugin-designs/gospel-internet/src/centeredSet.js'
import { whiteboardProjection } from '../library/maps/whiteboard-projection.js'
const fail = []
const ok = (label, cond, detail = '') => {
if (cond) console.log(` ✓ ${label}${detail ? ` — ${detail}` : ''}`)
else { console.log(` ✗ ${label}${detail ? ` — ${detail}` : ''}`); fail.push(label) }
}
const R2D = 180 / Math.PI
// TRUE Web Mercator screen space: x is proportional to LONGITUDE ALONE. An earlier version of
// this used lng*cos(lat), a plate-carree correction the renderer never applies, and it
// manufactured a distortion that does not exist. Keep x = lng.
const screen = (lng, lat) => [lng, Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)) * R2D]
console.log('GOSPEL-WHITEBOARD')
// ── 1. the boundary gap, on projected coordinates ───────────────────────────
const R = 120, SPREAD = 260
function gapMargins(extentFraction, inner = 0.92, outer = 1.12) {
const p = whiteboardProjection({ extent: SPREAD, extentFraction })
const d = (u, v) => { const [lng, lat] = p(u, v); const [x, y] = screen(lng, lat); return Math.hypot(x, y) }
let bMin = Infinity, bMax = -Infinity, inMax = -Infinity, outMin = Infinity
for (let i = 0; i < 720; i++) {
const a = i / 720 * 2 * Math.PI, c = Math.cos(a), s = Math.sin(a)
const b = d(c * R, s * R); bMin = Math.min(bMin, b); bMax = Math.max(bMax, b)
inMax = Math.max(inMax, d(c * R * inner, s * R * inner))
outMin = Math.min(outMin, d(c * R * outer, s * R * outer))
}
return { inside: bMin - inMax, outside: outMin - bMax }
}
const m = gapMargins(0.17)
ok('bounded: no inside point reaches the boundary', m.inside > 0, `margin ${m.inside.toFixed(3)}`)
ok('bounded: no outside point reaches the boundary', m.outside > 0, `margin ${m.outside.toFixed(3)}`)
// ★ THE ARM, AND WHAT WRITING IT TAUGHT ME. My first version narrowed the gap to 0.999/1.001 and
// expected the margins to go negative. THEY DID NOT — they stayed positive at 0.028. The
// projection is conformal, so it preserves the RATIO exactly; a gap of a tenth of a percent
// survives projection just as a gap of eight percent does. There is no distortion for a narrow
// gap to be eaten by.
// That means "the gap survives projection" is very nearly a tautology, and a check resting on it
// alone would look like a guard while testing almost nothing. What CAN actually fail is the
// ORDERING of the constants — someone editing 0.92/1.12 to the wrong side of 1 — so that is what
// the arm poisons. Recorded rather than quietly swapped, because the fact that narrowing is safe
// is itself worth knowing: it says the boundary cannot be eroded by the projection, only by us.
const inverted = gapMargins(0.17, 1.01, 0.99)
ok('bounded: inverting the constants FAILS (so the guard is not inert)',
inverted.inside <= 0 || inverted.outside <= 0,
`inverted margins ${inverted.inside.toFixed(3)} / ${inverted.outside.toFixed(3)}`)
const narrow = gapMargins(0.17, 0.999, 1.001)
ok('bounded: a narrowed gap still survives, because the projection preserves ratios exactly',
narrow.inside > 0 && narrow.outside > 0, `margins ${narrow.inside.toFixed(3)} / ${narrow.outside.toFixed(3)}`)
// ── 2. the latitude ceiling ─────────────────────────────────────────────────
const EXTENT_C = 30 + 9 * 22
const feats = centeredSetFeatures(
layoutCenteredSet([{ id: 'a', label: 'A', ring: 10 }], { innerR: 30, ringGap: 22 }).placed,
ringRadii({ innerR: 30, ringGap: 22 }), {})
const { maxAbsLat } = toFeatureCollection(feats, whiteboardProjection({ extent: EXTENT_C }))
ok('centered: the drawing stays inside the Mercator clamp', maxAbsLat < 85, `max |lat| ${maxAbsLat.toFixed(2)}`)
// THE ARM: the ceiling is extentFraction's, so a wide one must breach it
const wide = whiteboardProjection({ extent: EXTENT_C, extentFraction: 0.95 })(0, EXTENT_C)[1]
ok('the clamp CAN be breached by extentFraction alone (so the guard is not inert)',
Math.abs(wide) > 85, `|lat| ${Math.abs(wide).toFixed(2)} at fraction 0.95`)
// and it does not depend on the extent
const lats = [100, 228, 260, 1000].map((e) => Math.abs(whiteboardProjection({ extent: e })(0, e)[1]))
ok('the ceiling is extentFraction\'s alone, not the extent\'s',
Math.max(...lats) - Math.min(...lats) < 1e-6, lats.map((l) => l.toFixed(3)).join(' '))
// ── 3. a map-unit radius doubles per zoom ───────────────────────────────────
const deg = dishRadiusDegrees(R, whiteboardProjection({ extent: SPREAD }))
const expr = degreesToPixelRadius(deg)
const [, , , z0, r0, z1, r1] = expr
ok('dish: the radius is a zoom expression, not a constant', Array.isArray(expr) && expr[0] === 'interpolate')
ok('dish: it uses exponential base 2, which is what doubling per zoom requires',
expr[1][0] === 'exponential' && expr[1][1] === 2)
ok('dish: its stops scale by exactly 2^(z1-z0)',
Math.abs(r1 / r0 - Math.pow(2, z1 - z0)) / Math.pow(2, z1 - z0) < 1e-9,
`${r0.toFixed(2)}px at z${z0}`)
if (fail.length) {
console.log(`\nGOSPEL-WHITEBOARD: FAIL — ${fail.length}: ${fail.join(', ')}`)
process.exit(1)
}
console.log('\nGOSPEL-WHITEBOARD: PASS — the gap, the clamp and the scaling all hold, and each arm can fail')