Added Ridgeline Plots and layers output
This commit is contained in:
71
tools/qft-perspective-sweep.mjs
Normal file
71
tools/qft-perspective-sweep.mjs
Normal file
@@ -0,0 +1,71 @@
|
||||
/* ============================================================
|
||||
qft-perspective-sweep.mjs — workshop the QFT cartesian/wavy grid
|
||||
viewpoint. Isolates the cubic lattice (other fields off) and sweeps
|
||||
the new camera: yaw / pitch / roll / perspective / distance.
|
||||
Usage: node tools/qft-perspective-sweep.mjs [size]
|
||||
============================================================ */
|
||||
import { writeFileSync, mkdirSync } from 'node:fs';
|
||||
import { generateQFTScene } from '../src/qft/scene.js';
|
||||
import { paramsFromSeed } from '../src/qft/params.js';
|
||||
import { renderQFTSVG } from '../src/qft/renderer.js';
|
||||
|
||||
const SIZE = +(process.argv[2] || 1100);
|
||||
const OUT = 'output/qft/perspective';
|
||||
mkdirSync(OUT, { recursive: true });
|
||||
const SEED = 'LATTICE-1003';
|
||||
|
||||
const F = (h0, h1, s, l, o, st) => ({ hueStart: h0, hueEnd: h1, saturation: s, lightness: l, opacity: o, stroke: st });
|
||||
const OFF = F(0, 0, 0, 0.5, 0, 0);
|
||||
|
||||
// isolate the cartesian grid: cubic only, mid teal, thin-ish wavy photon edges
|
||||
const BASE = {
|
||||
substrate: 'cream', showHeader: false, glow: 0.16, vign: 0.12,
|
||||
cubicN: 1, photonCyclesPerUnit: 7, segmentsPerEdge: 12, stroke: 1.3,
|
||||
cubicScale: 1.05, cubicRot: 0, linkCount: 0, e8Count: 0,
|
||||
fields: {
|
||||
cubic: F(0.52, 0.57, 0.6, 0.34, 1.0, 1.3), schlegel: OFF, e8: OFF, ripple: OFF, links: OFF,
|
||||
},
|
||||
};
|
||||
|
||||
const D = Math.PI / 180;
|
||||
const cam = (name, label, c) => ({ name, label, cam: c });
|
||||
const SWEEP = [
|
||||
// baseline isometric
|
||||
cam('01_iso-default', 'isometric · default 3/4', { }),
|
||||
// yaw (spin) at iso pitch
|
||||
cam('02_yaw-front', 'yaw 0° · facing a face', { yaw: 0, pitch: 35 * D }),
|
||||
cam('03_yaw-deep', 'yaw -70° · spun round', { yaw: -70 * D, pitch: 35 * D }),
|
||||
// pitch (tip)
|
||||
cam('04_pitch-low', 'pitch 12° · near eye-level', { yaw: -45 * D, pitch: 12 * D }),
|
||||
cam('05_pitch-steep', 'pitch 58° · looking down', { yaw: -45 * D, pitch: 58 * D }),
|
||||
cam('06_pitch-top', 'pitch 78° · near top-down', { yaw: -45 * D, pitch: 78 * D }),
|
||||
// perspective (vanishing point) at the 3/4 angle
|
||||
cam('07_persp-mild', 'perspective 0.45 · gentle depth', { persp: 0.45, dist: 4.2 }),
|
||||
cam('08_persp-strong','perspective 0.9 · dist 2.6 · dramatic', { persp: 0.9, dist: 2.6 }),
|
||||
cam('09_persp-corner','into a corner · 1-pt-ish', { yaw: 30 * D, pitch: 30 * D, persp: 0.7, dist: 3.0 }),
|
||||
// roll / cant
|
||||
cam('10_roll-cant', 'roll 18° · canted + persp 0.4', { roll: 18 * D, persp: 0.4, dist: 3.6 }),
|
||||
// dramatic hero angles
|
||||
cam('11_hero-tunnel', 'low + strong persp · tunnel', { yaw: -45 * D, pitch: 18 * D, persp: 0.95, dist: 2.3 }),
|
||||
cam('12_hero-vault', 'steep + persp · vaulted ceiling', { yaw: -20 * D, pitch: 62 * D, persp: 0.8, dist: 2.8 }),
|
||||
];
|
||||
|
||||
console.log(`Perspective sweep (${SWEEP.length}) → ${OUT}/ seed=${SEED}`);
|
||||
for (const v of SWEEP) {
|
||||
const p = {
|
||||
...paramsFromSeed(SEED), ...BASE,
|
||||
cubicYaw: v.cam.yaw ?? -45 * D, cubicPitch: v.cam.pitch ?? 35.26 * D,
|
||||
cubicRoll: v.cam.roll ?? 0, cubicPersp: v.cam.persp ?? 0, cubicDist: v.cam.dist ?? 3.4,
|
||||
};
|
||||
writeFileSync(`${OUT}/${v.name}.svg`, renderQFTSVG(generateQFTScene(p), p, SIZE));
|
||||
console.log(` ${v.name} — ${v.label}`);
|
||||
}
|
||||
|
||||
const cap = (v) => `${v.name.replace(/^\d+_/, '').replace(/-/g, ' ')} · ${v.label}`;
|
||||
const m = `<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<style>html,body{margin:0;background:#222}.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:10px;width:2100px}figure{margin:0;position:relative;background:#fff;overflow:hidden}img{width:100%;display:block}figcaption{position:absolute;left:0;bottom:0;right:0;padding:6px 10px;font:13px ui-monospace,monospace;color:#fff;background:linear-gradient(transparent,#000d)}</style></head><body>
|
||||
<div class="grid">
|
||||
${SWEEP.map(v => `<figure><img src="${v.name}.svg"><figcaption>${cap(v)}</figcaption></figure>`).join('\n')}
|
||||
</div></body></html>`;
|
||||
writeFileSync(`${OUT}/m.html`, m);
|
||||
console.log(`contact sheet -> ${OUT}/m.html`);
|
||||
Reference in New Issue
Block a user