openprocessing_p5js · KaleidoscopeMirror
Kaleidoscope Mirror Mandala
Draws a single wandering line and reflects it across N rotational mirrors around the canvas centre. The construction: translate(cx, cy), then for each k in 0..N-1: rotate(2π/N), scale(1, -1), draw line. The result is a real-time mandala whose symmetry group is D_N (the dihedral group of order 2N).
Original: https://p5js.org/examples/repetition-kaleidoscope/
▶ Try the live demo (JS port) ▶ Run reference.py via Pyodide 10 formulas have instant JS ports. The Pyodide path runs the actual Python in your browser — first load is ~6 MB, then instant.
Math essence
For each sector k: angle phi = k * 2π/N; rotate then mirror y: (x', y') = (cos(phi)*x - sin(phi)*y, -(sin(phi)*x + cos(phi)*y)). Inner line is a Bezier-like rosette origin + length L with theta(t) = 0.20*t + 0.10*sin(0.013*t).
Parameters
| Name | Type | Default | Range | Description |
|---|---|---|---|---|
dim | int | 512 | 200–1200 | Square canvas side length. |
n_sectors | int | 12 | 3–36 | Mirror sectors N (symmetry group D_N). |
line_length | float | 220 | 20–600 | Inner line length in pixels. |
angular_speed | float | 0.1 | 0–1 | Reserved (currently fixed in trajectory). |
hue_shift | float | 0.004 | 0–0.05 | Per-tick hue rotation of the palette. |
bg_color | tuple | 10,8,24 | — | Background canvas color. |
seed | int | null | 0–999999 |
Reference
First 60 lines of reference.py. Full source:
library_external/openprocessing_p5js/KaleidoscopeMirror/reference.py
from __future__ import annotations
from typing import ClassVar
import numpy as np
class KaleidoscopeMirror:
"""Kaleidoscope / mandala: draw a single wandering line and reflect it
across N rotational mirrors around the canvas centre.
This is the canonical *p5.js* "Repetition / Kaleidoscope" example
(<https://p5js.org/examples/repetition-kaleidoscope/>) and the source of
countless OpenProcessing mandalas. The construction is:
push(); translate(cx, cy);
for k in 0..N-1:
rotate(2π/N); push(); scale(1, -1); line(...); pop();
pop();
Where ``scale(1, -1)`` performs the mirror, ``rotate(2π/N)`` rotates the
mirrored copy into the next of ``N`` identical sectors, and the inner
line segment is drawn procedurally (here: a wandering Bezier-like
trajectory). The result is a real-time mandala whose symmetry group is
D_N (the dihedral group of order 2N).
step(n) advances the inner trajectory by n ticks; render() returns the
accumulated canvas.
"""
family: ClassVar[str] = "openprocessing_p5js"
sketch: ClassVar[str] = "kaleidoscopeMirror"
def __init__(
self,
dim: int = 512,
n_sectors: int = 12,
line_length: float = 220.0,
angular_speed: float = 0.10,
hue_shift: float = 0.004,
bg_color: tuple[int, int, int] = (10, 8, 24),
seed: int | None = None,
) -> None:
self.dim = dim
self.n_sectors = n_sectors
self.line_length = line_length
self.angular_speed = angular_speed
self.hue_shift = hue_shift
self.bg_color = np.array(bg_color, dtype=np.float32)
self._seed = seed
self.reset()
def reset(self, seed: int | None = None) -> None:
if seed is not None:
self._seed = seed
self.rng = np.random.default_rng(self._seed)
self.canvas = np.tile(self.bg_color, (self.dim, self.dim, 1))
self._tick = 0
self._t = 0.0
self._hue = float(self.rng.uniform(0.0, 1.0)) Try running it locally
The reference implementation is self-contained Python with numpy. Install the package and run:
python library_external/openprocessing_p5js/KaleidoscopeMirror/reference.py Need help? See Learn for the standard environment setup, or Playground for an in-browser sketchbook.
More from openprocessing · p5.js
Additive Synthesis Waveform Visualisation
openprocessing_p5js · SoundWaveform
Visualisation of additive synthesis: y(t) = A * sum_{i=0..N-1} a_i * sin(2π f_i t + phi_i).
Inverse-distance Attractor Network
openprocessing_p5js · AttractorNetwork
A population of point-agents, each carrying a position and a velocity, mutually attracted by an inverse-distance force F = G / max(d, d_min)^alpha along the displacement vector.
Mathematical Rose (Rhodonea) Patterns
openprocessing_p5js · PolarCurves
Overlay of multiple rose (rhodonea) curves in the canonical polar form r = a * cos((n/d) * theta + phase), parametrised by the rational multiplier k = n/d.
Poincaré Disk Hyperbolic Tessellation
openprocessing_p5js · HyperbolicTiling
Escher-style regular hyperbolic tessellation in the Poincaré disk.
Tron Lightcycle Trails
openprocessing_p5js · TronLightcycle
Tron-style lightcycle trails.