During the CS106A Stanford course, students are proposed a graphics contest. One of the worst winner’s score is upgraded. The exercise is assessed on two key dimensions: aesthetic and algorithmic sophistication. I decided to accept the challenge as an on-line student. Aesthetic, algorithmic, graphics and computer science make me think about fractals. I had only a very general knowledge of fractal at the beginning of this exercise.
[UPDATE: the winner of this contest for the quarter that has been recorded for the online course had coded a Fractal explorer too]
SHORT PRESENTATION OF THE MANDELBROT SET
I guess that half of the students of Stanford have chosen a similar topic. I would probably not have gained the best mark of creativity. Anyway, fractals are a major computer related topic and it is time to know a little more about them and geek this subject.
One of the most famous fractal is probably the Mandelbrot set. This fractal is pushed in the front in most fractal documentation. The name comes from the mathematician that worked on it, Benoît Mandelbrot. The concept is relatively new and has been popularized in the early years of graphics computing, thank to the amazing pictures that it can produce.
So what is it? To go to the point directly, this set is the set of the complex points (c), for which the following sequence is bounded:
The magic is operated by the extraordinary complexity of the projection of this set on the complex plan, compared to this simple and petty equation. Simple if you know what a complex plan is, of course.
Mathematically speaking, the sequence is bounded or not. A given point can only have 2 states (in the set or out of the set). Most illustrations of the set use intermediate colors to describe at which pace the sequence tends to infinite. This is a common way to present a third dimension in a two dimension plan, like a computer screen. By convention, the black color is reserved for the point included in the set.
GENERAL CONSIDERATIONS AND ARCHITECTURE OF THE PROGRAM
Given a center position and a zoom level, each pixel of the the window will be colored according to the equation. When clicking somewhere on the screen, the display will be zoomed in by a factor of 2, and centered where the click has been done. This feature will allow the user to explore the amazing universe of the set.
The conversion between the pixel position and the value of the complex number is a simple translation. I could have decided to do it the other way around, starting from an area of the complex plan, and determine the value of a pixel. I found it more convenient this way.
Infinity is not easily manageable by computers. A property of the sequence will make it trivial. If the absolute value of an element of the sequence is greater than 2, the sequence is not bounded. This property will be used to define the pace at which the sequence escape for a given point. The pace will just be the number of iterations before reaching 2.
So the general idea is to determine how many iterations are required to reach 2, for each pixel and color this last accordingly. The maximum number of iteration is set as a variable. If this number is reached, the sequence is considered as not bounded.
SEQUENCE CALCULATION
Computers are not comfortable with infinity, but they are with sequence calculation. This is a really common algorithm problem to calculate the value of a sequence and to determine how many steps are required to top a target value. The only tricky point is that the sequence deals with complex numbers.
Surprisingly enough, there is no API for dealing with complex numbers. You can do it without managing complex numbers, but as coding style is part of the assessment I have decided to create a class for complex numbers. Anyway, this is really more fun like that.
This class has two variables, the real and the imaginary parts, and the following methods:
- setters and getters for both parts, and initiators
- (void)equalTo(ComplexNumber): set to an already existing complex number
- (double) absolute(): calculate the absolute value
- (ComplexNumber) addToComplex(ComplexNumber): return a new complex number after an addition
- (ComplexNumber) multiplyToComplex(ComplexNumber) : return a new complex number after a multiplication
- (ComplexNumber) pow2(): return a new complex number for the square
This class helps for a good decomposition of the program. Each method can easily be developed individually. Each terms of the sequence are computed using a combination of the methods.
COLORS PROCESSING
So at this point of the program, I’m able to generate a huge matrix containing the number of iterations for each pixel. It’s time to give them colors.
Compared to the first part, this step has not been easy mainly because I did not know anything about managing colors on a screen. In my mind, the idea was to give a significant color to the pixel, not just a color, like in a temperature color diagram.
My starting point was the RGB color model, probably the most famous one. In this model, each color are defined as a combination of intensity for each component (red, green and blue). After a couple of trials, I realized that there was no easy method to do what I wanted. Then I found the HSL and HSV color models. That was exactly what I needed.
In this model, a color is described with three components, closer to what a human can manipulate:
- Hue: describes the color, just the color, in an angular scale. In this scale, 0 is red, 270 is blue. From 0 to 270, this scale gives color variations similar to a temperature color diagram. From 270 to 360, the color spans from purple to red, which I find not natural.
- Saturation: estimates the proportion of “pure color”. With a full saturation, the hue is displayed. With a null saturation, the gray projection of the hue is rendered.
- Value or lightness: describes a kind of exposition to light. When close to 0, the final color is black.
HSL and HSV are two different color systems, with a lot of similarities.
The coloration for a given number of iterations can be determined by the hue. The hue is 0 for a low number of iterations, and 270 for the maximum number of iterations. All intermediate numbers are extrapolated. To avoid mixing low number of iterations with high number of iterations, hue values between 270 and 360 are not used.
As explained in the introduction, the black should be used for points where the sequence is bounded. To render that, the lightness has to be modify too. In the final version, the rules are as follow:
- between 0 and a low boundary: hue = 0 and lightness varies from 0 % to 100 %
- between a low boundary and a high boundary: hue varies from 0 to 270 and lightness = 100 %
- between a high boundary and the maximum number of iteration: hue = 270 and lightness varies from 100 % to 0 %
A special class has been created for this purpose, the “ColorSpectrum”. To use it, an object has to be initiated with the maximum number of iteration expected. A method returns the color, given the number of the iterations as a parameter.
Here is a color palette for a maximum value of 50, starting from 0:
Another color palette for a maximum value of 300, close to the end:
FINAL STEPS
It is now time to apply the color for each pixel of the area. Without any idea of what a good value for the maximum number of iterations would be, I tried 50 and that gives this picture:
Not bad at all! I find it convenient to display the coordinate in the complex plan of the center of the window (small white line in the right bottom corner). This is the render with a maximum value of 300:
The image is globally darker, but zooming capabilities are higher. A drawback of a higher value, is that the calculation is also badly increased.
FIRST EXPLORATIONS
The exploration of the set is really magnetic. The bolt shapes are beautiful, the main shape can be seen at several locations and at different size, the “coast” is covered with repeated shapes again and again.
Here are a couple of screenshots, you can guess where they have been caught.
The set has some fascinating properties:
- the area is bounded (easy to prove) but the perimeter is not
- the area has only been approximated
- between any part of the border, the distance is always infinite
- there is no isolated dots or “islands”
Feel free to contact me if you know a way to prove easily one of those properties.
Moreover, the shapes have something natural, not to say living. Many biological processes are driven by fractal behaviors. This is a good way to optimize the surface without increasing the weight. Think about lungs or trees …
FURTHER IMPROVEMENTS
The more developed the program is, the better chance I would have to win this contest. In this case, further developments can be considered:
- zoom out: probably the most expected feature
- display control: size of the window, number of maximum iterations, starting and ending colors, all constants could be manipulated directly by the user
- resource saving algorithm only the border is interesting, so large area could be approximated and not calculated (they take most of the calculation time)
- dynamic contrast: high number of iterations are required when zooming a lot, but are time consuming, so the number of iterations could be adapted to the zoom level
- soft gradation: even with a large number of iterations, the transitions are not smooth between numbers, this could be improved, considering the absolute value before escaping
- heat-map class: a kind of “heat-map” class can be developed and used to display the fractal, this class would have a matrix of number of iterations as a parameter
- fractal class: a general fractal class can be imagined … the Mandelbrot Set would simply extend it, overriding the method giving the number of iterations
- etc.
And leaving Java and dreaming a little bit, we could imagine to print fractals in three dimensions, using a 3D printer, like the Replicator 2 from Makerbot. You can also contact me if you have one, and are interested in trying.
ADDITIONAL RESSOURCES
My program can be downloaded here (.jar program, Java 6 required).
As fractals are half way between science, technology, art and design, Benoît Mandelbrot had to have his TED talk:
The post Mandelbrot fractal set explorer in Java appeared first on Zombie Brainz' Juice.