Fractals In Go
When I first learned about fractals in middle school, I was hit by a lot of conflicting feelings. They looked fantastically terrifying with their patterns both evoking a sense of wonder and discomfort. They also were enigmatic: a locked puzzle that somehow came up “naturally” in mathematics. A kind of Lovecraftian “natural”, that is.
I mean, look at this!
This particular fractal is famously known as the Mandlebrot set. To understand why it is important, one must first know two concepts: complex numbers, and recursion.
It is unfortunate that “complex numbers” (or “imaginary numbers”) were given these names. They are neither complex, nor imaginary. Two differences make complex numbers stand out from the real numbers we use in our daily life. Firstly, complex numbers have an additional dimension to their counting, turning the number line into a number grid. Secondly, when squaring complex numbers, not only do they scale bigger or smaller like when you square or square-root the real numbers but they also rotate around the origin. It is this property of rotation which gives rise to the fractal.
But what about recursion? I will now show you how recursion works. If you have read this sentence thrice, go ahead to the next paragraph, but if you have not then do not read ahead and instead go back to the beginning of this paragraph and continue reading normally from there.
Phew, so you made it. Luckily the above paragraph only has you recur your reading three times!
Now, armed with the knowledge necessary to understand fractals, the secret can now be revealed. A fractal is simply a group of complex numbers with rules applied recursively to it. For the fractal such as this one:
The rules are:
- The center of the image is the origin
0 + 0i.
- The edge of the image is 2 away. So the right-center pixel would be
2 + 0i, the top-right corner pixel would be
2 + 2i, and so on.
- For each pixel in the image, begin with its complex number and call it
- Recursively apply:
z = z * z + Cfor some constant number
- Once we have done enough recursion, color the pixel based on the resulting number.
Pretty cool! This is the algorithm for a Julia set fractal.
But how do we go back to the famous Mandlebrot? Simplly change the second-to-last rule above to be:
- Recursively apply:
z = z * z + Cwhere
Cis the very first number we started with before recurring.
That simple change is all it takes!
Note that since the Mandlebrot’s
C is changing depending on where we started, eventually for one pixel it will recur in exactly the same way an entire Julia set fractal does. So the Julia set that looks like a galaxy above was generated with a single
C for the entire image; in the Mandlebrot above there is a single pixel whose
C matches this value!
Neat, but what if we start messing with the color palette used to generate these images?
Let’s use a CMYK palette - which means we have the cyan, magenta, yellow, and black colors at our disposal. Since black will overshadow any of the other colors, let’s use the other three. And let’s use the following rules:
- Cyan will color the
zvalues that did not go very far.
- Magenta will color the areas that did not diverge. That is, the more we recursively applied
z = z * z + Cabove, the new
zremained near zero.
- Yellow will color the areas that did diverge.
Applying it to a Julia fractal, we get:
A couple of you have already made some smart observations:
- No blue! Blue has mixed with the Magenta and Yellow to add emphasis on the distance of their (non) divergence.
- Green areas are where numbers diverged, but not very far.
- Purple areas did not diverge, but wound up far from where they started.
- There’s a lot of dots! These Magenta and Purple dots are showing the limits of recursion. If I allowed the computer to continue recurring far longer, the dots would be much smaller.
While this coloration tells us a lot of information, it does not look nice. And that’s what is really important with fractals. So, what happens when we apply a rainbow gradient without smoothing to a fractal?
What if we could animate this? How can we animate this? Should we animate this? Or has math gone too far?
Long story short, remember how I mentioned complex numbers rotate when squaring? Well what if we generated a bunch of fractal Julia set images, but each one with a slightly different
C? This would be like picking many neighboring pixels in the Mandelbrot set, which gives us a good signal that the images would smoothly transition from one to another and not be discontinuous and jarring. To precisely calculate the angle of rotation desired over a given number of frames requires the application of Euler’s Formula, which is beyond what I want to discuss now. However, it is an area of math that is the gateway to a lot of cool, weird relationships.
The result with 5 degrees of rotation, if my memory serves me right:
Note that the original GIF is huge at over 25 MB in size. So I can only get my poor server to show you a smaller, compressed version of its psychedelic beauty.
Still not convinced that fractals are terrifyingly beautiful? Fine, we will smoothen out the rainbow gradient and zoom into a really neat part of the Julia set.
I hope you enjoy, thanks for reading.
Published: Feb 05, 2018 17:14:38 EST
By: Cory Slep