I wanted an ambient display for the second monitor in an open-space
office: something alive enough to rest the eyes on, quiet enough not
to distract, and installable nowhere — because the machine is a locked-
down corporate laptop. No pygame, no numpy, no GPU, no admin rights.
So the constraint became the project: real mathematics, rendered
with nothing but tkinter and math. One file. If you have Python,
you already have everything it needs.
Repo: https://github.com/RMANOV/algorithmic-arts
What's inside
Hopf fibration — the circles of S³, stereographically projected to
3D. Each fiber is a genuine circle on the 3-sphere:
(cos(η/2)·e^(it), sin(η/2)·e^(i(t+ξ))) as two complex coordinates,
projected from the pole. The nested tori emerge on their own — nothing
is drawn as a torus.
Three-body figure-8 — the Chenciner–Montgomery choreography with
real gravity, integrated with velocity Verlet from the classic initial
conditions. The GIF starts cold on purpose: watching the orbit weave
itself out of three moving points is the whole show.
Murmuration wars — three boid flocks in rock–paper–scissors
predation. Each flock hunts one neighbour and flees the other; a
caught bird converts to the hunter's colour in a burst ring, so the
armies grow and collapse in cycles.
Hyperbolic flow — a geodesic web in the Poincaré disk carried by a
live Möbius transformation. Geodesics are circles orthogonal to the
boundary: for boundary points u, v the center is (u+v)/(1+Re(u·v̄)) —
one line of algebra, an Escher engraving in motion.
Plus a morphing Clifford attractor, a swarm of 36 double pendulums
diverging from 10⁻⁵-radian differences, a rotating Klein bottle, and
torus knots smoothstep-morphing into one another.
The interesting engineering problem
The tkinter canvas is slow, and that was the fun part. Naively
updating ~1500 line items at 30 fps chokes on itemconfig calls —
coordinates are cheap, but style changes are not. Three tricks fixed
it:
- Pre-allocated item pool — line items are created once and reused; nothing is ever created or destroyed per frame.
-
Style caching — each pool slot remembers its (color, width);
itemconfigfires only on actual change. - Quantized HSV — hues snap to 1/48 steps, brightness to 1/20. Visually identical, but colors stabilize between frames, so most updates become coordinate-only. Frame cost dropped ~3×.
There is also a headless --selftest that runs every scene for 60
frames without a display and checks line budgets — so the physics can
be verified in CI or over SSH.
Why bother with stdlib-only?
Because constraints are the art. Every dependency you drop is a
machine the code can still run on: the locked-down office laptop, the
server with bare Python, the machine of someone who will never run
pip install. And because it forces the mathematics to carry the
show — there are no shaders to hide behind.
MIT licensed. If there's a scene you'd like added — the attractor and
polytope families are deep — tell me in the comments.




Top comments (0)