Generator - Depth & exposure dynamics: per-track chamber depth (z) + event age drive opacity, bubble size and defocus (depthFactors); depth/aging dials. - Palette abstraction (src/render/palette.js) — one registry entry per "feel": mono, charge, beta, kind, kindlife, kindrise, lifecycle, psychedelic, cyanotype, magentarise. Per-track ink + per-bubble bubbleInk hooks. - Global colour controls: saturation, hue shift; paper toning (cream/sepia/ selenium/cool/olive/neutral + brightness + gas-glow), bubble edge softness, iridescent disk (spectral sunburst), chromatic halo. Ink blend chosen by ground luminance so light-on-dark chemistries composite correctly. - Tracks carry charge q; bubbles carry lifecycle position + local beta. - All effects in raster + layered SVG + CMYK/OCG PDF; B&W remains the default. Tooling & art - tools/find-semicircle.mjs; render-svg/pdf --seed mode + k=v overrides. - Curated vector SVG sets under output/ with browsable index.html. Repo hygiene - .gitignore: stop tracking generated rasters/PDFs (reproducible from seeds), the reference image, and a stray db; keep curated SVGs + code + docs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
39 lines
2.1 KiB
JavaScript
39 lines
2.1 KiB
JavaScript
/* Scan random seeds for the "semicircle" look: a shock disk sitting LOW (so its
|
|
striated sunburst fans up like a rising half-disc), prominent + striated, with
|
|
abundant δ-ray curls. Pure paramsFromSeed scoring — no rendering.
|
|
Usage: node tools/find-semicircle.mjs [count] [topN] */
|
|
import { paramsFromSeed, archetypeOf } from '../src/scene/params.js';
|
|
|
|
const WORDS = ['MUON', 'KAON', 'PION', 'LAMBDA', 'SIGMA', 'XI', 'OMEGA', 'TAU', 'GLUON', 'QUARK',
|
|
'HADRON', 'BARYON', 'LEPTON', 'NEUTRINO', 'BOSON', 'STRANGE', 'CHARM', 'HYPERON', 'ANTIPROTON',
|
|
'POSITRON', 'MESON', 'FERMION', 'NUCLEON', 'ISOSPIN', 'CASCADE', 'RESONANCE', 'PARITY', 'GLUEBALL',
|
|
'PENTAQUARK', 'PHOTON', 'AXION', 'TACHYON', 'NEUTRON', 'PROTON', 'DELTA', 'UPSILON', 'BORON'];
|
|
|
|
const N = +(process.argv[2] || 6000);
|
|
const TOP = +(process.argv[3] || 16);
|
|
const rows = [];
|
|
for (let i = 0; i < N; i++) {
|
|
const seed = WORDS[(Math.random() * WORDS.length) | 0] + '-' + ((Math.random() * 9000) | 0 + 1000);
|
|
const p = paramsFromSeed(seed);
|
|
if (!p.shock || p.shockIntensity <= 0) continue;
|
|
// want: disk low (shockY high), prominent, well-striated, decent size, lots of curls
|
|
if (p.shockY < 0.5) continue;
|
|
const score =
|
|
(p.shockY - 0.5) * 6 + // lower disk → stronger half-disc
|
|
p.shockIntensity * 1.4 +
|
|
p.shockStriations * 1.6 +
|
|
p.shockSize * 2 +
|
|
p.deltaRate * 1.2 + // abundant curls
|
|
p.burst * 0.6;
|
|
rows.push({ seed, score, arch: archetypeOf(seed), y: p.shockY, I: p.shockIntensity, str: p.shockStriations, sz: p.shockSize, d: p.deltaRate, inv: p.invert });
|
|
}
|
|
rows.sort((a, b) => b.score - a.score);
|
|
// de-dup seeds, keep variety of archetypes
|
|
const seen = new Set(); const out = [];
|
|
for (const r of rows) { if (seen.has(r.seed)) continue; seen.add(r.seed); out.push(r); if (out.length >= TOP) break; }
|
|
console.log('seed'.padEnd(18), 'score arch shockY int striae size delta inv');
|
|
for (const r of out) {
|
|
console.log(r.seed.padEnd(18), r.score.toFixed(2), r.arch.padEnd(9),
|
|
r.y.toFixed(2), ' ', r.I.toFixed(2), ' ', r.str.toFixed(2), ' ', r.sz.toFixed(2), ' ', r.d.toFixed(2), ' ', r.inv);
|
|
}
|