Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faster method for drawing in C#

Tags:

c#

winforms

I'm trying to draw the Mandelbrot fractal, using the following method that I wrote:

public void Mendelbrot(int MAX_Iterations)
{
    int iterations = 0;

    for (float x = -2; x <= 2; x += 0.001f)
    {
        for (float y = -2; y <= 2; y += 0.001f)
        {
            Graphics gpr = panel.CreateGraphics();

            //System.Numerics
            Complex C = new Complex(x, y);
            Complex Z = new Complex(0, 0);

            for (iterations = 0; iterations < MAX_Iterations && Complex.Abs(Z) < 2; Iterations++)
                Z = Complex.Pow(Z, 2) + C;

            //ARGB color based on Iterations
            int r = (iterations % 32) * 7;
            int g = (iterations % 16) * 14;
            int b = (iterations % 128) * 2;
            int a = 255;

            Color c = Color.FromArgb(a,r,g,b);
            Pen p = new Pen(c);

            //Tranform the coordinates x(real number) and y(immaginary number) 
            //of the Gauss graph in x and y of the Cartesian graph
            float X = (panel.Width * (x + 2)) / 4;
            float Y = (panel.Height * (y + 2)) / 4;

            //Draw a single pixel using a Rectangle
            gpr.DrawRectangle(p, X, Y, 1, 1);
        }
    }
}

It works, but it's slow, because I need to add the possibility of zooming. Using this method of drawing it isn't possible, so I need something fast. I tried to use a FastBitmap, but it isn't enough, the SetPixel of the FastBitmap doesn't increase the speed of drawing. So I'm searching for something very fast, I know that C# isn't like C and ASM, but it would be interesting do this in C# and Winforms.

Suggestions are welcome.

EDIT: Mendelbrot Set Zoom Animation

like image 428
Omar Avatar asked May 13 '26 01:05

Omar


2 Answers

I assume it would be significantly more efficient to first populate your RGB values into a byte array in memory, then write them in bulk into a Bitmap using LockBits and Marshal.Copy (follow the link for an example), and finally draw the bitmap using Graphics.DrawImage.

You need to understand some essential concepts, such as stride and image formats, before you can get this to work.

like image 110
Douglas Avatar answered May 14 '26 13:05

Douglas


As comment said put out CreateGraphics() out of the double loop, and this is already a good imrovement.

But also

  • Enable double buffering
  • For zooming use MatrixTransformation functions like:

    ScaleTransform

    RotateTransform

    TranslateTransform

An interesting article on CodeProject can be found here. It goes a little bit further than just function calls, by explaining actually Matrix calculus ( a simple way, don't worry), which is good and not difficult to understand, in order to know what is going on behind the scenes.

like image 20
Tigran Avatar answered May 14 '26 15:05

Tigran



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!