Mandelbrot Fractal Program

Tools/hotkeys

Mandelbrot set: The Mandelbrot set is the set of complex numbers c for which the function does not diverge when iterated from z =0, i.e., for which the sequence, etc., remains bounded in absolute value. In simple words, Mandelbrot set is a particular set of complex numbers which has a highly convoluted fractal boundary when plotted. Benoit Mandelbrot was a Polish/French/American mathematician who has spent most of his career at the IBM Watson Research Center in Yorktown Heights, N.Y. He coined the term fractal and published a very influential book, The Fractal Geometry of Nature, in 1982. An image of the now famous Mandelbrot set appeared on the cover of Scientific. I think you might not see fractals as an algorithm or something to program. Fractals is a concept! It is a mathematical concept of detailed pattern repeating itself. Therefore you can create a fractal in many ways, using different approaches, as shown in the image below. Choose an approach and then investigate how to implement it. Introduction Fractal To Desktop renders the Mandelbrot Set onto your desktop. The Mandelbrot Set is defined by the equation Z^2+C. If you’ve seen the video on the homepage, this probably makes no sense. How can an equation this simple create shapes like the Mandelbrot Set? Complex Numbers Firstly, Z and C are not normal numbers. The Mandelbrot Fractal. The mandelbrot set is a subset of the complex numbers. When visualized on the complex plane, it gives the familliar image often referred to as the 'gingerbread man'. The image to the right, is a direct plot of the mandelbrot set on the complex plane, black points are elements of the set, while white points are not.

Max. iterations This value describes how many times the script is allowed to iterate each pixel. The higher the value, the better the resolution, but more time is required to generate.
X offset This value sets the offset for the generated set along the x axis. Higher numbers push the set to the right, and lower numbers push it to the left.
Y offset This value sets the offset for the generated set along the y axis. Higher numbers push the set to the bottom, and lower numbers push it to the top.
Zoom This value sets the zoom for the set. The lower the number, i.e. closer to zero, the further into the set, and the higher the number, further out from the set.
S - Scale mode Click and drag to select a part of the fractal. You can move the selection around if needed. Click enter to generate, escape to cancel.
M - Move mode Drag the entire rendered image. If a different zoom value is input, a rectangular selection box will appear in the center to ease framing.
E - Escape mode Move your cursor over the set. The script will display the positions of complex numbers for each cycle of the rendering algorithm until it escapes. A popup will also appear that displays the absolute value of each complex number in a plot to show how the input escapes, which happens when the line hits the top of the plot area.
I - Info mode Move your cursor over the set. The script will display the amount of iterations and position for that point.
G - Generate Generate a new set. Edit the function in the function panel.
F - Function (ordinary) Edit the function used to render a fractal. It's not picky with the input, but requires one constant for a Mandelbrot set (power, default is 2), and two or more constants for Julia sets. Note that the script automatically selects which settings are input if only two constants are present. z2-0.5 will be parsed as z2-0.5+0i and z2-0.5i as z2+0-0.5i, for instance.
F- Function (advanced) Edit the function, but with more advanced input. This mode supports more advanced mathematical operations to describe constants in Julia sets, such as trigonometry, roots, and variables (x and y).
C - Color scheme Set a different color scheme for your set. The mod value describes how often colors are repeated.
U - get URL Get the shareable URL for your set!
Esc Pretty basic stuff. Closes popups.
Enter Generate new set.

About - Mandelbrot and Julia sets

