nullprogram.com/blog/2020/06/29/
Ever since I worked out how to render video from scratch some
years ago, it’s been an indispensable tool in my software development
toolbelt. It’s the first place I reach when I need to display some
graphics, even if it means having to do the rendering myself. I’ve used
it often in throwaway projects in a disposable sort of way. More
recently, though, I’ve kept better track of these animations since some
of them are pretty cool, and I’d like to look a them again. This post
is a showcase of some of these projects.
Each project is in a ready-to-run state of compile, then run with the
output piped into a media player or video encoding. The header includes
the exactly commands you need. Since that’s probably inconvenient for
most readers, I’ve included a pre-recorded sample of each. Though in a
few cases, especially those displaying random data, video encoding
really takes something away from the final result, and it may be worth
running yourself.
The projects are not in any particular order.
RANDU
Source: randu.c
This is a little demonstration of the poor quality of the RANDU
pseudorandom number generator. Note how the source embeds a
monospace font so that it can render the text in the corner. For the 3D
effect, it includes an orthographic projection function. This function
will appear again later since I tend to cannibalize my own projects.
Color sorting
Source: colorsort.c
The original idea came from an old reddit post.
Kruskal maze generator
Source: animaze.c
This effect was invented by my current mentee student while
working on maze / dungeon generation late last year. This particular
animation is my own implementation. It outputs Netpbm by default, but,
for both fun and practice, also includes an entire implementation in
OpenGL. It’s enabled at compile time with -DENABLE_GL
so long
as you have GLFW and GLEW (even on Windows!).
Sliding rooks puzzle
Source: rooks.c
I wanted to watch an animated solution to the sliding rooks
puzzle. This program solves the puzzle using a bitboard, then
animates the solution. The rook images are embedded in the program,
compressed using a custom run-length encoding (RLE) scheme with a tiny
palette.
Glauber’s dynamics
Source: magnet.c
My own animation of Glauber’s dynamics using a totally
unoriginal color palette.
Fire
Source: fire.c
This is the classic Doom fire animation. I later implemented it
in WebGL with a modified algorithm.
Mersenne Twister
Source: mtvisualize.c
A visualization of the Mersenne Twister pseudorandom number generator.
Not terribly interesting, so I almost didn’t include it.
Pixel sorting
Source: pixelsort.c
Another animation inspired by a reddit post. Starting from
the top-left corner, swap the current pixel to the one most like its
neighbors.
Random walk (2D)
Source: walkers.c
Another reproduction of a reddit post. This is recent enough
that I’m using a disposable LCG.
Manhattan distance Voronoi diagram
Source: voronoi.c
Another reddit post, though I think my version looks a lot
nicer. I like to play this one over and over on repeat with different
seeds.
Random walk (3D)
Source: walk3d.c
Another stolen idea personal take on a reddit post. This
features the orthographic projection function from the RANDU animation.
Video encoding makes a real mess of this one, and I couldn’t work out
encoding options to make it look nice, so this one looks a lot better
“in person.”
Lorenz system
Source: lorenz.c
A 3D animation I adapted from the 3D random walk above, meaning it uses
the same orthographic projection. I have a WebGL version of this
one, but I like that I could do this in such a small
amount of code and without an existing rendering engine. Like before,
this is really damaged by video encoding and is best seen live.
Bonus: I made an obfuscated version just to show how
small this can get!