tower / files / src / ui / scales.ts
scales.ts
| 1 | /** |
| 2 | * Slider mappings shared by the panel and the views. |
| 3 | * |
| 4 | * This lives outside views/ on purpose: the panel needs the eye-height scale to |
| 5 | * label its slider before the interior view exists, and importing the view for it |
| 6 | * would statically pull Three.js into the entry chunk — the exact regression |
| 7 | * D-021 fixed for the exterior. |
| 8 | */ |
| 9 | |
| 10 | /** Standing eye height. */ |
| 11 | export const EYE_MIN_M = 1.7 |
| 12 | import { BEAM_RADIUS_M, RADIUS_M } from '../canon/constants.js' |
| 13 | |
| 14 | /** |
| 15 | * The edge of the beam, above the datum: as high as anyone can go (D-084). The whole world |
| 16 | * seen as a tube from inside its air (world-generation.md §6.4), with the beam filling the |
| 17 | * sky overhead. It was 45 km, 3.4 km short of it, until the author asked for the beam to be |
| 18 | * the top of the eye-height gauge. The interior stops you a little short of it, over |
| 19 | * whatever ground you are above. |
| 20 | */ |
| 21 | export const EYE_MAX_M = RADIUS_M - BEAM_RADIUS_M |
| 22 | |
| 23 | /** Eye height from a 0..1 slider position. Logarithmic, so 1.7 m is reachable. */ |
| 24 | export const eyeHeightFromSlider = (v: number): number => |
| 25 | EYE_MIN_M * (EYE_MAX_M / EYE_MIN_M) ** Math.min(1, Math.max(0, v)) |
| 26 | |
| 27 | export const sliderFromEyeHeight = (h: number): number => |
| 28 | Math.log(Math.max(EYE_MIN_M, h) / EYE_MIN_M) / Math.log(EYE_MAX_M / EYE_MIN_M) |