Organism of the week #28 – Fractal art

Flowers are essentially tarts. Prostitutes for the bees. (Uncle Monty, Withnail and I)

Our tiny garden has only passing acquaintance with sunshine, so about the only plants that really thrive in its dingy clutches are shade-loving ferns. This Japanese painted fern is my current favourite: who needs flowers anyway, when leaves look like this?

Athyrium niponicum cv. Pictum [CC-BY-SA-3.0 Steve Cook]

Japanese painted fern (Athyrium niponicum cv. Pictum)

The colour is spectacular, but I also love the shape of the leaves. I have a rabbit’s-foot fern on my windowsill at $WORK, which branches not once, not twice, not thrice, but fwice, with each leaflet at each level looking very much like a miniaturised version of the whole leaf:

Humata tyermannii [CC-BY-SA-3.0 Steve Cook]

Humata tyermannii

Self-similar shapes like this are called fractals. This fern’s leaf is not a true mathematical fractal, because its self-similarity goes only four levels deep, rather than infinitely so. Also, from a developmental point of view, the leaves of ferns are produced by interactions between signalling molecules that have very little in common with the maths of fractals. However, it is remarkable how easy it is to produce a fractal that looks very much like a fern – especially when someone else has done all the hard work of discovering one for you. This one is called the Barnsley fern fractal, after Michael Barnsley:

Barnsley fern [Public domain]

Barnsley fern

This rather cute simulator allows you to play about with the Barnsley fern without going to the hassle of coding up any R yourself, but for those who enjoy such things, here’s my version of the code written in R, based on the coefficients from its Wikipedia article. An entirely imaginary prize is available for anyone who can produce a good simulation of either of the two ferns above.

fm <- vector( "list", 4 )
fc <- vector( "list", 4 )
fp <- vector( "list", 4 )

# Stem
fm[[1]] <- matrix( c( 0.00, 0.00, 0.00, 0.16 ), nrow=2, byrow=TRUE )
fc[[1]] <- matrix( c( 0.00, 0.00 ), nrow=2 )
fp[[1]] <- 0.01

# Leaflets
fm[[2]] <- matrix( c( 0.85, 0.04, -0.04, 0.85 ), nrow=2, byrow=TRUE )
fc[[2]] <- matrix( c( 0.00, 1.60 ), nrow=2 )
fp[[2]] <- 0.85

# Left largest leaflet
fm[[3]] <- matrix( c( 0.20, -0.26, 0.23, 0.22 ), nrow=2, byrow=TRUE )
fc[[3]] <- matrix( c( 0.00, 1.60 ), nrow=2 )
fp[[3]] <- 0.07

# Right largest leaflet
fm[[4]] <- matrix( c( -0.15, 0.28, 0.26, 0.24 ), nrow=2, byrow=TRUE )
fc[[4]] <- matrix( c( 0.00, 0.44 ), nrow=2 )
fp[[4]] <- 0.07

n<-250000 # you might want to make this smaller if it takes forever to render
x <- numeric( n )
y <- numeric( n )
x[1] <- 0
y[1] <- 0

for( i in 1:(n-1) ) {
  choice  <- sample( 1:4, prob=fp, size=1 )
  xy.next <- fm[[ choice ]] %*% c( x[i], y[i] ) + fc[[ choice ]]
  x[i+1]  <- xy.next[1]
  y[i+1]  <- xy.next[2]
}

plot( x, y, cex=0.05, col="dark green" )

1 comments

  1. I’ve just googled for “Barnsley fern R” and found this, which is so similar I wish I had plagiarised it, rather than converging on more-or-less the same code!

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.