Draw a Mandelbrot set fractal in C#

The Mandelbrot set uses an iterated equation to calculate colors for the points in a region. The equation is:

    Z(n) = Z(n-1)2 + C

Here the Z(n) and C are complex numbers.

It can be shown that, if the magnitude of Z(n) ever exceeds 2, then it eventually diverges towards infinity.

To find the color for the point (x, y), the program sets Z(0) = 0 and C = x + y * i. It then generates values for Z(n) until Z(n)’s magnitude exceeds 2 or it reaches some predetermined maximum number of iterations. At that point, the program uses the number of iterations it performed to assign the point’s color. For example, if the program is using K colors and it performed I iterations, then it assigns the point color number I mod K.

The following code shows how the program draws the Mandelbrot set.

// Draw the Mandelbrot set.
private void DrawMandelbrot()
    // Work until the magnitude squared > 4.
    const int MAX_MAG_SQUARED = 4;

    // Make a Bitmap to draw on.
    m_Bm = new Bitmap(picCanvas.ClientSize.Width, picCanvas.ClientSize.Height);
    Graphics gr = Graphics.FromImage(m_Bm);

    // Clear.
    picCanvas.Image = m_Bm;

    // Adjust the coordinate bounds to fit picCanvas.

    // dReaC is the change in the real part
    // (X value) for C. dImaC is the change in the
    // imaginary part (Y value).
    int wid = picCanvas.ClientRectangle.Width;
    int hgt = picCanvas.ClientRectangle.Height;
    double dReaC = (m_Xmax - m_Xmin) / (wid - 1);
    double dImaC = (m_Ymax - m_Ymin) / (hgt - 1);

    // Calculate the values.
    int num_colors = Colors.Count;
    double ReaC = m_Xmin;
    for (int X = 0; X < wid; X++)
        double ImaC = m_Ymin;
        for (int Y = 0; Y < hgt; Y++)
            double ReaZ = Zr;
            double ImaZ = Zim;
            double ReaZ2 = Z2r;
            double ImaZ2 = Z2im;
            int clr = 1;
            while ((clr < MaxIterations) && (ReaZ2 + ImaZ2 < MAX_MAG_SQUARED))
                // Calculate Z(clr).
                ReaZ2 = ReaZ * ReaZ;
                ImaZ2 = ImaZ * ImaZ;
                ImaZ = 2 * ImaZ * ReaZ + ImaC;
                ReaZ = ReaZ2 - ImaZ2 + ReaC;

            // Set the pixel's value.
            m_Bm.SetPixel(X, Y, Colors[clr % num_colors]);

            ImaC += dImaC;
        ReaC += dReaC;

        // Let the user know we//re not dead.
        if (X % 10 == 0) picCanvas.Refresh();

    Text = "Mandelbrot (" +
        m_Xmin.ToString("0.000000") + ", " +
        m_Ymin.ToString("0.000000") + ")-(" +
        m_Xmax.ToString("0.000000") + ", " +
        m_Ymax.ToString("0.000000") + ")";

The program allows you to zoom in on areas of the set and to pick the color palette it uses to draw. If you resize the program or change the colors, use the Scale menu’s Refresh command to redraw the fractal.

The program lets you save its image in the usual formats (bmp, jpg, png, etc.). If you resize the form and redraw, you can make a really big version of the image you’re viewing. Download the example to see the details.

For more information on fractals, including information about the fascinating Julia set that uses the Mandelbrot set as a map, see my book Visual Basic Graphics Programming. The code is in Visual Basic 6 so you’ll have to do some translating but the math still works. (I’ve had no luck trying to get my publisher, Wiley, to let me make a .NET version of the book. If you would buy a C# version of the book, let me know.)

This entry was posted in algorithms, fractals, graphics, mathematics and tagged , , , , , , , , , , , . Bookmark the permalink.

5 Responses to Draw a Mandelbrot set fractal in C#

  1. Pingback: Use a Complex number class to draw a Mandelbrot set fractal easily in C# |

  2. Rostja From Russia says:

    Algorithm can be improved in all possible ways. One is to make a check before loop “while”. If a point is in main cardioid then we go after all checks and paint a pixel with color of the Mandelbrot set. Some piece of code:

    if (Math.Sqrt((ReaC - 0.25) * (ReaC - 0.25) + ImaC * ImaC) <
        (0.5 - 0.5 *Math.Cos(Math.Atan2(ImaC, ReaC - 0.25))))
        m_Bm.SetPixel(X, Y, Mandelbrot_set_color);
        goto AfterAllChecks;
    • RodStephens says:

      There are ways to improve the code, but that wasn’t really the point. This is an introduction.

      Other improvements would be to use faster code to create the bitmap and to use multiple cores. I’ll leave those to you. 😉

  3. comm says:

    “dReaC” – no need for such long descriptive variable names imo

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.