This project was developed for 42 school. For comprehensive information regarding the requirements, please consult the PDF file in the subject folder of the repository. Furthermore, I have provided my notes and a concise summary below.
+ keywords: similar repeated patterns
+ similarity occurs at different scales
+ leaf, trees, cauliflower, bronchial system, coast line
+ set of complex numbers (real + imaginary)
+ estable iteration
Graph from Geogebra, author Ben Sparks. "Simple exploration of the Mandelbrot Set (and the orbits of the iteration with different 'c' values). Stable orbits are coloured black. The colours 'outside' the set are determined by how quickly the iteration diverges..."
Visualization of the Mandelbrot and Julia iteration, made by Stefan Bion Click here
The Mandelbrot set, denoted M, is the set of complex numbers c
such that the critical point z = 0
of the polynomial
- Choose a maximal iteration number
N
; - For each pixel
p
of the image:
- Let
c
be the complex number represented byp
- Let
z
be a complex variable - Set
z
to0
- Do the following
N
times:
- If
|z|>2
then color the pixel white, end this loop prematurely, go to the next pixel - Otherwise replace z by
z*z+c
, a.k.a. iterate through the Mandelbrot formula
- If the loop above reached its natural end: color the pixel p in black
- Go to the next pixel
References:
Math University Toulouse
WikiBooks
The Nature of Code, chapter 8
Distance Estimator algorithm
Task | Prototype | Description |
---|---|---|
git submodule |
git submodule add git@github.com:shinckel/libft.git |
To add an external library to your project, it will generate a .gitmodules file. P.S. You must add targets to the Makefile! |
xquartz |
brew install --cask xquartz |
allows cross-platform applications using X11 for the GUI to run on macOS |
X11 |
x | enables users to run graphical applications on a remote server and interact with them using their local display and I/O devices |
Create canvas |
mlx_init() mlx_new_window() mlx_loop()
|
Initializes the MiniLibX library and assigns the mlx(connection with the graphical server); creates a new window using the specified width, height, and name, and assigns the window pointer to fractal.win ; enters the event loop of MiniLibX, which continuously listens for events such as key presses and mouse movements. This function call will keep the program running until the window is closed |
put some color |
for (int x = 0; x < fractal.width; x++) { for (int y = 0; y < fractal.height; y++) { mlx_pixel_put(fractal.mlx, fractal.win, x, y, bg_color); } } |
Manage the color pixel per pixel: graphical server - window pointer - x/y coordinates - color
|
handling events |
mlx_key_hook(fractal.win, deal_keys, (void *)0); |
Intercepting function calls or messages or events passed between software components. Code that handles such intercepted function calls, events or messages is called a hook. In this case, intercepting keyboard or mouse event |
scanline methods |
x | (a.k.a. raster scan) All pixels in the image will be scanned. For each pixel, the color has to be determined. The coordinates of the pixel are converted into mathematical parameters. Then an algorithm is run on that parameter |
aspect ratio |
width / height 4:3 320x40
|
display an image of a specific size, inside a rectangle that is another size(difference between image and container) |
double |
double zx double pi = 3.14159
|
to handle the floating-point calculations accurately |
orbit trap |
|
an orbit refers to a sequence of values generated by repeatedly applying a function or transformation to an initial value. Each value in the sequence becomes the input for the next iteration, and the process continues indefinitely or until a specific condition is met. The behavior of the orbit: does the point belong to the fractal set? does it tend to infinity, remain bounded, or exhibit certain patterns? |
Theorem |
The orbit of 0 tends to infinity if and only if at some point it has modulus >2 |
The modulus of a complex number measures its distance from the origin (0, 0) in the complex plane. Mathematically, if |
in the complex plane, x is the real axis, therefore the real component of z , and y is the imaginary axis, the imaginary component of z . To calculate zx , I will extract the first part of the formula: fractal->zx_new = zx * zx - zy * zy + fractal->cx; , and for zy : fractal->zy_new = 2 * zx * zy + fractal->cy;
|
||
modulus of |
zx * zx + zy * zy > 4.0 |
I don't need to calculate the square root of |
xarrow yarrow
|
c.x = (x + frac->xarrow) / frac->zoom * (0.47 + 2.0) / (WIDTH - 1) - 2.0; |
position horizontally xarrow and vertically yarrow relative to the pixel coordinates x y . These values are necessary for moving the drawing in the screen through the key hooks |
Mandelbrot boundary |
|
These are the coordinates of the outer boundary of the mandelbrot set. I can use it as value to establish its size in relation to the screen |
smooth colors |
escape time (how long does it take, a.k.a. number of iterations, before going to infinity?), color algorithms: the "bands" are generated because we can only set colors to pixels in discrete numbers of iterations, therefore the colors are divided as solid areas. The outermost solid color is the one out of the bailout radius. References: Plotting algorithms - Wikipedia, Renormalizing the Mandelbrot Escape, Mandelbrot Set Coloring Presentation, Draw a Mandelbrot set fractal with smoothly shaded colors in C# | |
42 docs |
BitShifting void my_mlx_pixel_put(t_data *data, int x, int y, int color)
|
In my opinion, these are two concepts really important for this project. The first, how RGB colors can be encoded in int format, the second, pushing images to a window instead of drawing pixel per pixel |
Julia set |
It is deeply connected to the Mandelbrot set, the same formula a.k.a patterns that emerge from the Mandelbrot map. Key concept: instead of the complex number |
|
hooks |
TAB = 65289 XK_Tab
|
key codes. For an improved version, I could use Keysyms instead. They are defined in two standard include files: <X11/keysym.h> and <X11/keysymdef.h>
|
color pallette |
rgb1 = ((int)(mu * 25) % 256) << 16; |
I could have more control of my get_color() results throught the establishment of a prior pallette. In my current implementation, I am multiplying my smooth value by a factor that produces variations in RGB values, and then normalizing it to the needed range (256 possible values in R, G and B). I could be much more efficient, see the example below in C++: |
private Color GetColor(double mu)
{
int clr1 = (int)mu;
double t2 = mu - clr1;
double t1 = 1 - t2;
clr1 = clr1 % Colors.Count;
int clr2 = (clr1 + 1) % Colors.Count;
byte r = (byte)(Colors[clr1].R * t1 + Colors[clr2].R * t2);
byte g = (byte)(Colors[clr1].G * t1 + Colors[clr2].G * t2);
byte b = (byte)(Colors[clr1].B * t1 + Colors[clr2].B * t2);
return Color.FromArgb(255, r, g, b);
}