Wikibooksβ

Pictures of Julia and Mandelbrot Sets/Computer programs

We will show two ways of making a program that can draw a Mandelbrot set where the iterations are towards ∞: a program where all is done from the ground, but which does nothing more than drawing a single picture, and a program where you can do all you desire (zoom, alter colouring and render as file), but where these facilities are handed over to another program, namely Ultra Fractal.

Section of the Mandelbrot set for z2+0.009/z+c{\displaystyle z^{2}+0.009/z+c}

Let us make a program that is as simple as possible: it draws a single picture, and does nothing more (when it has done its work it closes). It was originally written in assembly language, but here we write it in pseudo-code. It consists of two parts: the drawing procedure and the colour scale.

We draw a section of the Mandelbrot set for the family f(z)=z2+pz+c{\displaystyle f(z)=z^{2}+{\frac {p}{z}}+c\,}, for p = 0.009. We let the size of the window be 800x600 pixels, and we imagine that the section has its lower left corner in the point with coordinates (ax, ay) and that is has width h. We have f′(z)=2z−pz2{\displaystyle f'(z)=2z-{\frac {p}{z^{2}}}\,}, so that the finite critical point we need, is solution to the equation z3=p/2{\displaystyle z^{3}=p/2}. We choose the real solution cri = (p/2)1/3{\displaystyle (p/2)^{1/3}}.

The drawing procedure

p = 0.009

cri = (p/2)1/3{\displaystyle (p/2)^{1/3}}

r = 1.0E200 (square of the bail-out radius)

u = log(log(r))

v = 1/log(2) (2 is the degree of the rational function)

ax = -0.7028233689263 (x-coordinate of lower left corner)

ay = 0.1142331238418 (y-coordinate of lower left corner)

h = 0.0092906805859 (width of the section)

g = h / 800

m = 850 (maximum iteration number)

thick = h * 0.0005 (thickness of the boundary)

dens = 24.9 (density of the colours)

disp = 432.0 (displacement of the colour scale)

for i = 0 to 799 do

begin

cx = ax + i * g (x-coordinate of pixel (i, j))

for j = 0 to 599 do

begin

cy = ay + j * g (y-coordinate of pixel (i, j))

x = cri

y = 0

xd = 0

yd = 0

f = 0

n = 0

while (n < m) and (f < r) do

begin

n = n + 1

x1 = x * x - y * y

y1 = 2 * x * y

f = x * x + y * y

x2 = 2 * x - p * x1 / (f * f)

y2 = 2 * y + p * y1 / (f * f)

temp = xd

xd = x2 * xd - y2 * yd + 1

yd = x2 * yd + y2 * temp

fd = xd * xd + yd * yd

x = x1 + p * x / f + cx

y = y1 - p * y / f + cy

f = x * x + y * y

end

if (n = m) or (log(f) * sqrt(f) < thick * sqrt(fd)) then

setpixel(i, 599 - j, 0)

else

begin

s = n - v * (log(log(f)) - u)

n = round(dens * s + disp) mod 720

col = paletteRGB(col1[n], col2[n], col3[n])

setpixel(i, 599 - j, col)

end

end

end

Explanation

We have set c=cx+icy{\displaystyle c=cx+icy}, z=x+iy{\displaystyle z=x+iy}, z′=xd+iyd{\displaystyle z'=xd+iyd} and x1+iy1=(x+iy)2{\displaystyle x1+iy1=(x+iy)^{2}}, and we have used that 1/z=z−/|z|2{\displaystyle 1/z=z^{-}/|z|^{2}}.

The successive calculation of the derivative z' is xd+iyd=(x2+iy2)∗(xd+iyd)+1{\displaystyle xd+iyd=(x2+iy2)*(xd+iyd)+1}, where x2+iy2=2∗(x+iy)−p∗(x1−iy1)/(f∗f){\displaystyle x2+iy2=2*(x+iy)-p*(x1-iy1)/(f*f)} and f=x2+y2{\displaystyle f=x^{2}+y^{2}}. The next point in the iteration is x+iy=(x1+iy1)+p∗(x−iy)/f+(cx+icy){\displaystyle x+iy=(x1+iy1)+p*(x-iy)/f+(cx+icy)}. The distance function is

log(√f)*√f/√fd (= log(f)*√f/(2*√fd))

for the last z-value, here f=x2+y2{\displaystyle f=x^{2}+y^{2}} and fd=xd2+yd2{\displaystyle fd=xd^{2}+yd^{2}}. The number in the interval [0, 1[ to be subtracted from the iteration number (in order to get the real iteration number), is log(log(|z|)/log(r))/log(2)=v∗(log(log(f))−u){\displaystyle log(log(|z|)/log(r))/log(2)=v*(log(log(f))-u)}, for the last z, here v=1/log(2){\displaystyle v=1/log(2)} and u=log(log(r)){\displaystyle u=log(log(r))}.

paletteRGB(r, g, b) is the integer indexing the colour with RGB-values (r, g, b), 0 gives black. col, col2 and col3 are the arrays from 0 to 719 of integers from 0 to 255 constructed in the next section.

The colour scale

A colour is immediately (in the computer) given by its composition of the three primary colours red, green and blue, and their shares are measured in whole numbers between 0 and 255. This triple of numbers is the set of RGB values of the colour. The colours correspond accordingly to the entire points in a cube with side length 256, and we construct our cyclic colour scala by going regularly along an ellipse in this cube. An ellipse in the space is determined by:

a centre with coordinates (a, b, c)

a major axe rmaj and a minor axe rmin

two angles angle g and h determining the direction of the plane of the ellipse

Ultra Fractal is a program for drawing fractals where the user to a great extent can write his own formula programs and where the main program performs all that is common for all the fractal procedures, that is, the procedure of going from pixel to pixel, zooming, colouring, production of a large picture as a file. Your effort is reduced to a minimum, and apart from pictures that cannot be drawn regularly from pixel to pixel - attractors and landscapes, for instance - you can do all you desire: non-complex functions, quaternions, ... You can operate directly with complex numbers.

For the drawing two programs have to be combined: a formula program and a colouring program. In the formula program is a section called loop, and when this loop has done its work, the number of iterations and the last value of the complex number z are transferred to the colouring program, which calculates the colour from these two numbers. However, Ultra fractal is designed to "all" types of fractals, and unfortunately the Julia and Mandelbrot sets do not quite fit into this form: for iterations towards cycles, the iteration has to be continued in order to find the order and the attraction of the cycle, and it is not the last value of z in the sequence we do use for the colour. Therefore we replace this loop by a fictive loop (which only runs one time) and perform all the operations in the section init. This implies that we cannot use the default colouring program of Ultra Fractal, we must write a new colouring program.

Another thing you must be aware of, is that in Ultra Fractal the norm |z| of the complex number z is the square of its length: |z| = x2+y2{\displaystyle x^{2}+y^{2}}.

Section of the Mandelbrot set for z2/2+0.26∗z4+c{\displaystyle z^{2}/2+0.26*z^{4}+c}

We will show a program that draws the Mandelbrot set for the family f(z)+c{\displaystyle f(z)+c}, where f(z){\displaystyle f(z)} is a polynomial whose first two terms are zero, so that it begins with z2{\displaystyle z^{2}} or a larger power of z, because we then can take 0 as the finite critical point.

The two programs can be copied and inserted in an empty formula and colouring document, respectively. We have inserted the polynomial z2/2+p∗z4+c{\displaystyle z^{2}/2+p*z^{4}+c} of degree 4, where p is a real parameter. The picture shows a section of the Mandelbrot set for p = 0.26.

We have set the square of the radius r of the bail-out circle to 1010{\displaystyle 10^{10}}, and set the thickness of the boundary to "thick/(1000 * #magn)", so that it becomes thinner when we zoom in.

We have calculated the derivative f(z){\displaystyle f(z)} by (f(z+h)−f(z))/h{\displaystyle (f(z+h)-f(z))/h} for a small number h, namely "h = 1/(1500*#magn*width)", where "width" is the width of the picture. The default value is the width of the window in pixels (here set to 640), but if you draw a large picture, you should enter the width of this.

The successive calculation of the derivative zk+1′=f′(zk)zk′+1{\displaystyle z'_{k+1}=f'(z_{k})z'_{k}+1} is "zd = (f(z+h) - f(z)) * zd / h + 1". The next iteration zk+1=f(zk)+c{\displaystyle z_{k+1}=f(z_{k})+c} is "z = f(z) + #pixel". The square of the distance estimation log|zk|∗|zk|/|zk′|{\displaystyle log|z_{k}|*|z_{k}|/|z'_{k}|} is "sqr(log(|z|)) * |z| / |zd|". The number to be subtracted from the iteration number log(log(|zk|)/log(r))/log(deg){\displaystyle log(log(|z_{k}|)/log(r))/log(deg)} is "v * (log(log(|z|)) - u)", where "v = 1/log(deg)" and "u = log(log(r))".

The final complex number z (to be transferred to the colouring program), which here actually is real, is set to -1, when the point belongs to the Mandelbrot set or to the boundary, otherwise it is set to the real iteration number. It is transferred to the colouring program, which we have called Gradient, as #z, and is here set equal to the real number s. When s is negative the colour is set to "#solid", otherwise we multiply s by a number "dens" determining the density, and add to this number a number "disp" determining the displacement of the scale, and as we want this displacement to be a per cent, we divide the result by 100: "u = (dens * s + disp) / 100". In Ultra Fractal the colours of the cyclic colour scales are indexed by the real numbers in the interval [0, 1[, and we let this number, "#index", be the non-integral part of the number u: "#index = u - trunc(u)".