/* qft-perspgrid.mjs — sweep the perspective depth grid (VP off-horizon), plus a dual blur/fine plate deck. Usage: node tools/qft-perspgrid.mjs [size] */ import { writeFileSync, mkdirSync } from 'node:fs'; import { perspectiveGridSVG } from '../src/qft/perspgrid.js'; const SIZE = +(process.argv[2] || 1400); const ROOT = 'output/qft/perspgrid'; mkdirSync(`${ROOT}/explore`, { recursive: true }); mkdirSync(`${ROOT}/deck`, { recursive: true }); const D = Math.PI / 180; const EXPLORE = [ { name: '01_center-funnel', label: 'VP centre · full radial funnel', o: { vp: [0, 0], spread: Math.PI * 2, rays: 30, depthLines: 16 } }, { name: '02_high-vp-fan', label: 'VP high (sky) · fan downward', o: { vp: [0, -0.55], dir: 95 * D, spread: 150 * D, rays: 26 } }, { name: '03_low-vp-into-sea', label: 'VP low (in the sea) · fan upward', o: { vp: [0, 0.5], dir: -90 * D, spread: 150 * D, rays: 26 } }, { name: '04_corner-upper-left', label: 'VP off-frame upper-left · diagonal', o: { vp: [-1.3, -1.1], dir: 35 * D, spread: 60 * D, rays: 22, rMax: 3.4 } }, { name: '05_offright-corridor', label: 'VP off-frame right · corridor', o: { vp: [1.4, -0.1], dir: 178 * D, spread: 70 * D, rays: 22, rMax: 3.2 } }, { name: '06_center-tight-tunnel', label: 'VP centre · tight crowded tunnel', o: { vp: [0.1, -0.1], spread: Math.PI * 2, rays: 40, depthLines: 22, depthPow: 3.0 } }, { name: '07_upper-cone-wide', label: 'VP upper · wide shallow cone', o: { vp: [0.2, -0.8], dir: 100 * D, spread: 120 * D, rays: 24, depthPow: 1.8 } }, { name: '08_teal-mandala', label: 'VP centre · teal radial mandala-grid', o: { vp: [0, -0.05], spread: Math.PI * 2, rays: 36, depthLines: 18, hue: 0.5, hue2: 0.55, sat: 0.5 } }, ]; console.log(`perspgrid · explore (${EXPLORE.length}) → ${ROOT}/explore/`); for (const v of EXPLORE) { writeFileSync(`${ROOT}/explore/${v.name}.svg`, perspectiveGridSVG(SIZE, { ...v.o, mode: 'solid' })); console.log(` ${v.name} — ${v.label}`); } writeFileSync(`${ROOT}/explore/m.html`, `