Files
bubblechambersimart/tools/find-semicircle.mjs
noisedestroyers 7d6d5c232e Colour palettes, depth/exposure, disk & halo effects; stop tracking rasters
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>
2026-05-21 15:55:03 -04:00

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);
}