Daniel Shiffman has been making YouTube movies for some time now. His videos focus on programming and include coding challenges in which he writes code for a target idea from scratch. If you are a coder I recommend Dan’s videos for entertainment and inspiration.
His latest live stream focused on Fractal Spirographs.
If you prefer to watch a shorter edited version, here it is.
He was inspired by the following image from the Benice Equation blog.
Fractal Spirographs (aka Fractal Routlette) are generated by tracking a series (or chain) of circles rotating around each other as shown in the above gif animation. You track the chain of 10 or so circles and plot the path the final smallest circle takes. Changing the number of circles, the size ratio between circles, the speed of angle change, and the constant “k” changes the resulting plots and images.
How I Coded It
As I watched Daniel’s video I coded my own version. For my code (Delphi/pascal) I used a dynamic array of records to hold the details of each circle/orbit. This seemed the simplest approach to me for keeping track of a list of the linked circles.
type orbit=record x,y:double; radius:double; angle:double; speed:double; end;
Before the main loop you fill the array;
//parent orbit orbits.x:=destimage.width/2; orbits.y:=min(destimage.width,destimage.height)/2; orbits.radius:=orbits.y/2.5; orbits.angle:=0; orbits.speed:=0; rsum:=orbits.radius; //children orbits for loop:=1 to numorbits-1 do begin newr:=orbits[loop-1].radius/orbitsizeratio; newx:=orbits[loop-1].x+orbits[loop-1].radius+newr; newy:=orbits[loop-1].y; orbits[loop].x:=newx; orbits[loop].y:=newy; orbits[loop].radius:=newr; orbits[loop].angle:=orbits[loop-1].angle; orbits[loop].speed:=power(k,loop-1)/sqr(k*k); end;
Then inside the main loop, you update the orbits;
//update orbits for loop:=1 to numorbits-1 do begin orbits[loop].angle:=orbits[loop].angle+orbits[loop].speed; rsum:=orbits[loop-1].radius+orbits[loop].radius; orbits[loop].x:=orbits[loop-1].x+rsum*cos(orbits[loop].angle*pi/180); orbits[loop].y:=orbits[loop-1].y+rsum*sin(orbits[loop].angle*pi/180); end;
and then you use the last orbit positions to plot the line, ie
Once the code was working I rendered the following images and movie. They are all 4K resolution to see the details. Click the images to see them full size.
Here is a 4K movie showing how these curves are built up.
Fractal Spirographs are now included with the latest version of Visions of Chaos.
Finally, here is an 8K Fulldome 8192×8192 pixel resolution image. Must be seen full size to see the fine detailed plot line.
Experiment with more changes in the circle sizes. The original blog post links to another 4 posts here, here, here and here and even this sumo wrestler
Plenty of inspiration for future enhancements.
I have already experimented with 3D Spirographs in the past, but they are using spheres rotating within other spheres. Plotting the sqheres rotating around the outside of other spheres should give more new unique results.