Barnsley Fern

canvasfractalsmath

The Barnsley Fern is a fractal named after the British mathematician Michael Barnsley who first described it in his book _Fractals Everywhere_. The fern is one of the basic examples of self-similar sets, i.e. it is a mathematically generated pattern that can be reproducible at any magnification or reduction. Like the Sierpinski triangle, the Barnsley fern shows how graphically beautiful structures can be built from repetitive uses of mathematical formulas with computers. The fern code developed by Barnsley is an example of an iterated function system (IFS) to create a fractal; this is translated into the below code using big-bang to compute successive values of (x,y) using a randomly chosen affine transform.

1 Aug 2014 by rm-hull
rm-hull/b971d77087ff873ed7c2
barnsley-fern.cljs
(ns big-bang.examples.barnsley-fern
  (:require  
    [jayq.core :refer [show]]
    [big-bang.core :refer [big-bang]]
    [enchilada :refer [ctx canvas canvas-size]]
    [monet.canvas :refer [fill-rect fill-style]]))
 
(def width (first (canvas-size)))
(def height (second (canvas-size)))
(def scale (/ height 10))
(def offset (/ width 2))

(def black-spleenwort [
      ;Cumulative 
      ;Probability  Co-efficients
      [0.01        [ 0.00  0.00  0.00  0.16  0.00  0.00]]
      [0.86        [ 0.85  0.04 -0.04  0.85  0.00  1.60]]
      [0.93        [ 0.20 -0.26  0.23  0.22  0.00  1.60]]
      [1.00        [-0.15  0.28  0.26  0.24  0.00  0.44]]])

(def initial-state [0 0])
 
(defn pick-coeffs [prob affine-transforms]
  (first
    (for [[cumulative-prob coeffs] affine-transforms
          :when (<= prob cumulative-prob)]
      coeffs)))

(defn apply-transform [[x y] [a b c d e f]]
  [(+ (* a x) (* b y) e)
   (+ (* c x) (* d y) f)])

(defn update-state [event world-state]
  (->>
    black-spleenwort
    (pick-coeffs (rand))
    (apply-transform world-state)))

(defn render-fern [[x y]]
  (fill-rect ctx {
    :x (Math/floor (+ offset (* scale x)))
    :y (Math/floor (+ height (* scale y -1)))
    :w 1 :h 1}))
 
(show canvas)
(fill-style ctx "green")

(big-bang
  :initial-state initial-state
  :on-tick update-state
  :tick-rate 1
  :to-draw render-fern)