A terminal-based 3D ASCII rendering of the Lorenz attractor — the famous "butterfly" of chaos theory — written in C.
This program numerically integrates the three Lorenz differential equations in real time and renders the trajectory as a fading ASCII trail with a slowly orbiting camera.
The result is a chaotic dance that never repeats, drawn entirely with text characters.
This project focuses on learning:
- numerical integration (4th-order Runge-Kutta)
- ordinary differential equations
- chaos theory and strange attractors
- 3D projection math
- camera rotation
- depth-aware ASCII shading
- circular buffers / trails
- low-level rendering concepts in C
- Real-time RK4 integration of the Lorenz system
- 3D trail of recent points
- Orbiting camera (rotates around the attractor)
- Brightness fades from old (dim) to new (bright)
- ASCII shading
- Pure terminal rendering
- Written entirely in C
- Standard libraries only
The Lorenz system is three coupled ODEs:
dx/dt = sigma * (y - x)
dy/dt = x * (rho - z) - y
dz/dt = x * y - beta * z
With the classic parameters sigma = 10, rho = 28, beta = 8/3, the system never settles — it loops chaotically around two unstable equilibria, drawing out the iconic butterfly shape.
For every frame:
- Advance the simulation a few RK4 steps
- Push new points onto a circular trail buffer
- Clear the frame and Z-buffer
- Iterate the trail from oldest to newest
- Apply camera rotation and 3D perspective projection
- Map age to ASCII brightness
- Draw the frame to the terminal
The animation repeats forever — and because the system is chaotic, no two seconds look exactly the same.
Edward Lorenz, 1963 — a simplified model of atmospheric convection that turned out to be one of the first examples of deterministic chaos.
dx/dt = sigma * (y - x)
dy/dt = x * (rho - z) - y
dz/dt = x * y - beta * z
Euler's method drifts and looks ugly. RK4 evaluates the derivative four times per step and averages them, giving fourth-order accuracy:
k1 = f(state)
k2 = f(state + h/2 * k1)
k3 = f(state + h/2 * k2)
k4 = f(state + h * k3)
state += h/6 * (k1 + 2 k2 + 2 k3 + k4)
This keeps the trajectory on the true attractor for thousands of steps.
A circular buffer holds the last N points:
float tx[TRAIL], ty[TRAIL], tz[TRAIL];
int head, count;
New points overwrite the oldest. This gives the attractor its "comet tail" look.
Two slowly-incremented angles A and B rotate the entire scene each frame:
A += 0.003; // tilt
B += 0.012; // orbit
Trigonometric functions rotate every trail point before projection.
Perspective projection converts 3D points into terminal coordinates:
ooz = 1 / (z + CAM_Z);
xp = WIDTH/2 + 80 * ooz * x;
yp = HEIGHT/2 - 40 * ooz * y;
The 1 / z factor creates the illusion of depth.
Each trail point's brightness depends on its age:
age = i / count; // 0 = oldest, 1 = newest
char c = shades[age * 9];
Brightness ramp:
" .,:;+*#%@"
Newest points are @, oldest fade into space.
The frame is drawn using:
putchar()
and terminal cursor reset escape sequences:
printf("\x1b[H");
This redraws frames in-place to create animation.
Compile using:
gcc lorenz.c -o lorenz -lm
Or just:
make
The -lm flag links the math library.
./lorenz
Press Ctrl+C to exit.
Edit the parameter constants at the top of lorenz.c:
static const float SIGMA = 10.0f;
static const float RHO = 28.0f;
static const float BETA = 8.0f / 3.0f;
Try:
RHO = 14-> the system settles into a stable point (no chaos)RHO = 99.96-> a different chaotic regime with period-doublingBETA = 4-> deformed butterfly- different initial conditions reveal sensitive dependence on starting state
.,:;;+++**
.,:;+++*****####
.,:++*****########%%
.,;+****#########%%%%@@
.;+****########%%%%@@@@
.;+****########%%%%@@@
.;+****#######%%%%@@
.,:;+++*****####
..,,,:;;+
(The actual attractor rotates and traces continuously in the terminal.)
- Numerical integration (RK4)
- Ordinary differential equations
- Chaos theory / strange attractors
- 3D coordinate systems
- Perspective projection
- Rotation matrices
- Circular buffers
- ASCII rendering
- Frame buffering
- Animation loops
- Terminal graphics
- Real-time simulation
Standard C libraries only:
stdio.hmath.hstring.hunistd.h
No graphics engine required.
Discovered by meteorologist Edward Lorenz in 1963, the Lorenz attractor was one of the first concrete examples of deterministic chaos: a system whose long-term behavior is completely unpredictable even though its rules are perfectly simple.
A small change in initial conditions — a butterfly flapping its wings — and the trajectory diverges into a completely different future.