# Barnsley’s Fern

# 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([[0], [0]])
p1 = 0.01
A2 = np.array(([0.85, 0.04], [-0.04, 0.85]))
b2 = np.array([[0], [1.60]])
p2 = 0.85
A3 = np.array(([0.20, -0.26], [0.23, 0.22]))
b3 = np.array([[0], [1.60]])
p3 = 0.07
A4 = np.array(([-0.15, 0.28], [0.26, 0.24]))
b4 = np.array([[0], [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(([0], [0])) # 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[0] for X in fern], y=[X[1] for X in fern], c="green", s=0.5)
plt.axis("off")
```

That’s it! All the code to reproduce this is on Colab:

## Comments