I'm trying to visualize Mandelbrot set with OpenGL and have found very strange behaviour when it comes to smooth coloring.
Let's assume, for the current complex valueC
, algorithm have escaped after n
iterations when Z
had been proven to be more than 2.
I programmed coloring part like this:
if(n==maxIterations){
color=0.0; //0.0 is black in OpenGL when put to each channel of RGB
//Points in M-brot set are colored black.
} else {
color = (n + 1 - log(log(abs(Z)))/log(2.0) )/maxIterations;
//continuous coloring algorithm, color is between 0.0 and 1.0
//Points outside M-brot set are colored depending of their absolute value,
//from brightest near the edge of set to darkest far away from set.
}
glColor3f(color ,color ,color );
//OpenGL-command for making RGB-color from three channel values.
The problem is, this just don't work well. Some smoothing is noticable, but it's not perfect.
But when I add two additional iterations (just found this somewhere without explanation)
Z=Z*Z+C;
n++;
in the "else"-branch before calculating a color, the picture comes out to be absolutely, gracefully smooth.
Why does this happen? Why do we need to place additional iterations in coloring part after checking the point to be in set?
I'm not actually certain, but I'm guessing it has something to do with the fact that the log of the log of a number (log(log(n))
) is somewhat of an unstable thing for "small" numbers n
, where "small" in this case means something close to 2. If your Z
has just escaped, it's close to 2. If you continue to iterate, you get (quickly) further and further from 2, and log(log(abs(Z)))
stabilizes, thus giving you a more predictable value... which, then, gives you smoother values.
Example data, arbitrarily chosen:
n Z.real Z.imag |Z| status color
-- ----------------- ----------------- ----------- ------- -----
0 -0.74 -0.2 0.766551 bounded [nonsensical]
1 -0.2324 0.096 0.251447 bounded [nonsensical]
2 -0.69520624 -0.2446208 0.736988 bounded [nonsensical]
3 -0.31652761966 0.14012381319 0.346157 bounded [nonsensical]
4 -0.65944494902 -0.28870611409 0.719874 bounded [nonsensical]
5 -0.38848357953 0.18077157738 0.428483 bounded [nonsensical]
6 -0.62175887162 -0.34045357891 0.708867 bounded [nonsensical]
7 -0.46932454495 0.22336006613 0.519765 bounded [nonsensical]
8 -0.56962419064 -0.40965672279 0.701634 bounded [nonsensical]
9 -0.58334691196 0.26670075833 0.641423 bounded [nonsensical]
10 -0.4708356748 -0.51115812757 0.69496 bounded [nonsensical]
11 -0.77959639873 0.28134296385 0.828809 bounded [nonsensical]
12 -0.2113833184 -0.63866792284 0.67274 bounded [nonsensical]
13 -1.1032138084 0.070007489775 1.10543 bounded 0.173185134517425
14 0.47217965836 -0.35446645882 0.590424 bounded [nonsensical]
15 -0.64269284066 -0.53474370285 0.836065 bounded [nonsensical]
16 -0.6128967403 0.48735189882 0.783042 bounded [nonsensical]
17 -0.60186945901 -0.79739278033 0.999041 bounded [nonsensical]
18 -1.0135884004 0.75985272263 1.26678 bounded 0.210802091344997
19 -0.29001471459 -1.7403558114 1.76435 bounded 0.208165835763602
20 -3.6847298156 0.80945758785 3.77259 ESCAPED 0.205910029166315
21 12.182012228 -6.1652650168 13.6533 ESCAPED 0.206137522227716
22 109.65092918 -150.41066764 186.136 ESCAPED 0.20614160700086
23 -10600.782669 -32985.538932 34647.1 ESCAPED 0.20614159039676
24 -975669186.18 699345058.7 1.20042e+09 ESCAPED 0.206141590396481
25 4.6284684972e+17 -1.3646588486e+18 1.44101e+18 ESCAPED 0.206141590396481
26 -1.6480665667e+36 -1.263256098e+36 2.07652e+36 ESCAPED 0.206141590396481
Notice how much the color value is still fluctuating at n in [20,22], getting stable at n=23, and consistent from n=24 onward. And notice that the Z values there are WAY outside the circle of radius 2 that bounds the Mandelbrot set.
I haven't actually done enough of the math to be sure that this is actually a solid explanation, but that would be my guess.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With