Index Books FAQ Contact About Rod

# Title: Draw a Barnsley fern fractal in C#

This example draws a Barnsley fern fractal. For information about this kind of fractal, see Barnsley's Fern by Eric W. Weisstein from MathWorld, a Wolfram Web Resource.

The program starts from a random point. At each step, it randomly picks a function (with non-uniform probability) and applies the function to the point to find the next point. It then plots that point.

Each function has the form:

X(n+1) = A * X(n) + B * Y(n) + C
Y(n+1) = D * X(n) + E * Y(n) + F

The following code initializes the probability and function parameters.

private float[] Prob = { 0.01f, 0.85f, 0.08f, 0.06f }; private float[, ,] Func = { { {0, 0}, {0, 0.16f}, }, { {0.85f, 0.04f}, {-0.04f, 0.85f}, }, { {0.2f, -0.26f}, {0.23f, 0.22f}, }, { {-0.15f, 0.28f}, {0.26f, 0.24f}, }, }; private float[,] Plus = { {0, 0}, {0, 1.6f}, {0, 1.6f}, {0, 0.44f}, };

The Prob array gives the probabilities of picking each of the different functions. The Func array contains the values A, B, D, and E. The Plus array holds the values C and F.

The following MakeFern method draws the fractal into a Bitmap and displays it.

private void MakeFern() { int wid = picCanvas.ClientSize.Width; int hgt = picCanvas.ClientSize.Height; Bitmap bm = new Bitmap(wid, hgt); using (Graphics gr = Graphics.FromImage(bm)) { gr.Clear(Color.Black); Random rnd = new Random(); int func_num = 0, ix, iy; float x = 1, y = 1, x1, y1; for (int i = 1; i <= 100000; i++) { double num = rnd.NextDouble(); for (int j = 0; j <= 3; j++) { num = num - Prob[j]; if (num <= 0) { func_num = j; break; } } x1 = x * Func[func_num, 0, 0] + y * Func[func_num, 0, 1] + Plus[func_num, 0]; y1 = x * Func[func_num, 1, 0] + y * Func[func_num, 1, 1] + Plus[func_num, 1]; x = x1; y = y1; const float w_xmin = -4; const float w_xmax = 4; const float w_ymin = -0.1f; const float w_ymax = 10.1f; const float w_wid = w_xmax - w_xmin; const float w_hgt = w_ymax - w_ymin; ix = (int)Math.Round((x - w_xmin) / w_wid * picCanvas.ClientSize.Width); iy = (int)Math.Round( (picCanvas.ClientSize.Height - 1) - (y - w_ymin) / w_hgt * hgt); if ((ix >= 0) && (iy >= 0) && (ix < wid) && (iy < hgt)) { bm.SetPixel(ix, iy, Color.Lime); } } } // Display the result. picCanvas.BackgroundImage = bm; }

The MakeFern method starts at point (1, 1) and repeatedly applies randomly selected functions, plotting each point on the Bitmap.