|Mandelbrot Zoomer in WPF|
|Written by Mike James|
|Thursday, 23 July 2015|
Page 1 of 4
The Mandelbrot set is fun, but implementing a simple viewer in WPF can be a challenge.Here's a project to plot the Mandelbrot set and allow the user to zoom in on any area of interest.
The Mandelbrot set is fun but implementing a simple viewer in WPF can be a challenge. The reason is that WPF is essentially a vector graphics system and the natural way to think of plotting the Mandelbrot set is to plot pixels.If you would like some background reading on fractals and the Mandelbrot set in particular then see - Fractals
In this project we plot the Mandelbrot set and allow the user to zoom in on any area of interest. The zooming is done "live" in the sense that the area is recomputed rather than simply zooming in to a pre-computed image.
The general programming topics covered in this project include:
The Mandelbrot set
The actual Mandelbrot computation is very easy.
In fact it is this very simplicity that makes it so amazing that something so complex is the end product.
If you consider a small 2D region centred on (0,0) i.e. the origin, then a point (a,b) is in the Mandelbrot set if the iteration:
does not diverge to infinity where c=a+ib and z is a general complex number of the form x=x+iy.
(Recall that i is a number such that i2=-1).
To compute the Mandelbrot set all we do is start off with a number c and an initial value for z, usually 0, and then replace z by its square plus c.
This operation is repeated, generating a sequence of z values. Either z gets bigger and bigger, in the sense of moving away from the origin, or it doesn't. If it doesn't then it is in the Mandelbrot set.
Until .NET 4.0 our next problem would have been finding a good way of doing complex arithmetic in C#. However, in .NET 4.0 a Complex type was introduced and we can now simply create complex variables and do complex arithmetic more or less as written in the usual notation.
For more details see Not so complex numbers in C#.
The only real problem concerns deciding when the iteration has resulted in a value which is going off to infinity and when it has not. B
Putting all this together we have the following algorithm:
Translating this into a function is fairly easy:
To make this work we have to load a reference to the System.Numerics assembly. Right click on References in the Project Explorer window and select Add References. Also add:
to the start of the program.
There’s very little to add to the earlier comments about this function except the fact that it returns the value of count. If count equals 1000 then the point is in the Mandelbrot set and any other value gives you a measure of how quickly the point goes off to infinity.
The value of count is often used to colour the non-Mandelbrot points according to how fast they shoot off to infinity and we will return to this topic when we get to plotting the set.
Now that we have the function that computes what we want to plot, the next part of the project is all about displaying the result and allowing the user to zoom in on sections of the plot.
The program was developed in a stepwise fashion but to save the trouble of having to keep on explaining a revised version to I’m going to present each part complete with everything need to make the whole work even if it doesn’t make much sense until later.
Place button on the window and set its content to "Reset". Next place a Canvas panel on the window and an Image control with it. Set the Image control to 400 by 400. The XAML should read something like:
The key idea is that we are going to use a Rect struct to specify the area that is going to be plotted. Notice that the area to be plotted is specified using standard Cartesian, i.e. x,y, co-ordinates which correspond to a complex value by the usual z=x+iy relationship.
The rectangle being plotted will have to be available to other methods so we have to declare is as a property:
This is initialised to an area that provides a good initial view of the Mandelbrot set - found by trial and error.
The initial display can be constructed as soon as the application is loaded so we might as well put a call to the method that does the plotting into the main window's constructor:
Now we have to write the drawSet method.
|Last Updated ( Thursday, 23 July 2015 )|