Barnsley Fern

The Barnsley Fern is a fractal pattern named after British mathematician Michael Barnsley. It is generated by an iterative process that involves repeatedly applying a set of geometric transformations to a simple initial shape. The resulting fern-like pattern displays self-similarity at different scales, and has applications in computer graphics, image compression, and chaos theory.

  1float x = 0;
  2float y = 0;
  3
  4float[][] magicX = {  
  5  {0.00, 0.00}, 
  6  {0.85, 0.04}, 
  7  {0.20, -0.26}, 
  8  {-0.15, 0.28}
  9};
 10
 11float[][] magicY = {  
 12  {0.16, 0.00, 0.00}, 
 13  {-0.04, 0.85, 1.6}, 
 14  {0.23, 0.22, 1.6}, 
 15  {0.26, 0.24, 0.44}
 16};
 17
 18//PGraphics pg;
 19
 20int iterations = 123456;
 21
 22void setup() {
 23  //fullScreen(P3D);
 24  size(2048, 2048, P3D);
 25  background(0);
 26  histogram = new int[width][height];
 27  //pg = createGraphics(width*2, height*2);
 28  //pg.beginDraw();
 29  //pg.background(0, 50);
 30  //pg.endDraw();
 31}
 32
 33boolean record = false;
 34void draw() {
 35  /*
 36   background();
 37   translate(width*0.5, 0, 0);
 38   rotateY(frameCount*0.01);
 39   translate(-width*0.5, 0, 0);
 40   image(pg, -width, -height);
 41   */
 42
 43  for (int i = 0; i < iterations; i++) {
 44    getPoint();
 45    drawPoint();
 46  }
 47
 48  if (frameCount < 100) {
 49    saveFrame("frame-####.jpg");
 50  } else {
 51    exit();
 52  }
 53}
 54
 55void getPoint() {
 56
 57  float dx = 0;
 58  float dy = 0;
 59
 60  float r1 = random(1);
 61  if (r1 < 0.01) {
 62    //1
 63    dx =  magicX[0][0];
 64    dy = magicY[0][0] * y;
 65  } else if (r1 < 0.86 ) {
 66    //2
 67    dx = magicX[1][0] * x + magicX[1][1] * y;
 68    dy = magicY[1][0] * x + magicY[1][1] * y + magicY[1][2];
 69  } else if (r1 < 0.93) {
 70    //3
 71    dx = magicX[2][0] * x + magicX[2][1] * y;
 72    dy = magicY[2][0] * x + magicY[2][1] * y + magicY[2][2];
 73  } else {
 74    //4
 75    dx = magicX[3][0] * x + magicX[3][1] * y;
 76    dy = magicY[3][0] * x + magicY[3][1] * y + magicY[3][2];
 77  }
 78
 79  x = dx;
 80  y = dy;
 81}
 82
 83int[][] histogram;
 84int highest = 0;
 85
 86void drawPoint() {
 87
 88  int px = (int)map(x, -2.1820, 2.6558, width*0.19, width*0.81);
 89  int py = (int)map(y, 0, 9.9983, height*0.99, height*0.01);
 90
 91  histogram[px][py]++;
 92
 93  if (histogram[px][py] > highest) {
 94    highest = histogram[px][py];
 95    set(px, py, 255);
 96  }
 97
 98  if (highest > 1) {
 99    //float bright = map(histogram[px][py], 0, (float)Math.log(highest), 0, 255);
100    //stroke(histogram[px][py], bright,0);
101    float m = map(histogram[px][py], 0, log(highest), 0, 1);
102    color from = color(#123556);
103    color to = color(255);
104    color l = lerpColor(from, to, m);
105
106    // pixels[py*width+px] = l;
107    set(px, py, l);
108  }
109}

Written using the Processing Java library: https://processing.org/download