Complex numbers Mandelbrot/Julia sets are fractals based on the properies of complex numbers, written as a+bi, where a and b are real numbers and i is an imaginary unit, equal to the square root of -1. For the record, bi=b*i, which makes bi an imaginary number, with b as a 'real number coefficient'. All complex numbers can be plotted in a two-dimensional coordinate system, the complex plane, where a represents values on the real axis (x-axis), and bi represents the imaginary axis, thus taking on the role of the y-axis in the normal coordinate system. Every complex number in the system is represented by a point. 2+3i is a point two steps away from the origin along the x-axis, and three steps away from the origin along the y-axis, for instance.
How Mandelbrot sets are generated pt. 1: Iterations The mandelbrot set follows this formula: z2+c, where z is the complex number from the previous iteration (I'll explain what that means in a second), and c is the complex number described by the point that is generated. Okay, this sounds confusing, so let's begin with c. A generated set is an image, and so contains a lot of pixels. Imagine each of those pixels is a point in the complex plane, which makes each pixel describe a complex number c which changes for every pixel position in the image. Now, I said z was the result of the previous iteration, so here's how this works: We start by saying z=0 (0+0i, if you're pedantic; this initial value is also called the orbit of the function, and for mandelbrot sets, this is always 0), and so z2+c=c. Now, take the result (=c) and put it into the formula, c2+c=d. Again: d2+c=e, and again, e2+c=f, etc. c,d,e, and f are all complex numbers. The next step is to investigate how these new numbers behave.
How Mandelbrot sets are generated pt. 2: Escape time Okay, let's investigate these new numbers. We need to get a grasp of where these new numbers lie in the complex plane, so we use the absolute value of the complex number. The absolute of a complex number is the hypotenuse in a right triangle with sides a and b (i.e. the components in the complex number). abs(c)=sqrt(a2+b2). The good thing is that we get a single value, and best of all, it's a real number!. If the absolute is small, that means that the complex number is close to the origin, and the opposite if the absolute is large. It has been proven that if the absolute exceeds 2, no new generated complex number will have an absolute value less than 2, and thus diverge to infinity. If, for any value of c, the sequence diverges, it doesn't belong to the Mandelbrot set. If, on the other hand, no new number reaches an absolute of 2+ during a set number of iterations, it does. The time (number of iterations) it takes for a series to reach abs(z2+c)>2 is called the escape time.
How Mandelbrot sets are generated pt. 3: Colors This part is a little easier than generating the set. If the sequence remains bounded, i.e. no complex number in the series has an absolute value larger than 2, that pixel is colored black to show it belongs in the set. Conversely, if it has escaped, a color is picked according to escape time, which is denoted as a number. The number is then placed on a color scale, and depending on where it is on the scale, a color value can be read. This is what causes those beautiful color gradients!
What about Julia sets, then? The mandelbrot set uses the form z2+c, and Julia sets use the form z2+a+bi, with the first value of z=c, instead of 0 (which as you might know by now, is the orbit of Mandelbrot sets). That's the main difference. Instead of a variable (ex. c), a Julia set uses a single complex number for each pixel. Otherwise, they're generated the same way as Mandelbrot sets.
Searching for a higher power? The Mandelbrot set was first defined as z2+c, but any other power will work, such as z4+c. This web app accepts any integer power value larger or equal to 2. For power 2, the code uses a simple formula to generate the next number. For higher powers, this becomes inefficient, as you need to loop through the algorithm. Fortunately, there exists a formula, de Moivre's formula, which lets you put in any integer power and outputs the complex number in polar form, which is a different way to describe complex numbers than a+bi (read more about polar form here). This way, Mandelbrot/Julia sets with powers exceeding, say, 100 are fully possible to generate in reasonable time.

About - code

This is roughly how the script iterates input values for sets with power 2: //Set complex numbers and generate for each pixel
for (var h=0;h<height;h++){ //Generate each row
for (var w=0;w<width;w++){ //Generate each pixel in that row
//Below: set coordinate value based on pixel position and zoom
a2=(w-width/2-xOff/zoom)/(500/zoom);
b2=(h-height/2-yOff/zoom)/(500/zoom);
if (isMandel){ //if Mandelbrot set, assume orbit 0
a=a2;
b=b2;
}else{ //if Julia set, assume orbit a2+b2i, set c to constant
a=julA;
b=-julB;
}
//iterate for pixel
pixels.push(generateIndividual()); //generateIndividual returns the iteration count for that pixel.
}
}
function generateIndividual() for power 2 with cartesian coordinates: //Iterate (power 2)
for (var i=0;i<max_iterations;i++){
if (a2*a2+b2*b2>=4){
return i; //return escape time
}
/*Below: follow rule (a+b)^2=a^2+2ab+b^2 -> (a+bi)^2=a^2+2abi-b^2
Suppose c is a complex number d+ei, and (a+bi)^2+c=a^2+2abi-b^2+d+ei, thus a^2-b^2+d(real part, a2) and 2*(a+bi)+ei(imaginary part, b2)*/

aTmp=a2;
a2=a2*a2-b2*b2+a;
b2=2*(aTmp*b2)+b;
}
return -1; //signifies a number belonging to the set
function generateIndividual() for powers >2 with polar coordinates using de Moivre's formula: //Iterate (power 2+)
for (var i=0;i<max_iterations;i++){
if (a2*a2+b2*b2>=4){
return i; //return escape time
}
v*=power;
magnitude=Math.pow(Math.sqrt(a2*a2+b2*b2),power) //IE does not, of course, support Math.hypot.
a2=magnitude*Math.cos(v)+a;
b2=magnitude*Math.sin(v)+b;
}
return -1; //signifies a number belonging to the set

