In this article, I will show you how to render the Barnsley Fern in Python 3. The Barnsley Fern is a fractal that can be generated using four simple affine transformations of the form:
In the above table p represents the probability factor for a transform. For example, the second transform will be used 85% of times, third transform 7% and so on.
From a practical point of view, the Barnsley Fern is generated starting with an initial point \({x_{1}}\), \((0, 0)\), and iteratively calculating the next point \({x_{i}}\) using one of the above \({w_{i}}\) transforms.
At each step, we generate a random number r from the interval [0, 1) and, interpreting this number as a probability, we pick the corresponding transform. For example, if r is in the interval \([0, 0.01]\) we pick \({w_{1}}\), if r is in the interval \((0.01 + 0.85, 0.01 + 0.85 + 0.07]\) we pick \({w_{3}}\) and so on. Note, we define the intervals using the cumulative sum of the probability factors.
This is the result, after 1000000 iterations:
Now, we can implement the Python code that will generate the above fractal. Because we can generate an infinite number of fractals, by varying the coefficients of the affine transforms and their probability factor, I propose to implement a general Barnsley class that will let us use more than a set of coefficients. You can find the entire code on my GitHub https://github.com/sol-prog/Barnsley-Fern.
Next, we need a function to select which transform to use:
We can calculate and store the next point of the fractal using:
Use the above function to iteratively generate the number of points you need for the fractal:
Next step is to visualize the generated fractal. A simple solution is to use an image file for this.
In my last article I’ve shown you how to write your own PPM image generator from scratch in Python and you can follow this approach if you want. In the present article I will show you how to use the Pillow image library. On most systems you can install Pillow with:
Next, we initialize the fractal points, transform these points to the image space and save the image:
As previously mentioned, you can generate an infinite number or fractals by altering the coefficients of the transform. Here is what you get with a slightly changed set of coefficients:
w
a
b
c
d
e
f
p
1
0
0
0
0.16
0
0
0.04
2
0.7
0.035
-0.04
0.8
0
1.6
0.8
3
0.2
-0.29
0.23
0.22
0
1.6
0.08
4
-0.2
0.28
0.26
0.25
0
0.44
0.08
If you want to read more about the mathematics of fractal generation, I recommend reading Fractals Everywhere by Michael F. Barnsley:
If you want to learn more about Python, I recommend reading Python Crash Course by Eric Matthes: