__Inspiration__

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.

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[0].x:=destimage.width/2;
orbits[0].y:=min(destimage.width,destimage.height)/2;
orbits[0].radius:=orbits[0].y/2.5;
orbits[0].angle:=0;
orbits[0].speed:=0;
rsum:=orbits[0].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

```
canvas.lineto(round(orbits[numorbits-1].x),round(orbits[numorbits-1].y));
```

__Results__

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.

__To Do__

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.

Jason.