Barnsley's fern
   HOME

TheInfoList



OR:

The Barnsley fern is a fractal named after the British
mathematician A mathematician is someone who uses an extensive knowledge of mathematics in their work, typically to solve mathematical problems. Mathematicians are concerned with numbers, data, quantity, structure, space, models, and change. History On ...
Michael Barnsley Michael Fielding Barnsley (born 1946) is a British mathematician, researcher and an entrepreneur who has worked on fractal compression; he holds several patents on the technology. He received his Ph.D. in theoretical chemistry from University of Wi ...
who first described it in his book ''Fractals Everywhere''.Fractals Everywhere
Boston, MA: Academic Press, 1993,
He made it to resemble the black spleenwort, '' Asplenium adiantum-nigrum''.


History

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. Barnsley's 1988 book ''Fractals Everywhere'' is based on the course which he taught for undergraduate and graduate students in the School of Mathematics, Georgia Institute of Technology, called ''Fractal Geometry''. After publishing the book, a second course was developed, called ''Fractal Measure Theory''. Barnsley's work has been a source of inspiration to graphic artists attempting to imitate nature with mathematical models. The fern code developed by Barnsley is an example of an iterated function system (IFS) to create a fractal. This follows from the collage theorem. He has used fractals to model a diverse range of phenomena in science and technology, but most specifically plant structures. —Michael Barnsley ''et al.''
Michael Barnsley Michael Fielding Barnsley (born 1946) is a British mathematician, researcher and an entrepreneur who has worked on fractal compression; he holds several patents on the technology. He received his Ph.D. in theoretical chemistry from University of Wi ...
, ''et al.'', 


Construction

Barnsley's fern uses four affine transformations. The formula for one transformation is the following: : f(x,y) = \begina & b \\ c & d \end \begin x \\ y \end + \begin e \\ f \end Barnsley shows the ''IFS'' code for his ''Black Spleenwort'' fern fractal as a matrix of values shown in a table.''Fractals Everywhere'', table III.3, IFS code for a fern. In the table, the columns "a" through "f" are the coefficients of the equation, and "p" represents the probability factor. These correspond to the following transformations: : f_1(x,y) = \begin \ 0.00 & \ 0.00 \ \\ 0.00 & \ 0.16 \end \begin \ x \\ y \end : f_2(x,y) = \begin \ 0.85 & \ 0.04 \ \\ -0.04 & \ 0.85 \end \begin \ x \\ y \end + \begin \ 0.00 \\ 1.60 \end : f_3(x,y) = \begin \ 0.20 & \ -0.26 \ \\ 0.23 & \ 0.22 \end \begin \ x \\ y \end + \begin \ 0.00 \\ 1.60 \end : f_4(x,y) = \begin \ -0.15 & \ 0.28 \ \\ 0.26 & \ 0.24 \end \begin \ x \\ y \end + \begin \ 0.00 \\ 0.44 \end


Computer generation

