-7

I wrote a program that is supposed to draw the Mandelbrot fractal. Unfortunately, it seems to be drunk. Here is the output:

Failed Mandelbrot

The relevant function:

void drawMandelbrot(float x, float y, float width, float height, float delta) {
    for (float currentX = -2; currentX < 2; currentX += delta) {
        for (float currentY = -2; currentY < 2; currentY += delta) {
            Complex z(0, 0);
            Complex c(currentX, currentY);
            int iterations = 0;

            do {
                z = z * z + c;
                ++iterations;
            }
            while (z.getAbsoluteValue() <= 2 && iterations < MANDELBROT_ITERATION_LIMIT);

            ALLEGRO_COLOR pixelColor;
            float pixelX = (currentX + 2) / 4 * width;
            float pixelY = (currentY + 2) / 4 * width;

            if (z.getAbsoluteValue() <= 2) {
                pixelColor = blackColor;
                // Commented because you might not want this much junk in your terminal
                //std::cout << "Stayed small! " << z.toString() << std::endl;
            } else {
                pixelColor = al_color_hsv(iterations / MANDELBROT_ITERATION_LIMIT, 1.0f, 1.0f);
                // idem
                //std::cout << "Blew up! " << z.toString() << std::endl;
            }
            al_draw_pixel(pixelX, pixelY, pixelColor);
        }
    }
}

I believe the Complex::operator... methods are correct, I suspect a logic error in the above function. When checking the output of the above (commented) std::cout statements, the absolute values of the complex numbers in the output is indeed less than 2, yet the image doesn't look like the plotted mandelbrot set.

Where is the wrong condition?


An mcve is included in the edit history.

11684
  • 7,356
  • 12
  • 48
  • 71
  • 1
    What is the question ? – Arkapravo May 10 '15 at 16:21
  • 2
    What are we supposed to be doing? Compiling, executing and debugging your code? – Oliver Charlesworth May 10 '15 at 16:22
  • @Arkapravo There must be some logic error in `drawMandelbrot()`. All the picture I saw of the Mandelbrot set I saw online look a lot more symmetrical. Will edit. – 11684 May 10 '15 at 16:22
  • @OliverCharlesworth I admit it is a lot of code, but last time I encountered a logic problem in an isolated function, the feedback I got was "post an mcve", although the question was correctly answered before I could edit it into the question. This time, I thought to include it up front, but due to the complex number maths the "minimum" is still a lot. I was hoping somebody would look at `drawMandelbrot()` and spot an off-by-one mistake or similar. – 11684 May 10 '15 at 16:28
  • 1
    I would write some unit tests to verify your assertion that the Complex class is correct. – Oliver Charlesworth May 10 '15 at 16:29
  • 2
    Why did you write your own Complex class instead of std::complex? – Puppy May 10 '15 at 16:30
  • Increase your `MANDELBROT_ITERATION_LIMIT` and cast at least one operand to float before doing the division `iterations / MANDELBROT_ITERATION_LIMIT`. – Klemens Baum May 10 '15 at 16:31
  • @Puppy 1) I didn't know until the std::complex class until now, 2) as an exercise. – 11684 May 10 '15 at 16:31
  • You removed the code with the error in it :) – Alfred Rossi May 10 '15 at 16:34

1 Answers1

1

Your calculation of the complex modulus is incorrect.

float Complex::getAbsoluteValue() const {
    return sqrt(real * real + imaginary + imaginary);
}

You've since removed this section of your post, but it should say

float Complex::getAbsoluteValue() const {
    return sqrt(real * real + imaginary * imaginary);
}
Alfred Rossi
  • 1,942
  • 15
  • 19