# Barnsley’s Fern

In 1988, Michael Barnsley published an elegant way to programatically generate ferns. The rules are rather simple: iteratively apply a rotation + translation to a coordinate with certain probabilities, and voilà! A fern appears: ## How it works

The fern is generated iteratively. Starting with a seed coordinate, we jump to a new coordinate using an update rule. Given a coordinate vector [x, y], the update is given by:

Which values you use for A and b depend on a probability p. For this specific fern, there are four possible sets of values for A and b, each with it’s associated p:

We plant a seed at [0, 0] and iterate for as many steps as we’d like. At each step, we plot the coordinate. That’s it!

## Python Implementation

Let’s code this in python. First, we define our transformations and their associated probabilities:

import numpy as np

A1 = np.array(([0, 0], [0, 0.16]))
b1 = np.array([, ])
p1 = 0.01

A2 = np.array(([0.85, 0.04], [-0.04, 0.85]))
b2 = np.array([, [1.60]])
p2 = 0.85

A3 = np.array(([0.20, -0.26], [0.23, 0.22]))
b3 = np.array([, [1.60]])
p3 = 0.07

A4 = np.array(([-0.15, 0.28], [0.26, 0.24]))
b4 = np.array([, [0.44]])
p4 = 0.07


Next, we chose given probability p which update rule to apply, and apply it as long as many times as we want:

fern = [] # The collection of all Xs that will make up our Fern
X = np.array((, ))  # Seed

for N in range(100000):
p = np.random.random()  # Random value between 0 and 1
if p < p1:
A, b = A1, b1
elif p < p1 + p2:
A, b = A2, b2
elif p < p1 + p2 + p3:
A, b = A3, b3
elif p < p1 + p2 + p3 + p4:
A, b = A4, b4
X = np.matmul(A, X) + b  # Update Rule
fern.append(X)  # Add our new point to the fern


The last step is simply to scatter plot all our results:

import matplotlib.pyplot as plt

plt.figure(figsize=(10, 10))
plt.scatter(x=[X for X in fern], y=[X for X in fern], c="green", s=0.5)
plt.axis("off") That’s it! All the code to reproduce this is on Colab:

Tags:

Categories:

Updated: