BLOG.CSHARPHELPER.COM: Draw a Buddhabrot fractal in C#
Draw a Buddhabrot fractal in C#
The Mandelbrot set iterates the function Z = Z2 + C in complex numbers for various values of C. It can be shown that, if the magnitude of Z ever grows beyond 2, then the function eventually heads towards infinity.
To draw a Mandelbrot set, you iterate the function and see how many iterations it takes for the function to reach magnitude 2. You then color the point C based on how many iterations it took. For example, if you use N colors and it took M iterations, then you could give the point color number M mod N.
To draw the Buddhabrot, you iterate Z = Z2 + C for values as usual, except you pick the values C randomly. If the function's magnitude exceeds 2 at some point, you go back and iterate the function again. This time you increment a count for each value Z that you come to before the magnitude exceeds 2. When you're done, you set a pixel's brightness to be 255 times its hit count divided by the largest hit count of any pixel.
To get the color map version, you set each point in the sequence based on the color of the initial value C. In this example, the program makes the points red if the distance from C to the origin is less than 1, green if the distance from C to the origin is less than Sqrt(2), and blue otherwise.
// Draw the Buddhabrot until stopped or // we plot the desired number of points. private void DrawBrot() { // Get parameters. int wid = int.Parse(txtWidth.Text); int hgt = int.Parse(txtHeight.Text); int cut_r = int.Parse(txtRedCutoff.Text); int cut_g = int.Parse(txtGreenCutoff.Text); int cut_b = int.Parse(txtBlueCutoff.Text); int stop_after = int.Parse(txtStopAfter.Text); int draw_every = int.Parse(txtDrawEvery.Text);
Application.DoEvents(); if (!m_Drawing) break; } } }
// Plot one point. private void DrawPoint(double cx, double cy , int wid, int hgt, double dx , double dy , ref int max_hits, int[,] hits, int cutoff, ref int num_hits) { const double ESCAPING = 4;
// Pick C. ////Dim cx As Double = Wxmin + m_Rand.NextDouble() * (Wxmax - Wxmin) ////Dim cy As Double = Wymin + m_Rand.NextDouble() * (Wymax - Wymin)
// Zet Z0. double x, xx, y, yy; x = cx; y = cy; xx = x * x; yy = y * y;
// Iterate. for (int i = 1; i <= cutoff; i++) { y = 2 * x * y + cy; x = xx - yy + cx; xx = x * x; yy = y * y; if (xx + yy >= ESCAPING) break; }
// See if we escaped. if (xx + yy >= ESCAPING) { // Plot. x = cx; y = cy; xx = x * x; yy = y * y;
// Iterate. for (int i = 1; i <= cutoff; i++) { int ix = (int)Math.Round((x - Wxmin) / dx); int iy = (int)Math.Round((y - Wymin) / dy); if ((ix >= 0) && (ix < hgt) && (iy >= 0) && (iy < wid)) { hits[iy, ix] += 1; if (max_hits < hits[iy, ix]) max_hits = hits[iy, ix]; } else { break; }
y = 2 * x * y + cy; x = xx - yy + cx; xx = x * x; yy = y * y; if (xx + yy >= ESCAPING) break; }
num_hits += 1; } }
// Draw the current image. private void DisplayBrot(int wid, int hgt, int max_r, int max_g, int max_b, int[,] hit_r, int[,] hit_g, int[,] hit_b) { Graphics gr = Graphics.FromImage(m_Bitmap); gr.Clear(Color.Black);
for (int y = 0; y < hgt; y++) { for (int x = 0; x < wid; x++) { int r = (int)Math.Round(hit_r[x, y] * scale_r); if (r > 255) r = 255; int g = (int)Math.Round(hit_g[x, y] * scale_g); if (g > 255) g = 255; int b = (int)Math.Round(hit_b[x, y] * scale_b); if (b > 255) b = 255;
m_Bitmap.SetPixel(x, y, Color.FromArgb(255, r, g, b)); } }
Comments