Files
bubblechambersimart/tools/qft-variations-fine.mjs

252 lines
9.6 KiB
JavaScript
Raw Normal View History

2026-05-29 15:40:42 -04:00
/* ============================================================
qft-variations-fine.mjs sketch 05.
Two new mechanics exercised:
(a) DENSER cubic mesh (cubicN=2 125 vertices / ~300 edges)
+ finer photon waves (photonCyclesPerUnit ) "even
finer oscillating sub-grid with each line another hue
in a gradient"
(b) LARGER softer rosettes E8 cluster scaled 0.550.85
with lightness pushed ABOVE the paper's lightness and
opacity dropped to 0.350.55 the rosette becomes a
soft luminous halo rather than a focal jewel.
Plus fewer / dimmer cross-field links so they punctuate
instead of dominate.
Output output/qft/sketch05/
============================================================ */
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/sketch05';
const SIZE = 1800;
mkdirSync(OUT_DIR, { recursive: true });
const F = (hueStart, hueEnd, saturation, lightness, opacity) =>
({ hueStart, hueEnd, saturation, lightness, opacity });
const paper = (flat, glowInDelta = [18, 16, 14], glowOutDelta = [-25, -22, -20]) => ({
flat,
glowIn: [flat[0] + glowInDelta[0], flat[1] + glowInDelta[1], flat[2] + glowInDelta[2]],
glowOut: [flat[0] + glowOutDelta[0], flat[1] + glowOutDelta[1], flat[2] + glowOutDelta[2]],
});
// shared base for the new sketches
// Dense cubic (300 edges) needs MUCH thinner strokes than sketch04, otherwise it
// piles into solid wallpaper and buries the soft rosettes. Stroke 1.0 + cubic
// opacity ~0.45 leaves room for the rosette + schlegel to read.
const FINE_BASE = {
cubicN: 2, // 5³=125 vertices / ~300 edges
photonCyclesPerUnit: 22, // finer waves than default (12)
segmentsPerEdge: 10,
linkCount: 5, // fewer cross-field links (was 8)
stroke: 1.0, // thin so the dense mesh stays atmospheric, not opaque
};
const variations = [
{
name: '01_spectral-comb-pearl',
label: 'Spectral comb · pearl · dense cubic + radial spectrum + soft rosette',
overrides: {
...FINE_BASE,
paperOverride: paper([240, 235, 230]),
vignOverride: [80, 70, 65], featureOverride: [80, 70, 60],
gradientMode: 'radial',
cubicScale: 1.40, schlegelScale: 0, // no schlegel — let cubic + rosette breathe
e8Origins: [{ x: 0, y: 0, scale: 0.72 }], // single large central rosette
fields: {
cubic: F(0.55, 0.04, 0.65, 0.45, 0.30), // cool centre → warm corners
schlegel: F(0, 0, 0, 0.5, 0), // off
e8: F(0.55, 0.08, 0.55, 0.48, 0.85), // very pale tinted-white halo (L > paper)
links: F(0.04, 0.10, 0.55, 0.45, 0.55), // dim warm links
},
},
},
{
name: '02_dense-radial-cream',
label: 'Dense radial spectrum · cream · large pale rosette',
overrides: {
...FINE_BASE,
substrate: 'cream',
gradientMode: 'radial',
cubicScale: 1.55, schlegelScale: 0.85,
e8Origins: [{ x: 0, y: 0, scale: 0.78 }],
fields: {
cubic: F(0.58, 0.05, 0.70, 0.40, 0.30),
schlegel: F(0.10, 0.05, 0.35, 0.45, 0.55),
e8: F(0.08, 0.04, 0.55, 0.48, 0.85), // pale warm halo on cream
links: F(0.05, 0.10, 0.60, 0.45, 0.55),
},
},
},
{
name: '03_linear-horizon-ivory',
label: 'Linear horizon · ivory · dense cubic with left→right gradient',
overrides: {
...FINE_BASE,
paperOverride: paper([232, 224, 202]),
vignOverride: [70, 55, 40], featureOverride: [60, 50, 35],
gradientMode: 'linear-x',
cubicScale: 1.65, schlegelScale: 0.90,
e8Origins: [{ x: -0.35, y: 0.25, scale: 0.55 },
{ x: 0.35, y: 0.25, scale: 0.55 }], // twin pale rosettes lower
fields: {
cubic: F(0.58, 0.04, 0.65, 0.36, 0.30),
schlegel: F(0.60, 0.08, 0.40, 0.40, 0.55),
e8: F(0.55, 0.10, 0.55, 0.48, 0.85),
links: F(0.06, 0.12, 0.60, 0.40, 0.55),
},
},
},
{
name: '04_twin-rosettes-mauve',
label: 'Twin overlapping rosettes · pale mauve · soft & atmospheric',
overrides: {
...FINE_BASE,
paperOverride: paper([222, 205, 224]),
vignOverride: [55, 35, 60], featureOverride: [75, 50, 90],
gradientMode: 'along-edge',
cubicScale: 1.45, schlegelScale: 0, // no schlegel
e8Origins: [{ x: -0.20, y: 0, scale: 0.65 },
{ x: 0.20, y: 0, scale: 0.65 }],
fields: {
cubic: F(0.72, 0.92, 0.55, 0.38, 0.30),
schlegel: F(0, 0, 0, 0.5, 0),
e8: F(0.78, 0.92, 0.55, 0.48, 0.85), // pale lighter-than-mauve glow
links: F(0.82, 0.95, 0.65, 0.40, 0.55),
},
},
},
{
name: '05_finest-waves-linen',
label: 'Finest photon waves · linen · super-dense cubic + soft halo',
overrides: {
...FINE_BASE,
paperOverride: paper([225, 210, 178]),
vignOverride: [85, 60, 35], featureOverride: [80, 55, 30],
photonCyclesPerUnit: 30, // even finer ripples than the FINE_BASE
cubicScale: 1.50, schlegelScale: 0.75,
e8Origins: [{ x: 0, y: 0, scale: 0.82 }],
fields: {
cubic: F(0.08, 0.14, 0.60, 0.35, 0.30),
schlegel: F(0.04, 0.10, 0.40, 0.35, 0.55),
e8: F(0.10, 0.06, 0.55, 0.48, 0.85),
links: F(0.06, 0.10, 0.60, 0.40, 0.55),
},
},
},
{
name: '06_big-mandala-pale-blue',
label: 'Big central mandala · pale blue · single huge rosette',
overrides: {
...FINE_BASE,
paperOverride: paper([190, 215, 230]),
vignOverride: [40, 55, 70], featureOverride: [30, 50, 75],
gradientMode: 'radial',
cubicScale: 1.50, schlegelScale: 0.80,
e8Origins: [{ x: 0, y: 0, scale: 0.92 }], // very large central rosette
fields: {
cubic: F(0.60, 0.66, 0.65, 0.25, 0.30),
schlegel: F(0.58, 0.62, 0.45, 0.28, 0.55),
e8: F(0.55, 0.65, 0.55, 0.48, 0.85), // near-white tinted-blue halo
links: F(0.58, 0.66, 0.65, 0.32, 0.55),
},
},
},
{
name: '07_dense-ghostly-schlegel-bone',
label: 'Dense cubic + ghostly large Schlegel · bone china',
overrides: {
...FINE_BASE,
paperOverride: paper([234, 230, 222]),
vignOverride: [80, 70, 60], featureOverride: [70, 60, 50],
gradientMode: 'radial',
cubicScale: 1.55, schlegelScale: 1.85, // big BUT...
e8Origins: [{ x: 0, y: 0, scale: 0.72 }],
fields: {
cubic: F(0.55, 0.05, 0.65, 0.38, 0.30),
schlegel: F(0.62, 0.10, 0.25, 0.92, 0.35), // ...made ghostly: pale + low opacity
e8: F(0.10, 0.06, 0.55, 0.48, 0.85),
links: F(0.06, 0.10, 0.55, 0.40, 0.50),
},
},
},
{
name: '08_atmospheric-mint',
label: 'Atmospheric · pale mint · large soft rosette dominant',
overrides: {
...FINE_BASE,
paperOverride: paper([210, 225, 208]),
vignOverride: [30, 55, 35], featureOverride: [40, 70, 45],
stroke: 1.6, // thinner — let the rosette breathe
cubicScale: 1.30, schlegelScale: 0,
e8Origins: [{ x: 0, y: 0, scale: 0.85 }],
fields: {
cubic: F(0.42, 0.50, 0.45, 0.36, 0.30),
schlegel: F(0, 0, 0, 0.5, 0),
e8: F(0.40, 0.50, 0.55, 0.48, 0.85),
links: F(0.12, 0.18, 0.55, 0.42, 0.55),
},
},
},
{
name: '09_all-dense-layered-pearl',
label: 'Everything dense and layered · pearl · 4 rosettes, full spectrum',
overrides: {
...FINE_BASE,
paperOverride: paper([240, 235, 230]),
vignOverride: [80, 70, 65], featureOverride: [80, 70, 60],
gradientMode: 'radial',
cubicScale: 1.60, schlegelScale: 1.20,
e8Origins: [
{ x: -0.30, y: -0.30, scale: 0.42 },
{ x: 0.30, y: -0.30, scale: 0.42 },
{ x: -0.30, y: 0.30, scale: 0.42 },
{ x: 0.30, y: 0.30, scale: 0.42 },
],
linkCount: 8,
fields: {
cubic: F(0.55, 0.05, 0.65, 0.40, 0.30),
schlegel: F(0.58, 0.10, 0.35, 0.42, 0.55),
e8: F(0.55, 0.08, 0.55, 0.48, 0.85),
links: F(0.06, 0.10, 0.55, 0.42, 0.55),
},
},
},
{
name: '10_concentric-rosettes-pale-rose',
label: 'Concentric nested rosettes · pale rose · all centred',
overrides: {
...FINE_BASE,
paperOverride: paper([232, 210, 210]),
vignOverride: [80, 55, 55], featureOverride: [90, 55, 55],
gradientMode: 'radial',
cubicScale: 1.30, schlegelScale: 0,
e8Origins: [
{ x: 0, y: 0, scale: 0.95 }, // outermost
{ x: 0, y: 0, scale: 0.62 }, // middle
{ x: 0, y: 0, scale: 0.30 }, // innermost
],
linkCount: 0, // no links — the nested rosettes are the picture
fields: {
cubic: F(0.95, 0.03, 0.55, 0.38, 0.30),
schlegel: F(0, 0, 0, 0.5, 0),
e8: F(0.92, 0.05, 0.55, 0.48, 0.85),
links: F(0.9, 0.05, 0.55, 0.42, 0.50),
},
},
},
];
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}/`);