Added QFT

This commit is contained in:
2026-05-29 15:40:42 -04:00
parent e59b024b62
commit 56c59a1f9c
148 changed files with 428741 additions and 7 deletions

169
tools/qft-variations.mjs Normal file
View File

@@ -0,0 +1,169 @@
/* ============================================================
qft-variations.mjs — render a curated set of variations.
Single base seed (geometry held constant); each variation
overrides per-field hue / sat / light / opacity + gradient mode
+ substrate (or arbitrary paperOverride RGB) + cross-field
link colours.
Output → output/qft/sketch02/
============================================================ */
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 BASE_SEED = 'FEYNMAN-7167';
const OUT_DIR = 'output/qft/sketch02';
const SIZE = 1800;
mkdirSync(OUT_DIR, { recursive: true });
const F = (hueStart, hueEnd, saturation, lightness, opacity) =>
({ hueStart, hueEnd, saturation, lightness, opacity });
const variations = [
{
name: '01_anchor-vintage', label: 'Anchor · warm vintage muted',
overrides: {
substrate: 'vintage', gradientMode: 'along-edge',
fields: {
cubic: F(0.08, 0.05, 0.30, 0.52, 0.65),
schlegel: F(0.10, 0.10, 0.20, 0.48, 0.55),
e8: F(0.10, 0.16, 0.65, 0.60, 0.92),
links: F(0.10, 0.04, 0.90, 0.62, 0.95), // bright amber
},
},
},
{
name: '02_ember-triad', label: 'Ember triad · warm fire band',
overrides: {
substrate: 'vintage', gradientMode: 'along-edge',
fields: {
cubic: F(0.04, 0.10, 0.65, 0.55, 0.75),
schlegel: F(0.96, 0.03, 0.55, 0.50, 0.65),
e8: F(0.12, 0.18, 0.85, 0.62, 0.90),
links: F(0.02, 0.10, 0.95, 0.62, 0.95), // deep red→orange
},
},
},
{
name: '03_aurora-void', label: 'Aurora · cool spectral on void',
overrides: {
substrate: 'void', gradientMode: 'along-edge', vign: 0.55,
fields: {
cubic: F(0.50, 0.72, 0.70, 0.60, 0.85),
schlegel: F(0.40, 0.55, 0.55, 0.58, 0.75),
e8: F(0.78, 0.92, 0.85, 0.65, 0.90),
links: F(0.55, 0.85, 0.95, 0.70, 0.95), // cyan → violet bright
},
},
},
{
name: '04_spectrum-cream', label: 'Spectrum · one rainbow field on cream',
overrides: {
substrate: 'cream', gradientMode: 'along-edge',
fields: {
cubic: F(0.00, 0.95, 0.80, 0.48, 0.80),
schlegel: F(0.0, 0.0, 0.05, 0.30, 0.50),
e8: F(0.0, 0.16, 0.55, 0.42, 0.75),
links: F(0.55, 0.05, 0.85, 0.45, 0.95), // cyan → red — spans the spectrum too
},
},
},
{
name: '05_verdigris', label: 'Verdigris · oxidised copper / patina',
overrides: {
substrate: 'vintage', gradientMode: 'along-edge',
fields: {
cubic: F(0.42, 0.50, 0.50, 0.55, 0.75),
schlegel: F(0.06, 0.02, 0.45, 0.45, 0.65),
e8: F(0.32, 0.45, 0.55, 0.55, 0.85),
links: F(0.04, 0.10, 0.85, 0.58, 0.95), // copper highlights
},
},
},
{
name: '06_radial-sunrise', label: 'Radial · cool centre → warm edges',
overrides: {
substrate: 'vintage', gradientMode: 'radial',
fields: {
cubic: F(0.55, 0.06, 0.60, 0.55, 0.78),
schlegel: F(0.55, 0.06, 0.50, 0.55, 0.65),
e8: F(0.55, 0.06, 0.70, 0.60, 0.88),
links: F(0.55, 0.06, 0.90, 0.62, 0.95), // shares the radial gradient
},
},
},
{
name: '07_magenta-family', label: 'Magenta family on cream',
overrides: {
substrate: 'cream', gradientMode: 'along-edge',
fields: {
cubic: F(0.85, 0.93, 0.50, 0.45, 0.75),
schlegel: F(0.78, 0.88, 0.42, 0.42, 0.65),
e8: F(0.92, 0.00, 0.60, 0.48, 0.88),
links: F(0.92, 0.78, 0.85, 0.40, 0.95), // saturated pink → purple
},
},
},
{
name: '08_per-field-mono', label: 'Per-field monochrome',
overrides: {
substrate: 'vintage', gradientMode: 'along-edge',
fields: {
cubic: F(0.55, 0.55, 0.55, 0.55, 0.70),
schlegel: F(0.88, 0.88, 0.55, 0.55, 0.70),
e8: F(0.12, 0.12, 0.75, 0.60, 0.92),
links: F(0.34, 0.34, 0.80, 0.55, 0.95), // mono green accent — a 4th distinct hue
},
},
},
{
name: '09_cyanotype', label: 'Cyanotype · Anna Atkins',
overrides: {
substrate: 'cyanotype', gradientMode: 'along-edge',
fields: {
cubic: F(0.55, 0.50, 0.30, 0.80, 0.85),
schlegel: F(0.55, 0.55, 0.20, 0.85, 0.75),
e8: F(0.48, 0.42, 0.50, 0.78, 0.92),
links: F(0.55, 0.50, 0.30, 0.92, 0.95), // near-white connectors
},
},
},
{
name: '10_single-bright-void', label: 'Single bright · E8 rainbow on void',
overrides: {
substrate: 'void', gradientMode: 'along-edge', vign: 0.55,
fields: {
cubic: F(0.0, 0.0, 0.05, 0.40, 0.45),
schlegel: F(0.0, 0.0, 0.05, 0.42, 0.40),
e8: F(0.0, 0.95, 0.95, 0.62, 0.98),
links: F(0.0, 0.95, 0.95, 0.70, 0.98), // bright rainbow connectors
},
},
},
{
name: '11_mauve-fog-custom', label: 'Bonus · custom mauve paper',
overrides: {
gradientMode: 'along-edge',
paperOverride: { flat: [82, 76, 92], glowIn: [108, 98, 118], glowOut: [58, 52, 70] },
vignOverride: [22, 18, 28],
featureOverride: [200, 190, 215],
fields: {
cubic: F(0.00, 0.95, 0.50, 0.72, 0.80),
schlegel: F(0.0, 0.0, 0.05, 0.85, 0.55),
e8: F(0.55, 0.85, 0.65, 0.72, 0.92),
links: F(0.55, 0.85, 0.85, 0.78, 0.95), // pastel cyan → violet
},
},
},
];
const base = paramsFromSeed(BASE_SEED);
for (const v of variations) {
const params = { ...base, ...v.overrides };
if (v.overrides.fields) params.fields = v.overrides.fields;
const svg = renderQFTSVG(generateQFTScene(params), params, SIZE);
const path = `${OUT_DIR}/${v.name}.svg`;
writeFileSync(path, svg);
console.log(`ok ${v.name} · ${v.label}`);
}
console.log(`\nrendered ${variations.length} variations → ${OUT_DIR}/`);