Cosmic Geometry: Rendering a Sacred Harmonograph in py5
2026/7/26
“Sacred Harmonograph Mandala 3D” is a generative media art piece that visualizes the elegant intersection of mathematics, physics, and spiritual geometry. A physical harmonograph is a mechanical device that uses swinging pendulums to draw complex geometric images, known as Lissajous curves. By translating this analog concept into a 3D digital simulation using Python and the py5 library, the artwork constructs a high-frequency cosmic mandala. Composed of 150 overlapping, phase-shifted curves that breathe and rotate in a deep void, the piece serves as a mesmerizing study of perfect, cyclic mathematical harmony.
Visual & Aesthetic Approach
The visual aesthetic of “Sacred Harmonograph Mandala 3D” is simultaneously ancient and deeply futuristic. The background of the piece is a rich, nearly black void of deep purple, creating a sense of infinite, empty space. In the center of this void floats the mandala itself, a massive, spherical web of light.
Instead of solid geometry, the structure is constructed entirely from 150 separate, incredibly thin, brightly glowing lines. Because the drawing context utilizes additive blending (py5.blend_mode(py5.ADD)), the lines burn with intense brightness where their paths cross and overlap, creating dense nodes of energy within the broader geometric structure. The color palette spans from a deep, resonant gold at the center to a piercing electric cyan at the outer edges. As the entire 3D structure slowly rotates on its axes, the individual curves expand and contract, simulating a living, breathing digital organism that remains perfectly bound by its mathematical constraints.
Code & Technical Breakdown
To construct a shape this complex, the code must calculate the exact $X$, $Y$, and $Z$ coordinates of thousands of vertices using parametric trigonometric equations.
# From draw()
# Global time phase for a perfect 10-second loop
t_phase = (py5.frame_count / TOTAL_FRAMES) * py5.TWO_PI
num_curves = 150
resolution = 400
for i in range(num_curves):
# Color mapping: Gold (40) to Electric Cyan (180)
hue = py5.remap(i, 0, num_curves, 40, 180)
py5.stroke(hue, 90, 80, 70)Why this works: The setup is heavily parameterized. t_phase normalizes the current frame count against the total number of frames in the 10-second animation, scaling it to exactly $2\pi$. This guarantees that at the end of the animation, all mathematical functions driven by t_phase will perfectly return to their starting positions, ensuring a seamless, infinite loop. The main loop runs 150 times, drawing one complete parametric curve per iteration. The hue is smoothly remapped from gold (40) to cyan (180) based on the curve’s index, providing the striking color gradient that defines the artwork’s aesthetic.
The true magic of the piece lies in the complex trigonometric equations used to calculate the vertices of each curve.
# From draw()
py5.begin_shape()
for j in range(resolution):
# Parametric path from 0 to 8*PI (4 loops)
angle = py5.remap(j, 0, resolution - 1, 0, py5.TWO_PI * 4)
# Frequencies
wx = 3
wy = 5
wz = 7
# Modulate phase with curve index and global time to animate
px = (i * 0.05) + t_phase
py = (i * 0.08) - t_phase * 2
pz = (i * 0.03) + t_phase * 1.5Why this works: Inside the begin_shape() block, a second loop runs 400 times (the resolution). The angle variable acts as the primary parameter driving the curve forward, completing 4 full rotations ($8\pi$) to ensure the curve crosses back over itself. The frequencies (wx=3, wy=5, wz=7) are carefully chosen integers; mathematically, plotting sine waves with these interacting frequencies generates the classic, looping Lissajous knot structure. Crucially, the phase offsets (px, py, pz) are modified not just by the curve’s index (i), but also by the global t_phase. This is what causes the static curves to physically squirm and breathe throughout the animation.
Finally, the equations are evaluated and pushed to the renderer.
# From draw()
# 3D Lissajous curve with an outer envelope
envelope = 450 + 150 * np.sin(2 * angle + t_phase)
x = envelope * np.sin(wx * angle + px)
y = envelope * np.sin(wy * angle + py)
z = envelope * np.sin(wz * angle + pz)
# Add some inner geometric spirograph complexity
x += 100 * np.cos(11 * angle - t_phase)
y += 100 * np.sin(11 * angle + t_phase)
z += 100 * np.cos(13 * angle)
py5.curve_vertex(x, y, z)
py5.end_shape()Why this works: Rather than rendering a standard, uniform Lissajous knot, the code applies an envelope — a secondary sine wave that pulses the overall radius of the curve. This gives the mandala its flower-like, lobed shape. Furthermore, secondary, higher-frequency waves (11*angle, 13*angle) are added to the primary coordinates. These act as high-frequency noise, adding tight, microscopic loops to the broad, sweeping curves, mimicking the complex mechanics of a physical spirograph. Using py5.curve_vertex() ensures that py5 connects these calculated points with perfectly smooth, continuous bezier curves, rather than harsh, jagged straight lines.

Conclusion
“Sacred Harmonograph Mandala 3D” proves that the most beautiful structures are often born from rigid, unbreakable mathematical rules. By translating the analog mechanics of a physical harmonograph into a digital 3D space, the artwork is able to break the limits of gravity and friction, generating an impossible, glowing knot of pure frequency. Through Python and py5, the simulation creates a digital mandala — a perfect, infinitely looping meditation on the profound aesthetic beauty of trigonometry.
GitHub: https://github.com/asamiile/py5-media-art/tree/main/sketch/sacred_harmonograph_mandala_3d
Purchase assets: Adobe Stock