spirographs

spirographs · sources · schema v1

SPIROGRAPHS — a classic-spirograph video GENERATOR (a pure synth SOURCE: no video input). It draws 1–3 INDEPENDENT spirograph curves — HYPOTROCHOIDS (the rolling circle rolls INSIDE the fixed one) or EPITROCHOIDS (OUTSIDE) — each with its OWN full parameter set + matching CV, each DRIFTING around the screen with its fixed circle bouncing off the frame edges like a real spirograph pinned to the page. THE CURVES (a pen at offset p in a rolling circle of radius r rolling on/in a fixed circle of radius R): hypotrochoid x=(R−r)cos t + p·cos(((R−r)/r)t), y=(R−r)sin t − p·sin(((R−r)/r)t); epitrochoid x=(R+r)cos t − p·cos(((R+r)/r)t), y=(R+r)sin t − p·sin(((R+r)/r)t). The parameter t sweeps over exactly enough revolutions to CLOSE the figure — derived from the reduced R:r ratio (revolutionsToClose = the denominator of R/r in lowest terms); irrational-ish ratios are CAPPED at a sane maximum so the curve dense-fills the annulus instead of running forever. COUNT (1..3, DISCRETE knob + CV) sets how many spiros render. Each spiro i∈{1,2,3} owns ten params (port/param id sI_<name>), EACH with a knob AND a CV input: fixedRadius (R), rollingRadius (r), penOffset (p), inside (0=epitrochoid/outside, 1=hypotrochoid/inside — a discrete toggle), rotation, scale, xOffset, yOffset, thickness (real px line-width), and chroma (a colorwheel HUE for that spiro). MOTION: each spiro's CENTER drifts on its OWN per-spiro velocity/phase (the three never move in lockstep); the FIXED-radius circle (R scaled to screen) is CONSTRAINED to stay fully inside the frame and rolls/BOUNCES (elastic reflection) off the perimeter when it hits an edge — only the fixed circle's center+R is bound-constrained (closed-form, deterministic), while the drawn CURVE may extend past the viewport and clip (desired). The reflect/bounce + the curve math live in the pure, unit-tested $lib/video/modules/spirographs-math. RENDERING: Canvas2D polylines (real line-width with round joins/caps) painted to an OffscreenCanvas and uploaded as a GL texture each frame (the SHAPEGEN/TEXTMARQUEE path) — the right tool for thick stroked curves, where a GLSL distance-field would be costlier and read worse. OUTPUTS (all video): out (video) — the full-COLOUR composite, each spiro in its chroma hue additively blended on black so crossings glow; mono_out (mono-video) — every spiro stroked WHITE on black, a clean matte for keying / luma effects (reachable via read('outputTexture:mono_out')); overlap (video, labelled CANDY) — a COLOUR-OVERLAP output: the per-pixel overlap DENSITY (how many lines stack there — self-crossings AND multiple spiros) is colour-mapped into a rainbow that CASCADES with the count (deep cool hue for one line, racing through green→yellow→red→magenta as lines pile up) and blooms toward a white candy core where many overlap — gooey "candy" goodness (reachable via read('outputTexture:overlap')). CARD: a live preview of the colour OUT, the COUNT knob, a 1/2/3 SPIRO SELECTOR that swaps the knob bank to that spiro, an INSIDE/OUTSIDE toggle, a CHROMA colorwheel, and the per-spiro fader bank. All ports live on the yellow drill-down PATCH PANEL (no raw side jacks); the drill-down GROUPS the CV inputs per-spiro (a count section + spiro1 / spiro2 / spiro3 sections). USAGE: dial COUNT, pick a spiro tab, tune R/r/pen for the figure (low gcd ratios make few-lobed flowers, coprime ratios dense rosettes), set INSIDE/OUTSIDE + chroma, then patch out → OUTPUT / a video mixer / an effect — or modulate any per-spiro param from an LFO/sequencer for an animated, drifting spirograph.

A pure video source (no input) that renders 1-3 independent classic spirographs and uploads them to the GPU each frame. Each spiro is a trochoid traced by a pen at offset p inside a rolling circle of radius r that rolls without slipping on a fixed circle of radius R: inside=hypotrochoid (rolling circle inside the fixed one), outside=epitrochoid (rolling circle outside it). The R:r ratio sets how many petals/loops the figure makes and how many revolutions it takes to close (a rational ratio closes; a near-irrational one densely fills the annulus, capped at a sane max). Each spiro has its own full parameter bank (R, r, pen, in/out, rotation, scale, X/Y, thickness, hue) and its own center that drifts independently across the frame, with the fixed-radius circle bouncing elastically off the four edges (only the fixed circle is kept fully in-frame; the drawn curve may overflow and clip, which is intended). The COLOR out composites each curve in its hue additively (lighter blend) on black so crossings glow toward white; switch its output port to get a white-on-black matte or a density-mapped rainbow "candy" overlap instead. Usage: pick a count, then use the per-spiro tabs to dial each figure (try a 5:2 inside spiro for a 5-petal star), and feed an LFO into a rotation or scale CV for slow living motion.