About - creator / license

This web app was written by PicturElements, starting in June 2016.
License:
MIT License
Copyright © 2016, PicturElements
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.




'The Mandelbrot Set is the most complex object in mathematics, its admirers like to say. An eternity would not be enough time to see it all, its disks studded with prickly thorns, its spirals and filaments curling outward and around, bearing bulbous molecules that hang, infinitely variegated, like grapes on God's personal vine.'
[James Gleick, 'Chaos: Making a New Science']

Almost everyone reading this article has no doubt encountered pictures from the Mandelbrot Set, like the one above. Their appeal is not limited to the mathematician, and their breathtaking beauty has found its way onto posters, T-shirts and computers everywhere. Yet what is a fractal? How do these dusty old maths equations create such pretty pictures? If you look in most library books onfractals and chaos, you'll soon find the pretty pictures on the cover give way to talk of iterations, complex numbers and mapping .

This article will show exactly what your computer does. If you have some skill at programming, you will find this article very helpful. But don't worry if you aren't a programmer, all my code examples are well commented and you should be able to figure them out. I have also included a few links to source code and a fully compiled program. More on that later.

Benoit B. Mandelbrot, born in Poland in 1924, started experimenting with Julia sets in the late 1970s, and placed great pressure on the computers of the time, demanding more memory, more power to clean up the grainy images that appeared on the monitor screen. Back then computers were very primitive, anddrawing pretty fractals would have taken a lot more effort! These days even humble old PCs can easily do better.

Mandelbrot Fractal Program

Mandelbrot fractal program

The algorithm for defining the Set is really quite simple. I am assuming here that the reader is at least partly familiar with complex numbers. If this is not the case, try back issues of PASS Maths or your local library.

  1. Let be a complex constant, defined according to the position on screen.

  2. Let be our first complex iteration.

  3. Iterate once by letting .

  4. Repeat step 3 until one of the following occurs:

    • (a) The modulus (length) of exceeds a given value. This is our test for divergence.

    • (b) The number of iterations exceeds a given value. This is how we assume convergence.

  5. Draw the point with colour determined by the number of iterations. Often the convergent points are drawn in black.

If all this talk of convergent and divergent iterations is making your head spin, don't worry! All will be explained later.

All my example code is in Turbo Pascal, since although I am learning to code in C, I don't know enough yet to draw pretty graphics. I'd best explain a few peculiarities of the language for those unfamiliar.

Firstly, I have placed plenty of comments to explain what goes on. These are the bits of text in {squiggly brackets}. In C you would use /* this notation */ for the same effect. Comments are not important and can be omitted in your own programs, but it is good practice to explain your programs for both others and yourself, much later, when you want to come back to them.

Secondly, the variable type real is just Pascal's version of C's float. I could have opted for singles or doubles, both of which are faster, but they would have required compiler directives and I'm trying to keep the program as simple to follow as possible. Any other obscure commands will be explained in the program.

I apologise for the video mode I have used in this program. I wanted to use a graphics mode that had at least 256 colours, but since SVGA modes are a headache and a half to access in Turbo Pascal I have used a mode with rather 'chunky' pixels. This is mainly to keep the program from getting too complicated. I hope I have succeeded!

If you haven't already done so, download and look at the source code for mbrot1.pas. This is a simple first program to introduce you to the basics before we get into complicated matters like 'zooming in' on interesting details. The {commented} bits of the program are rather self-explanatory, but even so I will now explain what the program does.

The first interesting part of the program is the list of variables (after the word var for non-Pascal programmers). Many of these values are never changed throughout the program, such as limit, cx and cy. Why did I use them?

There are two reasons. The first is that this way, if you follow the same method in your own program you can experiment with exploring the Mandelbrot Set by simply changing these starting values. The variables cx and cy are the centre of our viewpoint. The scale value is how much we are 'zoomed in' by - if you make this value smaller it will bring you 'closer' to the Set, make it bigger andyou will 'zoom out'.

The second reason for using variables instead of constant values is that later on we will look at an improved version of the program, with a limited zoom ability. In other words, they are for expansion.

Now look down to the section that starts with repeat and ends with the until (...) statement. This is the main loop of the program, and each pass through it the equation is iterated once. Each time the until (...) statement checks to see if it has either converged or diverged.

Some people may be wondering why I use such a complicated expression to check for divergence. As a demonstration, consider the source code for mbrot1a.pas. In this version, I used the simpler expression abs(a1) + abs(b1) to check for divergence. The effect is shown below:

