388 lines
15 KiB
JavaScript
388 lines
15 KiB
JavaScript
/* ============================================================
|
||
qft-variations-tangle.mjs — sketch 07.
|
||
Pursuing "chaotic interconnectedness" via:
|
||
- Cubic mesh FILLS the page (often bleeding past edges)
|
||
- Schlegel hypercube also taking much space
|
||
- Many bright Feynman cross-field links (8–14 per plate)
|
||
- NAUTILUS rosettes (open spirals with chambers growing
|
||
with radius) replacing closed concentric rings
|
||
- Per-field stroke weights for hierarchical emphasis
|
||
- Mid-tone substrates so brightness can work in BOTH
|
||
directions (lighter than bg AND darker)
|
||
Output → output/qft/sketch07/
|
||
============================================================ */
|
||
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/sketch07';
|
||
const SIZE = 1800;
|
||
mkdirSync(OUT_DIR, { recursive: true });
|
||
|
||
// Field config: hueStart, hueEnd, sat, light, opacity. Optional `stroke` per-field.
|
||
const F = (hueStart, hueEnd, saturation, lightness, opacity, stroke) => {
|
||
const f = { hueStart, hueEnd, saturation, lightness, opacity };
|
||
if (stroke != null) f.stroke = stroke;
|
||
return f;
|
||
};
|
||
const paper = (flat, glowInDelta = [16, 14, 12], glowOutDelta = [-22, -20, -18]) => ({
|
||
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: every plate has cubic+schlegel large, many links, nautilus rosettes
|
||
const BASE = {
|
||
cubicN: 1, // N=2 is too busy when cubic fills the page
|
||
photonCyclesPerUnit: 14,
|
||
segmentsPerEdge: 10,
|
||
linkCount: 11,
|
||
// nautilus defaults (used unless overridden)
|
||
e8Style: 'nautilus',
|
||
nautilusTurns: 2.6, nautilusPerTurn: 14, nautilusGrowth: 0.22,
|
||
};
|
||
|
||
const variations = [
|
||
{
|
||
name: '01_E3-evolved-nautilus',
|
||
label: 'E3 evolved · lavender-grey · twin nautilus + counter-rotated cubic',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([198, 198, 215]),
|
||
vignOverride: [60, 55, 75], featureOverride: [40, 40, 60],
|
||
cubicScale: 1.55, cubicRot: 0.80,
|
||
schlegelScale: 1.85, schlegelInnerR: 0.55, schlegelRot3D: -0.30,
|
||
schlegelOriginX: -0.10, schlegelOriginY: 0.10,
|
||
e8Origins: [{ x: 0.42, y: -0.42, scale: 0.55 },
|
||
{ x: -0.42, y: 0.42, scale: 0.55 }],
|
||
linkCount: 12,
|
||
fields: {
|
||
cubic: F(0.62, 0.70, 0.40, 0.50, 0.50, 1.1),
|
||
schlegel: F(0.62, 0.72, 0.60, 0.32, 0.82, 2.6), // schlegel thick
|
||
e8: F(0.65, 0.78, 0.65, 0.48, 0.88, 2.0),
|
||
links: F(0.05, 0.12, 0.85, 0.50, 0.92, 2.4), // bright warm links
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '02_single-huge-nautilus',
|
||
label: 'Single huge nautilus spiraling out · dense link web',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([175, 170, 185]), // dusty lavender-grey
|
||
vignOverride: [55, 50, 70], featureOverride: [40, 40, 55],
|
||
cubicScale: 1.50, schlegelScale: 1.20,
|
||
e8Origins: [{ x: 0, y: 0, scale: 0.95 }], // ONE huge spiral
|
||
nautilusTurns: 3.2, nautilusGrowth: 0.24,
|
||
linkCount: 14,
|
||
fields: {
|
||
cubic: F(0.58, 0.68, 0.40, 0.42, 0.45, 1.0),
|
||
schlegel: F(0.06, 0.13, 0.50, 0.40, 0.70, 1.8),
|
||
e8: F(0.08, 0.15, 0.85, 0.52, 0.92, 2.6), // saturated warm spiral
|
||
links: F(0.05, 0.15, 0.95, 0.55, 0.95, 2.6),
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '03_triangular-three-nautilus',
|
||
label: 'Three nautilus in a triangle · many crisscrossing links',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([185, 175, 160]), // warm tan-grey
|
||
vignOverride: [70, 55, 35], featureOverride: [50, 40, 25],
|
||
cubicScale: 1.60, schlegelScale: 1.30,
|
||
schlegelRot3D: 0.85,
|
||
e8Origins: [
|
||
{ x: 0.00, y: -0.40, scale: 0.40 },
|
||
{ x: -0.45, y: 0.35, scale: 0.40 },
|
||
{ x: 0.45, y: 0.35, scale: 0.40 },
|
||
],
|
||
linkCount: 14,
|
||
fields: {
|
||
cubic: F(0.04, 0.12, 0.45, 0.38, 0.50, 1.0),
|
||
schlegel: F(0.06, 0.14, 0.55, 0.32, 0.72, 1.6),
|
||
e8: F(0.05, 0.18, 0.80, 0.48, 0.90, 2.2),
|
||
links: F(0.95, 0.10, 0.95, 0.50, 0.95, 2.4), // hot pink → orange links
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '04_asymmetric-chaos',
|
||
label: 'Asymmetric · nautilus low-right · schlegel bleeding upper-left',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([170, 165, 175]), // cool grey-mauve
|
||
vignOverride: [60, 55, 70], featureOverride: [40, 40, 55],
|
||
cubicScale: 1.70, cubicOriginX: -0.10,
|
||
schlegelScale: 2.05, schlegelOriginX: -0.30, schlegelOriginY: -0.30,
|
||
schlegelInnerR: 0.40, schlegelRot3D: 0.65,
|
||
e8Origins: [{ x: 0.45, y: 0.40, scale: 0.55 },
|
||
{ x: 0.20, y: 0.55, scale: 0.30 }],
|
||
linkCount: 13,
|
||
fields: {
|
||
cubic: F(0.72, 0.85, 0.45, 0.40, 0.48, 0.9),
|
||
schlegel: F(0.74, 0.92, 0.55, 0.32, 0.78, 2.4),
|
||
e8: F(0.86, 0.98, 0.85, 0.50, 0.90, 2.2),
|
||
links: F(0.50, 0.12, 0.95, 0.55, 0.95, 2.6), // teal→amber crosslinks
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '05_warm-tangle-tan',
|
||
label: 'Warm tan-grey · dense cubic · many small nautilus · many links',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([188, 168, 145]),
|
||
vignOverride: [80, 55, 30], featureOverride: [60, 45, 25],
|
||
cubicScale: 1.60, schlegelScale: 0.95,
|
||
e8Origins: [
|
||
{ x: -0.50, y: -0.45, scale: 0.30 },
|
||
{ x: 0.45, y: -0.50, scale: 0.30 },
|
||
{ x: -0.40, y: 0.45, scale: 0.30 },
|
||
{ x: 0.50, y: 0.40, scale: 0.30 },
|
||
{ x: 0.00, y: 0.00, scale: 0.30 }, // 5 small nautilus
|
||
],
|
||
nautilusTurns: 2.0,
|
||
linkCount: 14,
|
||
fields: {
|
||
cubic: F(0.04, 0.12, 0.55, 0.35, 0.55, 1.0),
|
||
schlegel: F(0.04, 0.10, 0.50, 0.32, 0.68, 1.4),
|
||
e8: F(0.06, 0.14, 0.85, 0.52, 0.92, 2.2),
|
||
links: F(0.50, 0.10, 0.90, 0.55, 0.92, 2.4),
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '06_sage-with-bright-lighter',
|
||
label: 'Sage midtone · bright LIGHTER nautilus glowing above',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([155, 165, 145]), // sage midtone
|
||
vignOverride: [55, 70, 50], featureOverride: [235, 240, 225],
|
||
cubicScale: 1.55, schlegelScale: 1.40,
|
||
schlegelInnerR: 0.45, schlegelRot3D: 0.30,
|
||
e8Origins: [{ x: -0.30, y: -0.10, scale: 0.55 },
|
||
{ x: 0.30, y: 0.10, scale: 0.55 }],
|
||
linkCount: 11,
|
||
fields: {
|
||
cubic: F(0.42, 0.50, 0.40, 0.38, 0.55, 1.1),
|
||
schlegel: F(0.42, 0.48, 0.45, 0.32, 0.72, 1.8),
|
||
e8: F(0.38, 0.50, 0.30, 0.90, 0.88, 2.2), // pale-mint lighter than sage
|
||
links: F(0.38, 0.50, 0.45, 0.92, 0.92, 2.4),
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '07_deep-teal-luminous',
|
||
label: 'Deep teal · luminous nautilus + cubic glowing brighter',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([60, 95, 100]), // deep teal
|
||
vignOverride: [25, 45, 50], featureOverride: [195, 220, 220],
|
||
cubicScale: 1.55, schlegelScale: 1.35,
|
||
schlegelInnerR: 0.30, schlegelRot3D: 0.45,
|
||
e8Origins: [{ x: 0, y: 0, scale: 0.80 }],
|
||
linkCount: 13,
|
||
fields: {
|
||
cubic: F(0.50, 0.55, 0.35, 0.82, 0.62, 1.0), // pale cyan glowing
|
||
schlegel: F(0.48, 0.55, 0.30, 0.80, 0.65, 1.8),
|
||
e8: F(0.10, 0.20, 0.85, 0.65, 0.92, 2.4), // hot amber-gold spiral
|
||
links: F(0.10, 0.04, 0.95, 0.65, 0.95, 2.6), // bright orange links
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '08_bone-thick-white-nautilus',
|
||
label: 'Bone midtone · thick WHITE nautilus chain · dense links',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([185, 175, 160]),
|
||
vignOverride: [60, 50, 35], featureOverride: [55, 45, 30],
|
||
cubicScale: 1.50, schlegelScale: 1.40,
|
||
schlegelInnerR: 0.45, schlegelRot3D: 0.55,
|
||
e8Origins: [
|
||
{ x: -0.50, y: 0, scale: 0.40 },
|
||
{ x: 0.00, y: 0, scale: 0.40 },
|
||
{ x: 0.50, y: 0, scale: 0.40 },
|
||
],
|
||
nautilusTurns: 2.4,
|
||
linkCount: 12,
|
||
fields: {
|
||
cubic: F(0.08, 0.14, 0.35, 0.42, 0.45, 1.0),
|
||
schlegel: F(0.08, 0.14, 0.40, 0.38, 0.65, 1.6),
|
||
e8: F(0.0, 0.0, 0, 0.96, 0.95, 3.0), // pure white THICK nautilus
|
||
links: F(0.0, 0.0, 0, 0.96, 0.88, 2.6), // white connectors too
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '09_galaxies-all-same-direction',
|
||
label: 'Spiral galaxies · all nautilus winding the same way',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([170, 170, 195]), // dusty blue-violet
|
||
vignOverride: [50, 50, 70], featureOverride: [40, 40, 60],
|
||
cubicScale: 1.65, schlegelScale: 1.50,
|
||
schlegelInnerR: 0.40, schlegelRot3D: 0.20,
|
||
e8Origins: [
|
||
{ x: -0.45, y: -0.45, scale: 0.32 },
|
||
{ x: 0.45, y: -0.30, scale: 0.36 },
|
||
{ x: -0.30, y: 0.45, scale: 0.36 },
|
||
{ x: 0.50, y: 0.40, scale: 0.32 },
|
||
],
|
||
nautilusTurns: 3.0,
|
||
linkCount: 12,
|
||
fields: {
|
||
cubic: F(0.60, 0.70, 0.40, 0.42, 0.50, 1.0),
|
||
schlegel: F(0.62, 0.72, 0.50, 0.38, 0.65, 1.4),
|
||
e8: F(0.55, 0.80, 0.85, 0.55, 0.92, 2.4), // each nautilus its own hue
|
||
links: F(0.10, 0.18, 0.95, 0.55, 0.95, 2.4),
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '10_nested-nautilus-mandala',
|
||
label: 'Nested nautilus at three scales · cubic backdrop',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([180, 170, 175]), // dusky rose-grey
|
||
vignOverride: [70, 50, 55], featureOverride: [55, 35, 40],
|
||
cubicScale: 1.45, schlegelScale: 0.95,
|
||
e8Origins: [
|
||
{ x: 0, y: 0, scale: 0.95 },
|
||
{ x: 0, y: 0, scale: 0.55 },
|
||
{ x: 0, y: 0, scale: 0.25 },
|
||
],
|
||
nautilusTurns: 2.8,
|
||
linkCount: 10,
|
||
fields: {
|
||
cubic: F(0.92, 0.05, 0.45, 0.42, 0.45, 0.9),
|
||
schlegel: F(0.92, 0.05, 0.45, 0.40, 0.55, 1.4),
|
||
e8: F(0.94, 0.06, 0.85, 0.50, 0.88, 2.0),
|
||
links: F(0.85, 0.95, 0.90, 0.50, 0.92, 2.2),
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '11_windblown-biased',
|
||
label: 'Wind-blown · everything biased to the left · drift',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([175, 165, 145]),
|
||
vignOverride: [65, 50, 30], featureOverride: [55, 45, 30],
|
||
cubicScale: 1.55, cubicOriginX: -0.30,
|
||
schlegelScale: 1.60, schlegelOriginX: -0.25,
|
||
schlegelInnerR: 0.40, schlegelRot3D: 0.55,
|
||
compositionOffsetX: -0.10, // whole scene shifted left
|
||
e8Origins: [
|
||
{ x: -0.55, y: -0.25, scale: 0.42 },
|
||
{ x: -0.20, y: 0.35, scale: 0.36 },
|
||
],
|
||
linkCount: 11,
|
||
fields: {
|
||
cubic: F(0.06, 0.14, 0.50, 0.38, 0.50, 1.0),
|
||
schlegel: F(0.04, 0.12, 0.55, 0.35, 0.72, 1.8),
|
||
e8: F(0.08, 0.18, 0.85, 0.50, 0.92, 2.4),
|
||
links: F(0.95, 0.10, 0.95, 0.55, 0.95, 2.4),
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '12_linked-chain-across',
|
||
label: 'Linked chain · nautilus across the diagonal, very bright links',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([170, 175, 185]), // cool storm-grey
|
||
vignOverride: [50, 55, 70], featureOverride: [40, 45, 60],
|
||
cubicScale: 1.55, schlegelScale: 1.40,
|
||
schlegelInnerR: 0.42, schlegelRot3D: 0.40,
|
||
e8Origins: [
|
||
{ x: -0.55, y: -0.40, scale: 0.32 },
|
||
{ x: -0.18, y: -0.10, scale: 0.32 },
|
||
{ x: 0.18, y: 0.10, scale: 0.32 },
|
||
{ x: 0.55, y: 0.40, scale: 0.32 },
|
||
],
|
||
linkCount: 14,
|
||
fields: {
|
||
cubic: F(0.55, 0.65, 0.40, 0.42, 0.50, 1.0),
|
||
schlegel: F(0.56, 0.66, 0.50, 0.38, 0.70, 1.6),
|
||
e8: F(0.08, 0.18, 0.85, 0.55, 0.92, 2.4), // amber nautilus
|
||
links: F(0.06, 0.16, 0.95, 0.60, 0.98, 2.8), // brightest links of the set
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '13_spectral-radial-tangle',
|
||
label: 'Spectral radial · everything cycling through the spectrum',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([175, 170, 165]),
|
||
vignOverride: [60, 55, 50], featureOverride: [50, 45, 40],
|
||
gradientMode: 'radial',
|
||
cubicScale: 1.55, schlegelScale: 1.45,
|
||
schlegelInnerR: 0.40, schlegelRot3D: 0.40,
|
||
e8Origins: [{ x: -0.30, y: -0.30, scale: 0.40 },
|
||
{ x: 0.30, y: 0.30, scale: 0.40 }],
|
||
linkCount: 12,
|
||
fields: {
|
||
cubic: F(0.55, 0.05, 0.65, 0.42, 0.55, 1.0),
|
||
schlegel: F(0.55, 0.05, 0.55, 0.38, 0.70, 1.6),
|
||
e8: F(0.55, 0.05, 0.85, 0.50, 0.92, 2.2),
|
||
links: F(0.55, 0.05, 0.95, 0.55, 0.95, 2.6),
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '14_quiet-counterexample',
|
||
label: 'Quiet counter-example · single nautilus, fewer links · contemplative',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([195, 190, 185]),
|
||
vignOverride: [55, 50, 45], featureOverride: [55, 50, 45],
|
||
cubicScale: 1.40, schlegelScale: 1.20,
|
||
schlegelInnerR: 0.42, schlegelRot3D: 0.40,
|
||
e8Origins: [{ x: 0, y: 0, scale: 0.65 }],
|
||
linkCount: 5, // quiet
|
||
fields: {
|
||
cubic: F(0.60, 0.68, 0.30, 0.42, 0.40, 0.9),
|
||
schlegel: F(0.62, 0.70, 0.40, 0.40, 0.60, 1.4),
|
||
e8: F(0.06, 0.12, 0.65, 0.50, 0.85, 1.8),
|
||
links: F(0.06, 0.12, 0.70, 0.50, 0.80, 1.8),
|
||
},
|
||
},
|
||
},
|
||
{
|
||
name: '15_heavy-weight-contrast',
|
||
label: 'Weight contrast · thin cubic · THICK schlegel · medium nautilus',
|
||
overrides: {
|
||
...BASE,
|
||
paperOverride: paper([180, 170, 175]),
|
||
vignOverride: [55, 45, 50], featureOverride: [40, 35, 40],
|
||
cubicScale: 1.65, schlegelScale: 1.55,
|
||
schlegelInnerR: 0.32, schlegelRot3D: 0.60,
|
||
e8Origins: [{ x: -0.30, y: 0.10, scale: 0.42 },
|
||
{ x: 0.35, y: -0.15, scale: 0.42 }],
|
||
linkCount: 11,
|
||
fields: {
|
||
cubic: F(0.85, 0.95, 0.40, 0.45, 0.45, 0.6), // very thin
|
||
schlegel: F(0.05, 0.12, 0.55, 0.30, 0.85, 3.4), // very thick
|
||
e8: F(0.05, 0.15, 0.85, 0.55, 0.92, 2.0), // medium
|
||
links: F(0.50, 0.10, 0.95, 0.55, 0.95, 2.8), // thick links
|
||
},
|
||
},
|
||
},
|
||
];
|
||
|
||
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}`);
|
||
}
|
||
console.log(`\nrendered ${variations.length} variations → ${OUT_DIR}/`);
|