Though Barnsley's fern could in theory be plotted by hand with a pen and graph paper, the number of iterations necessary runs into the tens of thousands, which makes use of a computer practically mandatory. Many different computer models of Barnsley's fern are popular with contemporary mathematicians. As long as math is programmed correctly using Barnsley's matrix of constants, the same fern shape will be produced. The first point drawn is at the origin (''x''0 = 0, ''y''0 = 0) and then the new points are iteratively computed by randomly applying one of the following four coordinate transformations: ''ƒ''1 :''x''''n'' + 1 = 0 :''y''''n'' + 1 = 0.16 ''y''''n''. This coordinate transformation is chosen 1% of the time and just maps any point to a point in the first line segment at the base of the stem. This part of the figure is the first to be completed during the course of iterations. ''ƒ''2 :''x''''n'' + 1 = 0.85 ''x''''n'' + 0.04 ''y''''n'' :''y''''n'' + 1 = −0.04 ''x''''n'' + 0.85 ''y''''n'' + 1.6. This coordinate transformation is chosen 85% of the time and maps any point inside the leaflet represented by the red triangle to a point inside the opposite, smaller leaflet represented by the blue triangle in the figure. ''ƒ''3 :''x''''n'' + 1 = 0.2 ''x''''n'' − 0.26 ''y''''n'' :''y''''n'' + 1 = 0.23 ''x''''n'' + 0.22 ''y''''n'' + 1.6. This coordinate transformation is chosen 7% of the time and maps any point inside the leaflet (or ''pinna'') represented by the blue triangle to a point inside the alternating corresponding triangle across the stem (it flips it). ''ƒ''4 :''x''''n'' + 1 = −0.15 ''x''''n'' + 0.28 ''y''''n'' :''y''''n'' + 1 = 0.26 ''x''''n'' + 0.24 ''y''''n'' + 0.44. This coordinate transformation is chosen 7% of the time and maps any point inside the leaflet (or ''pinna'') represented by the blue triangle to a point inside the alternating corresponding triangle across the stem (without flipping it). The first coordinate transformation draws the stem. The second generates successive copies of the stem and bottom fronds to make the complete fern. The third draws the bottom frond on the left. The fourth draws the bottom frond on the right. The recursive nature of the IFS guarantees that the whole is a larger replica of each frond. Note that the complete fern is within the range −2.1820 < ''x'' < 2.6558 and 0 ≤ ''y'' < 9.9983.


Mutant varieties

By playing with the coefficients, it is possible to create mutant fern varieties. In his paper on V-variable fractals, Barnsley calls this trait a ''superfractal''. One experimenter has come up with a table of coefficients to produce another remarkably naturally looking fern however, resembling the '' Cyclosorus'' or ''
Thelypteridaceae Thelypteridaceae is a family of about 900 species of ferns in the order Polypodiales. In the Pteridophyte Phylogeny Group classification of 2016 (PPG I), it is placed in the suborder Aspleniineae. Alternatively, the family may be submerged in a ...
'' fern. These are:A Barnsley fern generator
/ref>


Syntax examples

You can use the below syntax to draw the fern yourself.


Julia

using GLMakie f1(x, y) = 0; 0 0.16*
, y The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline ...
f2(x, y) = .85 0.04; -0.04 0.85*
, y The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline ...
+ , 1.6f3(x, y) = .2 -0.26; 0.23 0.22*
, y The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline ...
+ , 1.6f4(x, y) = 0.15 0.28; 0.26 0.24*
, y The comma is a punctuation mark that appears in several variants in different languages. It has the same shape as an apostrophe or single closing quotation mark () in many typefaces, but it differs from them in being placed on the baseline ...
+ , 0.44 function f(x, y) r = rand() r < 0.01 && return f1(x, y) r < 0.86 && return f2(x, y) r < 0.93 && return f3(x, y) f4(x, y) end function barnsley_fern(iter) X = .0 Y = .0 for i in 1:iter x, y = f(X nd Y nd push!(X, x) push!(Y, y) end scatter(X, Y, color=:green, markersize=1) end barnsley_fern(1_000_000)


Python

import turtle import random pen = turtle.Turtle() pen.speed(0) pen.color("green") pen.penup() x = 0 y = 0 for n in range(11000): pen.goto(65 * x, 37 * y - 252) # scale the fern to fit nicely inside the window pen.pendown() pen.dot(3) pen.penup() r = random.random() if r < 0.01: x, y = 0.00 * x + 0.00 * y, 0.00 * x + 0.16 * y + 0.00 elif r < 0.86: x, y = 0.85 * x + 0.04 * y, -0.04 * x + 0.85 * y + 1.60 elif r < 0.93: x, y = 0.20 * x - 0.26 * y, 0.23 * x + 0.22 * y + 1.60 else: x, y = -0.15 * x + 0.28 * y, 0.26 * x + 0.24 * y + 0.44


R

# Barnsley's Fern # create function of the probability and the current point fractal_fern2 <- function(x, p) # how many reps determines how detailed the fern will be reps <- 10000 # create a vector with probability values, and a matrix to store coordinates p <- runif(reps) # initialise a point at the origin coords <- c(0, 0) # compute Fractal Coordinates m <- Reduce(fractal_fern2, p, accumulate = T, init = coords) m <- t(do.call(cbind, m)) # Create plot plot(m, type = "p", cex = 0.1, col = "darkgreen", xlim = c(-3, 3), ylim = c(0, 10), xlab = NA, ylab = NA, axes = FALSE)


Processing

/* Barnsley Fern for Processing 3.4 */ // declaring variables x and y float x, y; // creating canvas void setup() /* setting stroke, mapping canvas and then plotting the points */ void drawPoint() /* algorithm for calculating value of (n+1)th term of x and y based on the transformation matrices */ void nextPoint() /* iterate the plotting and calculation functions over a loop */ void draw()


P5.JS

let x = 0; let y = 0; function setup() //range −2.1820 < x < 2.6558 and 0 ≤ y < 9.9983. function drawPoint() function nextPoint() function draw()


JavaScript (HTML5)


QBasic

SCREEN 12 WINDOW (-5, 0)-(5, 10) RANDOMIZE TIMER COLOR 10 DO SELECT CASE RND CASE IS < .01 nextX = 0 nextY = .16 * y CASE .01 TO .08 nextX = .2 * x - .26 * y nextY = .23 * x + .22 * y + 1.6 CASE .08 TO .15 nextX = -.15 * x + .28 * y nextY = .26 * x + .24 * y + .44 CASE ELSE nextX = .85 * x + .04 * y nextY = -.04 * x + .85 * y + 1.6 END SELECT x = nextX y = nextY PSET (x, y) LOOP UNTIL INKEY$ = CHR$(27)


VBA (CorelDraw)

Sub Barnsley() Dim iEnd As Long Dim i As Long Dim x As Double Dim y As Double Dim nextX As Double Dim nextY As Double Dim sShapeArray() As Shape Dim dSize As Double Dim sColor As String dSize = 0.01 ' Size of the dots sColor = "0,0,100" ' RGB color of dots, value range 0 to 255 iEnd = 5000 ' Number of iterations ReDim sShapeArray(iEnd) ' In Corel, each object drawn requires a variable name of its own Randomize ' Initialize the Rnd function For i = 0 To iEnd ' Iterate ... Select Case Rnd Case Is < 0.01 ' f1 = Draw stem nextX = 0 nextY = 0.16 * y Case 0.01 To 0.08 ' f3 nextX = 0.2 * x - 0.26 * y nextY = 0.23 * x + 0.22 * y + 1.6 Case 0.08 To 0.15 ' f4 nextX = -0.15 * x + 0.28 * y nextY = 0.26 * x + 0.24 * y + 0.44 Case Else ' f2 nextX = 0.85 * x + 0.04 * y nextY = -0.04 * x + 0.85 * y + 1.6 End Select x = nextX y = nextY Set sShapeArray(i) = ActiveLayer.CreateEllipse2(x + 2.5, y + 0.5, dSize) sShapeArray(i).Style.StringAssign "" DoEvents Next End Sub


Amola

addpackage("Forms.dll") set("x", 0) set("y", 0) set("width", 600) set("height", 600) method setup() createCanvas(width, height) rect(0, 0, 600, 600, color(0, 0, 0)) end method drawPoint() set("curX", div(mult(width, add(x, 3)), 6)) set("curY", sub(height, mult(height, div(add(y, 2), 14)))) set("size", 1) //log(curX) //log(curY) rect(round(curX - size / 2), round(curY - size / 2), round(curX + size / 2), round(curY + size / 2), color(34, 139, 34)) end method nextPoint() set("nextX", 0) set("nextY", 0) set("random", random(0, 100)) if(random < 1) set("nextX", 0) set("nextY", 0.16 * y) end else if(random < 86) set("nextX", 0.85 * x + 0.04 * y) set("nextY", -0.04 * x + 0.85 * y + 1.6) end else if(random < 93) set("nextX", 0.2 * x - 0.26 * y) set("nextY", 0.23 * x + 0.22 * y + 1.6) end else set("nextX", -0.15 * x + 0.28 * y) set("nextY", 0.26 * x + 0.24 * y + 0.44) end end end set("x", nextX) set("y", nextY) end setup() while(true) drawPoint() nextPoint() end


TSQL

/* results table */ declare @fern table (Fun int, X float, Y float, Seq int identity(1,1) primary key, DateAdded datetime default getdate()) declare @i int = 1 /* iterations */ declare @fun int /* random function */ declare @x float = 0 /* initialise X = 0 */ declare @y float = 0 /* initialise Y = 0 */ declare @rand float insert into @fern (Fun, X, Y) values (0,0,0) /* set starting point */ while @i < 5000 /* how many points? */ begin set @rand = rand() select @Fun = case /* get random function to use -- @fun = f1 = 1%, f2 = 85%, f3 = 7%, f4 = 7% */ when @rand <= 0.01 then 1 when @rand <= 0.86 then 2 when @rand <= 0.93 then 3 when @rand <= 1 then 4 end select top 1 @X = X, @Y = Y from @fern order by Seq desc /* get previous point */ insert into @fern(Fun, X, Y) /* transform using four different function expressions */ select @fun, case @fun when 1 then 0 when 2 then 0.85*@x+0.04*@y when 3 then 0.2*@x-0.26*@y when 4 then -0.15*@x + 0.28*@y end X, case @fun when 1 then 0.16*@y when 2 then -0.04*@x + 0.85*@y + 1.6 when 3 then 0.23*@x + 0.22*@y + 1.6 when 4 then 0.26*@x + 0.24*@y + 0.44 end Y set @i=@i+1 end select top 5000 *,geography::Point(Y, X, 4326) from @fern order by newid()


MATLAB

N = 1000000; xy = ; 0 fern = zeros(N, 2); f_1 = 0; 0 0.16 f_2 = .85 0.04; -0.04 0.85 f_3 = .2 -0.26; 0.23 0.22 f_4 = 0.15 0.28; 0.26 0.24 P = randsample(1:4, N, true, .01 0.85 0.07 0.07; for i = 2:N p = P(i - 1); if p

1 % Stem xy = f_1 * xy; elseif p

2 % Sub-leaflets xy = f_2 * xy + ; 1.6 elseif p

3 % Left leaflet xy = f_3 * xy + ; 1.6 else % Right leaflet xy = f_4 * xy + ; 0.44 end fern(i, 1) = xy(1); fern(i, 2) = xy(2); end clearvars -except N fern % R2008a+ % Plotting the fern % % % Less detail, better performance c = linspace(1, 0.2, N - 1); c(end + 1) = 0; colormap(summer(N)); set(gcf, 'Color', 'k', 'position', 0, 50, 800, 600; scatter(fern(:, 1), fern(:, 2), 0.1, c, '.'); set(gca, 'Color', 'k'); %}


Wolfram Mathematica

BarnsleyFern al_, n_:= Module __Graphics[,_ImageSize_->_Large BarnsleyFern[(__),_500000.html" ;"title="_ImageSize_->_Large.html" ;"title=" Graphics[, ImageSize -> Large"> Graphics[, ImageSize -> Large BarnsleyFern[( ), 500000">_ImageSize_->_Large.html" ;"title=" Graphics[, ImageSize -> Large"> Graphics[, ImageSize -> Large BarnsleyFern[( ), 500000


BBC Basic

0REM Compact version tweeted to @BBCMicroBot 1MODE0:VDU19,1,2,0,0,0:PRINT''" Barnsley fern":VDU23,1,0;0;0;0;:X=0:Y=0 2REPEATR=RND(100) 3IFR=1X=0:Y=.16*Y ELSEIFR<87T=.85*X+.04*Y:Y=-.04*X+.85*Y+1.6:X=T ELSEIFR<94T=.2*X-.26*Y:Y=.23*X+.22*Y+1.6:X=T ELSET=-.15*X+.28*Y:Y=.26*X+.24*Y+.44:X=T 4PLOT69,126*Y,471+200*X 5UNTIL0


HTML5 Canvas

Barneley Fern Generator

Barnsley Fern


References

{{Digital art Affine geometry L-systems Articles with example R code Articles with example Python (programming language) code