the faceplate

spirographsoutvideomono_outmono-videooverlapvideoaudiocvgatepitch
0 inputs · 3 outputs · 0 params

outputs

idcablewhat it does
outvideoCOLOR: the canonical full-color composite, each spiro stroked in its hue and additively blended (lighter) on black so overlaps glow toward white.
RGB video stream
mono_outmono-videoMONO: every spiro stroked white on black, a clean matte for keying or luma effects downstream.
mono video stream
overlapvideoCANDY: the per-pixel line-stack density mapped to a cascading rainbow that blooms to a white core where many lines pile up (hue-independent: driven by density, not the chroma controls).
RGB video stream

controls

controlwhat it does
CountCount (1-3, discrete): how many of the three spiros render. Independent of which tab you are editing.
S1 RSpiro 1 Fixed (R, 1-12): the fixed outer circle radius; with Roll it sets the petal/loop ratio.
S1 chromaSpiro 1 Hue (0-1 colorwheel): the curve's color in the COLOR output (MONO and CANDY ignore it).
S1 insideSpiro 1 In/Out toggle: INSIDE = hypotrochoid (rolling circle inside), OUTSIDE = epitrochoid (rolling circle outside).
S1 pSpiro 1 Pen (p, 0-8): pen offset in the rolling circle; 0 traces a plain circle, larger makes deeper loops.
S1 rSpiro 1 Roll (r, 0.5-11): the rolling circle radius; the R:r ratio defines the figure and revolutions to close.
S1 rotationSpiro 1 Rot (0-2pi radians): static rotation of the whole figure about its center.
S1 scaleSpiro 1 Scale (4-60): zoom from spiro-space units to pixels; with R it also sets the fixed circle's bounce inset.
S1 thicknessSpiro 1 Width (0.5-12 px): stroke line width, drawn with round joins and caps.
S1 xOffsetSpiro 1 X (-1..1): nudges the drift home position horizontally (center still drifts and bounces).
S1 yOffsetSpiro 1 Y (-1..1): nudges the drift home position vertically (center still drifts and bounces).
S2 RSpiro 2 Fixed (R, 1-12): the fixed outer circle radius; with Roll it sets the petal/loop ratio.
S2 chromaSpiro 2 Hue (0-1 colorwheel): the curve's color in the COLOR output (MONO and CANDY ignore it).
S2 insideSpiro 2 In/Out toggle: INSIDE = hypotrochoid (rolling circle inside), OUTSIDE = epitrochoid (rolling circle outside).
S2 pSpiro 2 Pen (p, 0-8): pen offset in the rolling circle; 0 traces a plain circle, larger makes deeper loops.
S2 rSpiro 2 Roll (r, 0.5-11): the rolling circle radius; the R:r ratio defines the figure and revolutions to close.
S2 rotationSpiro 2 Rot (0-2pi radians): static rotation of the whole figure about its center.
S2 scaleSpiro 2 Scale (4-60): zoom from spiro-space units to pixels; with R it also sets the fixed circle's bounce inset.
S2 thicknessSpiro 2 Width (0.5-12 px): stroke line width, drawn with round joins and caps.
S2 xOffsetSpiro 2 X (-1..1): nudges the drift home position horizontally (center still drifts and bounces).
S2 yOffsetSpiro 2 Y (-1..1): nudges the drift home position vertically (center still drifts and bounces).
S3 RSpiro 3 Fixed (R, 1-12): the fixed outer circle radius; with Roll it sets the petal/loop ratio.
S3 chromaSpiro 3 Hue (0-1 colorwheel): the curve's color in the COLOR output (MONO and CANDY ignore it).
S3 insideSpiro 3 In/Out toggle: INSIDE = hypotrochoid (rolling circle inside), OUTSIDE = epitrochoid (rolling circle outside).
S3 pSpiro 3 Pen (p, 0-8): pen offset in the rolling circle; 0 traces a plain circle, larger makes deeper loops.
S3 rSpiro 3 Roll (r, 0.5-11): the rolling circle radius; the R:r ratio defines the figure and revolutions to close.
S3 rotationSpiro 3 Rot (0-2pi radians): static rotation of the whole figure about its center.
S3 scaleSpiro 3 Scale (4-60): zoom from spiro-space units to pixels; with R it also sets the fixed circle's bounce inset.
S3 thicknessSpiro 3 Width (0.5-12 px): stroke line width, drawn with round joins and caps.
S3 xOffsetSpiro 3 X (-1..1): nudges the drift home position horizontally (center still drifts and bounces).
S3 yOffsetSpiro 3 Y (-1..1): nudges the drift home position vertically (center still drifts and bounces).

source

spirographs.ts on GitHub.

Generated from packages/web/src/lib/{audio,video}/module-registry.ts · repo