The Hypnotic World of Degenerate Spirals

Recently, I was looking for a way to add a spiral to my website1. My search led me to this CodePen, which I found fascinating. For one, the code for simulating the spiral was very simple. But what really caught my attention was what happened when I started playing with the provided "angle" slider. Incredibly complex, intricate shapes were being drawn in front of my eyes from a few simple lines of code, and they didn't even look like spirals after some point.

I fell down an enjoyable rabbit hole trying to understand what was actually going on, and then I ended up finding and playing around with different types of spirals to see what other effects I could observe. I'd love to share all my findings with you, but if you don't care for the details then feel free to jump directly to the visualisations!

What is a Spiral?

In mathematics, a spiral is a curve which emanates from a point, moving farther away as it revolves around the point.

I think it's useful to start by looking at a simple circle. Even though we usually think of circles as static, we could also think of them as curves revolving around a point, always staying at the exact same distance to that point.

As the radius \(r\) is kept constant while the angle \(\theta\) keeps increasing, this motion traces a perfect circle after \(360^{\circ}\) and goes on to loop over itself forever.

When we look at a circle from this perspective, the only difference of a spiral is that the radius is not kept constant, but changes according to some function of the angle: \[r = f(\theta)\] Different functions lead to different spirals, some of which we will explore later on. For now, let's start with the simplest one, the Archimedean Spiral: \[r = a\theta\]

In this example, I chose \(a = 0.1\) so the radius is always equal to \(\theta / 10\) (with \(\theta\) given in degrees). Changing this parameter does not change the fundamental shape of the spiral, it only changes the distance between consecutive loops.

To change the shape of the spiral, we need to change the relation between the angle and the radius. For example, Fermat's Spiral has loops that get closer to each other as the curve gets farther from the center: \[r = a \sqrt{\theta}\]

With a small change, we can even get a spiral converging towards a point instead of diverging away from one, such as a lituus: \[r = \frac{a}{\sqrt{\theta}}\]

How to Draw a Spiral

There are multiple ways of drawing a spiral using code, and you can see different implementations in many languages at Rosetta Code. We are interested in the approach using line segments, since that is the one that will lead to those interesting patterns at the start of this post.

Let's say we want to draw a spiral that has completed 5 full rotations, so \(\theta\) has gone from \(0^\circ\) to \(1800^\circ\). We are going to approximate this curve by picking lots of points that would be on this spiral and connecting them with straight line segments.

This is basically how I've been drawing all the spirals so far, but without showing you the actual points. To create an animation of an expanding spiral, all you need to do is increase \(\theta\) a little every frame and draw the corresponding spiral2.

In the above example, I chose to pick a point every \(5^\circ\) from \(0^\circ\) to \(1800^\circ\), which I think creates a pretty reasonable approximation. Of course, if we decrease this gap we will pick more points and get a better approximation, and similarly if we increase this gap we will get a worse approximation.

If you played around a bit with the slider above, you might already see where we're going with this.

Spiraling out of Control

What if, instead of committing to picking points at regular intervals (like every \(5^\circ\)), we limit ourselves to approximate the spiral with a fixed number of points (say, 100) no matter how big the spiral gets. In this case, as the spiral expands, the few points have to spread apart further and further to cover the entire shape, making our approximation progressively worse.

And there we are! Now we just have to choose some arbitrary number of points, let \(\theta\) grow and watch our spiral degenerate slowly into these cool, intricate patterns as our approximation fails spectacularly.

In the next section, I will remove the explanatory elements like the coordinate axes and the line/point showing the end of the spiral, so you can enjoy the hypnotic visualisations of what I'm now calling degenerate spirals.

Hypnotic Visualisations

Archimedean Spiral

Fermat's Spiral

Lituus

Bonus: The Second Branch (and Beyond)

I've only been drawing a single branch of these spirals, in fact there are more! We obtained the spirals so far by starting at \(\theta = 0\) and slowly increasing it; we can get another one by moving in the other direction. Here are both branches of the Archimedean Spiral and their romantic dance, starting with a small heart:

This actually adds a whole new layer of beautiful complexity to our degenerate spirals, leading to lots of flowery patterns!

There is another way of adding a secondary branch to a spiral, and that is by drawing its reflection with respect to the origin. Here is an example using Fermat's spiral:

Of course, you don't have to choose one or the other, you can have four branches at the same time. So here, to end this post, are all four branches of a lituus gracefully degenerating into an end mark.

Final Remarks

If you'd like to dive deeper into the world of spirals, the Wikipedia article is a good place to start with lots of general information and links to different types of spirals. All visualisations on this page were made with the amazing p5.js library. If you'd like to play around with code, I've made a template degenerate spiral sketch on the p5.js Web Editor that you can edit and run! If you would instead prefer to look at the code of the sketches here, check out the source for this post.

The format of this post is inspired by the Explorable Explanations movement, which I enjoy so much. If you liked this at all, you'll probably love some of the posts there. This is the first time I'm exploring and explaining a topic in this way, so if you have any feedback (or just want to say hi), feel free to write to me!



Footnotes

  1. As one does. ↩︎

  2. If you are just trying to draw a proper spiral that keeps expanding, it is obviously inefficient to redraw the entire spiral every frame; you should just add a few new line segments to the end at every frame. However, we are not trying to draw proper spirals and redrawing every frame is essential for the effect we are pursuing here. ↩︎