Search code examples
algorithmfractalsmandelbrot

improper mandelbrot set output plotting


i am trying to write a code to display Mandelbrot set for the numbers between (-3,-3) to (2,2) on my terminal. The main function generates & feeds a complex number to analyze function. The analyze function returns character "*" for the complex number Z within the set and "." for the numbers which lie outside the set.

The code:

#define MAX_A   2       // upperbound on real
#define MAX_B   2       // upper bound on imaginary

#define MIN_A   -3      // lowerbnd on real
#define MIN_B   -3      // lower bound on imaginary

#define NX      300     // no. of points along x
#define NY      200     // no. of points along y

#define max_its 50
int analyze(double real,double imag);
void main()
{
double a,b;
int x,x_arr,y,y_arr;
int array[NX][NY];

int res;

for(y=NY-1,x_arr=0;y>=0;y--,x_arr++)
{
 for(x=0,y_arr++;x<=NX-1;x++,y_arr++)
        {
        a= MIN_A+ (  x/( (double)NX-1)*(MAX_A-MIN_A) );
        b= MIN_B+ (  y/( (double)NY-1 )*(MAX_B-MIN_B) );
        //printf("%f+i%f ",a,b);        
        res=analyze(a,b);

        if(res>49)
                array[x][y]=42;
        else
                array[x][y]=46;


        }
//      printf("\n");

}

for(y=0;y<NY;y++)
        {
        for(x=0;x<NX;x++)
                printf("%2c",array[x][y]);
        printf("\n");
        }

}

The analyze function accepts the coordinate on imaginary plane ; and computes (Z^2)+Z 50 times ; and while computing if the complex number explodes, then function returns immidiately else the function returns after finishing 50 iterations;

  int analyze(double real,double imag)
    {
     int iter=0;
     double r=4.0;

            while(iter<50)
            {
                    if (  r < ( (real*real) + (imag*imag) )  )
                    {
                            return iter;
                    }
                    real=  ( (real*real) - (imag*imag) + real);
                    imag=  ( (2*real*imag)+ imag);
                    iter++;
            }
            return iter;

    }

So, i am analyzing 60000 (NX * NY) numbers & displaying it on the terminal considering 3:2 ratio (300,200) , i even tried 4:3 (NX:NY) , but the output remains same and the generated shape is not even close to the mandlebrot set :

enter image description here

hence, the output appears inverted , i browsed & came across lines like:

   (x - 400) / ZOOM;
   (y - 300) / ZOOM;

on many mandelbrot codes , but i am unable to understand how this line may rectify my output.

i guess i am having trouble in mapping output to the terminal!

(LB_Real,UB_Imag) --- (UB_Real,UB_Imag)
    |                       |
(LB_Real,LB_Imag) --- (UB_Real,LB_Imag)

Any Hint/help will be very useful


Solution

  • The Mandelbrot recurrence is zn+1 = zn2 + c.

    Here's your implementation:

    real=  ( (real*real) - (imag*imag) + real);
    imag=  ( (2*real*imag)+ imag);
    

    Problem 1. You're updating real to its next value before you've used the old value to compute the new imag.

    Problem 2. Assuming you fix problem 1, you're computing zn+1 = zn2 + zn.

    Here's how I'd do it using double:

    int analyze(double cr, double ci) {
        double zr = 0, zi = 0;
        int r;
        for (r = 0; (r < 50) && (zr*zr + zi*zi < 4.0); ++r) {
            double zr1 = zr*zr - zi*zi + cr;
            double zi1 = 2 * zr * zi + ci;
            zr = zr1;
            zi = zi1;
        }
        return r;
    }
    

    But it's easier to understand if you use the standard C99 support for complex numbers:

    #include <complex.h>
    
    int analyze(double cr, double ci) {
        double complex c = cr + ci * I;
        double complex z = 0;
        int r;
        for (r = 0; (r < 50) && (cabs(z) < 2); ++r) {
            z = z * z + c;
        }
        return r;
    }