Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!deimos.cis.ksu.edu!uxc.cso.uiuc.edu!uxc.cso.uiuc.edu!ux1.cso.uiuc.edu!uxe.cso.uiuc.edu!burkie From: burkie@uxe.cso.uiuc.edu Newsgroups: comp.lang.c Subject: Re: Mandlebrot set Message-ID: <225800193@uxe.cso.uiuc.edu> Date: 25 Jun 89 23:16:10 GMT References: <2492@blake.acs.washington.edu> Lines: 99 Nf-ID: #R:blake.acs.washington.edu:2492:uxe.cso.uiuc.edu:225800193:000:3247 Nf-From: uxe.cso.uiuc.edu!burkie Jun 25 04:37:00 1989 >double >func(real, imag) >double real, imag; >{ > int n; > double newreal, newimag, re2, im2; > > for (n = 0; n < MAX_ITER; n++) { > if ((re2 = real * real) + (im2 = imag * imag) > 4.0) > break; /* point is not in Mandelbrot set */ > > /* Xn+1 = Xn^2 + Xn */ > newreal = re2 - im2 + real; > newimag = 2.0 * real * imag + imag; > if (newreal == real && newimag == imag) { > n = MAX_ITER; > break; > } > } > return n; >} I think there is something missing in the above code. ----------------------- The general algorithm is: given complex number: c z = 0 { do (z = z ^ 2 + c) until |z| > 2 } <--- don't check beyond MAX_ITER iterations; assume beyond MAX_ITER is for all practical purposes 'stuck forever' return the number of iterations it took for |z| to exceed 2 and if never exceeded 2 during the MAX_ITER iterations that we tried then return MAX_ITER ------------------------ double func(c_real, c_imag) double c_real, c_imag; /* c = (c_real + i*c_imag) */ { int n; /* iteration count */ double z_real, z_imag, /* z = (z_real + i*z_imag) */ re2, im2; /* z_real^2 , z_imag^2 */ z_real = 0; z_real = 0; n = 0; while ( (n < MAX_ITER) && ((re2 = z_real * z_real) + (im2 = z_imag * z_imag) <= 4.0) ) { /* iterate z = z^2 + c */ /* = (z_real + i*z_imag)^2 + (c_real + i*c_imag) */ z_imag = 2.0 * z_real * z_imag + c_imag; z_real = re2 - im2 + c_real; n++; } /* if n < MAX_ITER then |z| exceeded 2 after iteration n * (and 'c' is definitely not in mandelbrot set) * if n = MAX_ITER then we were not able to see it diverge * (so we may assume it is part of mandelbrot set) * (for lack of knowing any better) */ return(n); } ---------------------------- I realize most people already know this but here is a short explanation: the mandelbrot set is the set of c's in the complex plane which never diverge when iterated in the manner described above. (i.e. the z remains finite, oscillating between values, converging to a value etc. destined never to escape beyond the circle) in most pictures of the mandelbrot set - the set is colored black and other areas are colored according to the number of iterations it took for the condition |z| > 2 to be reached using the 'c' value at that point. the condition |z| > 2 guarantees that future iterations of z = z^2 + c will diverge more and more away and so we use it as a convenient condition to test for divergence. however for certain points 'c' it may take a very long time to verify that |z| eventually exceeds 2 and for some this condition may never become true (those points which are truly within the mandelbrot set) So, to avoid waiting forever for this condition, we only test upto MAX_ITER iterations and then if |z| still < 2 , we assume for our purposes that the z never diverges and give up testing further for divergence. (and include 'c' in the mandelbrot set) the more detailed your examination of the boundary of the mandelbrot set, the higher MAX_ITER will have to be to give a good representation. For a given pixel resolution, MAX_ITER beyond a certain value will not increase the apparent accuracy of the picture and will only slow down the program. -Salman burkie@uxe.cso.uiuc.edu