The effect of 'cheating' on the maths!

The thing about the Mandelbrot Set that enthrals even non-mathematicians is that the more you zoom in on the image, the more beautiful the images become, and yet the same pattern seems to emerge. Our program so far isn't that useful - if we want to explore we have to half-guess the new starting conditions and recompile the entire program. Next I will show a basic system of zooming in. Once youhave the idea I have no doubt that you could improve upon it! To keep our program as simple as possible, zooming is very basic. If you haven't done so yet, download the source code for source code for mbrot2.pas.

This is an identical program to the previous version, but has had several new procedures added to provide a primitive zooming facility. When the Set has finished drawing, press Q to quit or the spacebar to bring up a crosshair. Move the crosshair left with Z, right with X, up with K and down with M, and when you have chosen the point to look closer at, press the spacebar again and the zoomdoubles! As the zoom level increases the time needed to redraw can get longer, so be patient. If you haven't got access to a programming language, the compiled versions of all three source codes are included and will run under DOS or Windows. I can't guarantee results for anything else, but if demand is great I'll try to write a C version, which should be pretty universal!

There are three main areas of note in this program. Firstly, notice the getpix function. It is not important for you to understand it, simply know that it returns the colour of a pixel at the given screen co-ordinate.

This is used for the second item of interest. Notice the section of code

in the draw_cross procedure. The xor statement is an 'exclusive or', and is used to perform bit comparisons. It compares each pair of bits in the numbers and returns 1 if they are different, and 0 if they are the same. The curious effect of this statement, since 255 is made entirely of 1s in binary, is that taking a number xor 255 will 'switch' all the bits in the number. And if we do this again,we get the original colour back. This trick is used simply so that moving the crosshair doesn't destroy the picture underneath!

The third item to consider is the keyboard routine. Why did I use letter keys instead of the arrow keys? The simple answer is that arrow keys are special functions and need to be treated with more care. Letters are simpler to code in, and as I keep stressing, I'm trying to keep this code as simple as possible!

So how does this bigger program work? Most of the new procedures are simply for drawing and moving the crosshair, and reading in the user's keypresses. The main zoom is just three lines in the select_point procedure:

The first two lines change the centre of our window onto the Set. The third line halves the scale, which means our main routine squeezes twice as much detail into the same size screen - in effect, doubling the zoom level!

This series of pictures demonstrates a simple delve into the Mandelbrot Set with my program! These were obtained by running the program under Windows 95 and using the PrintScrn button. The white rectangle shows where the next zoom is centred (the crosshair is in the centre of the rectangle).

This program is far from perfect. However, I hope you now have some idea of how the basic algorithms work, and can write your own programs to use them. Here are a few suggestions for you to consider:

The examples here use a rather primitive graphics mode, so I could get plenty of colours whilst avoiding messy encounters with SVGA. The assembly language procedures needed to draw anything with it are a rather unfortunate side effect. With these days of Windows programming and Direct X, most of the hassle of using graphics in programs is neatly removed. You should be able to write muchbetter, more accurate programs with far less effort!

I avoided changing the colours used by my program because things like palette changes would only make the program more complicated. However, feel free to change the colours in your own Mandelbrot Set programs.

The user interface is quite horrible. I could have used a mouse, or at least the arrow keys on the keyboard, but I avoided this because it would have meant more difficult code to study. Mouse routines are not standard in Turbo Pascal and need more dipping into assembly, for example. I would be quite disappointed if your programs used an interface like this one! Some suggestions forimprovements include allowing different zoom levels, changing the accuracy required and displaying some kind of menu or button system.

Mandelbrot Fractal Program

The program is also quite slow. I mentioned earlier that I could have used singles or doubles instead of real variables, but I avoided this because it requires using compiler directives in the program. If you know about numerical coprocessors and the like, feel free to change this (the speed increase is about three-fold!) and if you are writing in another programming language this may not be aproblem for you.

Mandelbrot Fractal Program

Mandelbrot Fractal Programs

Fractal
  • Chaos by James Gleick, Minerva, 1996.

Related Sites

MandelbrotMandelbrot Fractal Program
The Mandelbrot Set
Interactive viewer for the Mandelbrot set for readers with a Java-compatible browser.
Mandelbrot images
Some dramatic images from the Mandelbrot set by Andy Burbanks, interviewed in our The art of numbers in Issue 8 and author of our feature article Extracting beauty from chaos in this issue.

About the author

Andrew Williams is an undergraduate student taking a BSc in Mathematics at the University of Sussex.