Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

42 Project : Fract'ol

License

NotificationsYou must be signed in to change notification settings

PedroZappa/42_fractol

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fract'ol

This project is about creating graphically beautiful fractals.

Fractol Demo Overview

Table o'Contents

About 📌

Fract'ol is the first computer graphics project of the Common Core curriculum.

It is a simple graphics program usingminilibx, an opportunity to learn how to use the mathematical notion ofcomplex numbers, have a first contact with the concept ofoptimization in computer graphics, andevent handling.


Mandatory Features

  • General

    • The program must take the type of the fractal to be displayed as a parameter and any other relevant option.
    • The program must display the fractal in the window powered byminilibx.
    • The project must contain aMakefile that compiles all sources. It must not relink.
    • Global variables are forbidden.
  • Rendering

    • The program must offer theJulia andMandelbrot sets.
    • The mouse wheel zooms in and out almost infinitely, within the limits of the computer.
    • A differentJulia set must be rendered if the program is passed the appropriate parameters.
    • A parameter passed on startup must be the type of the fractal to be rendered.
      • Adding more parameters is optional.If no parameter is provided, or the parameters are invalid, it displays the help page and exits cleanly.
    • A few different color schemes must be implemented.
  • Graphic Management

    • The program has to display the image in a window.
    • The management of the window must remain smooth.
    • PressingESC must close the window and exit the program in a clean way.
    • Clicking on the cross on the top window frame must have the same effect.
    • It is mandatory to useimages fromminilibx.

Bonus Features

  • One extra fractal.
  • The zoom follows the mouse position.
  • Moving the view by pressing the arrow keys.
  • Make the color range shift.

Implementation 📜

Before anything else, themain() function declares at_display variable nameddisplay that stores all the necessary data, conveniently packed to be passed around the program.


t_display Structure

typedefstructs_display{// mlx Datavoid*mlx_conn;// Stores pointer to mlx connectionvoid*mlx_win;// Stores pointer to mlx windowt_imgimg;// Stores the image dataintwidth;// Stores the width of the windowintheight;// Stores the height of the windowt_rangewin_size;// Stores the size of the windowdoublex_offset;// Stores how much to shift when moving the viewdoubley_offset;// Stores how much to shift when moving the viewdoublezoom;// Stores the zoom factor// Fractal Datachar*name;// Stores the name of the fractalintset;// Stores the type of fractallongiter;// Stores the number of iterationst_complexz;// Stores z for Mandelbrot/Julia/Tricorn/Burning Shipt_complexc;// Stores c for Mandelbrot/Tricorn/Burning Shipt_complexc_julia;// Stores c for Juliat_complexz_newton;// Stores z for Newtont_rangefrac_range;// Stores the range of the complex planedoubleescape;// Stores the complex plane escape valuedoublenewton_esc;// Stores escape value for Newtont_rangecolor_iter;// Stores a range of 0 to n iterationst_rangecolor_range;// Stores a range from black to whiteintcolor;// Stores a color for the Newton fractal}t_display;

ft_args.c : Argument Parsing Functions

The main logic for argument parsing can be found inside theft_args.c file.

ft_no_args() andft_args() are used to parse the input arguments and ensure that if there is something wrong the program exits correctly (without memory leaks).

if (argc<2)return (ft_no_args());elseif (!ft_args(&display,argc,argv))exit(EXIT_FAILURE);

ft_no_args()

If the program is passed no arguments:

  • It prints an error tostderr;
  • Displays the help page and exits cleanly.

ft_args()

Checks if the arguments passed are valid.

intft_args(t_display*d,intargc,char**argv){if (!ft_select_fractal(d,argc,argv))return (ft_invalid_args(argv[1]));if (!ft_set_args(d,argc,argv))return (0);return (1);}
  • First checks if the fractal type selected is valid.
  • Then attempts to set the input arguments:

ft_select_fractal()

This function checks if the fractal type is valid.

  • It first converts the fractal type (first argument) to lowercase.
  • If it is valid,ft_set_fractal() is called and the function outputs 1.
  • If it is NOT valid it outputs 0.

ft_set_args()

Here we make sure we got the right number of arguments and check if they are the right type before the program initializes anything.

  • First checks the iterations argument:

    • If the 2nd argument is a valid input for the number of iterations, we set it tod->iter. In case it is a negative value a default value is set instead.
    • Otherwise the program prints an error tostderr and exits.
  • Then we check for the Julia case in which we get a complex number as the third and fourth arguments.

    • If the input arguments are a valid doubles we set them tod->c_julia.r andd->c_julia.i.
    • Otherwise the program prints an error tostderr and exits.

ft_init.c : Initialization Functions

After all validation tests are passed, the program callsft_init_display().


ft_init_display()

ft_init_display(&display,argv);

It initializes:

  • themlx connection intod->mlx_conn by callingmlx_init();
  • themlx window intod->mlx_win by callingmlx_new_window();
  • the image pointer intod->img.img by callingmlx_new_image();
  • the image pixels intod->img.pix by callingmlx_get_data_addr();

All these calls are properly protected by calls to cleanup functions in case a initialization error arises.

After everything is properly allocated we proceed to initialize theevent handling functionality.


ft_init_events()

This function initializes threeevent handlers to be triggered when certain events are received:


ft_kill_handle();
  • Listens forDestroyNotify event;
    • Destroys the image data;
    • Destroys themlx window;
    • Destroys themlx connection;
    • Frees thet_display pointer to themlx_conn;

ft_handle_keys();
  • Listens forKeyPress events;
    • IfEscape is received, it exits by callingft_kill_handle();
    • If the arrow keys are pressed,ft_handle_offsets() is called;
    • IfPageUp orPageDown are pressed, thed->iter is increased or decreased by 1 respectively;
    • IfSpace,1,2,3,4,5 are pressed,ft_swith_set() is called.
    • IfLeft-Shift,Right-Shift,r,g orb are pressed,ft_switch_color() is invoked.
    • Else if the key press received is not being handled, a message with the keysym value is printed tostdout.
    • If an event was successfully caughtft_render() is called causing a re-render of the window.

ft_handle_mouse();
  • Listens forButtonPress events;
    • If the left mouse button is pressed inside the window when on the Mandelbrot set the fractal settings are changed and a re-render is triggered with a Julia set with itsc set to the current mouse position;
    • Else if the right button is pressed the window re-renders the Mandelbrot set.
    • Else if the mouse wheel is scrolled up or downft_handle_zoom() is called.

Note

Understandingft_handle_zoom() :

Centering & Scaling

The keys to zooming in computer graphics are :

  • Adjusting the view's center, by changing thed->x_offset andd->y_offset;
  • Adjusting the view's scale, by changing thed->zoom factor;

Mouse Position & Zoom Center

Thex andy coordinates of the mouse are used to determine the zoom center;

  • This is done by mapping the mouse position to the range of the complex plane;

Zoom Factor & Scaling

  • The zoom factor (SCALE_FACTOR) determines how much the view is scaled with each zoom operation.
  • Increasing the zoom level, dividesd->zoom value by theSCALE_FACTOR, enlarging the view;
  • Decreasing the zoom level, multipliesd->zoom value by theSCALE_FACTOR, shrinking the view.
  • fabs() is used to ensure that the scale factor is always positive, regardless of the current zoom level.

Offset Adjustment

  • The offset adjustment (0.13 * fabs(d->zoom)) is a scaling factor that controls how much the view is moved in response to zooming.
  • This factor is multiplied by the mapped mouse position to ensure that the zoom center is adjusted proportionally to the zoom level, providing a smoother and more controlled zooming.

Now that we got the X connection, the window and event handling up and running all there is left to do it the data initialization.


ft_init_data()

In this function we initialize the data inside thet_display structure to be passed and used by the program.

ft_init_display(&display,argv);

Check outft_init.c andfractol.h for a closer look at what is being initialized and to what values.


ft_usage()

Theft_usage() function prints the usage of the program and all available commands tostdout.

ft_usage();

ft_render()

This is where the pixel-by-pixel drawing of the window takes place.

ft_render(&display);
  • It iterates over each pixel in the window;
  • Selects the rendering function based on the chosen fractal type;
  • For each pixel it evaluates the function describing the selected set;
while (++y <=HEIGHT){x=-1;while (++x<WIDTH)ft_select_set(d,x,y);ft_printf("\r%sRendering:%s [%d%%]",YEL,NC, ((y*100) /d->height));}ft_printf("\t%sComplete!%s\n",MAG,NC);
  • Once the calculations are donemlx_put_image_to_window() is called to render the image to the window.
mlx_put_image_to_window(d->mlx_conn,d->mlx_win,d->img.img,0,0);
  • Thenft_render_ui() is called to print a simple UI to the window.
ft_render_ui(d);

Note

This is a function that can produce memory leaks if the usage offt_itoa() andft_strjoin() are not handled correctly. Take a look for yourself atft_ui.c for details.


mlx_loop()

Finally, the program enters an infinite loop, keeping the window open listening for user events.

mlx_loop(d->mlx_conn);

Usage 🏁

First, clone the contents of this repository over SSH:

git clone git@github.com:PedroZappa/42_fractol.git

Then, make sure that the program is compiled with all its dependencies usingmake:

make

One way to find out all available startup options and keybindings, is to run the program without arguments:

./fractol

Testing 🧪

If you want to test the program withvalgrind, you can use the followingmake rule:

make valgrind

There is also a convenientmake rule to run aNorminette check:

make norm

Appendixes


MinilibX 🪟

MinilibX is a small library, a simplified version ofXLib (X11R6) written in C , designed to introduce students to theX-Window System.1


X-Window System

TheX-Window System is an architecture independent windowing system for bitmap displays that provides a basic framework for creating graphical user interfaces.2 It enables users to draw and move windows on a display using the mouse and keyboard.

Note

In computing, abitmap (also known asbit array orbitmap index) is a mapping from a given domain (for instance, a range of integers) to bits.3


X client-server Architecture

X is based on a client-server model:

  • oneX server connects to multipleX client programs.
flowchart TBDisplay[Display]Keys[Keyboard]Mouse[Mouse]Keys[Keyboard] --->|input| Xserv[X Server]Mouse[Mouse] --->|input| XservDisplay[Display] <---|output| Xservsubgraph W[User Workstation]Xserv[X Server]Xserv --> X-client[X client1]Xserv --> X-client2[X client2]endsubgraph Remote MachineXserv -->|Network Conn| X-client3[X client3]end
Loading

The X Server receives requests to output graphics on the display (through windows) and sends back user input (from a keyboard, mouse, etc).

Note

There are many implementations of the X Window System (Xlib), minilibx being just one among many following the X Consortium standard;4


Complex Numbers

Complex numbers are numbers in the form(a + bi) where:

  • a is the real part:
  • b is the imaginary part;
  • i is the imaginary unit, defined by the equation$i^2 = -1$.

Note

$i = \sqrt-1$


Complex Arithmetic

Like with real numbers, we can performarithmetic on complex numbers.


Addition

$(a + bi) + (c + di) = (a + c) + (b + d)i$

Example of how to add two complex numbers:

$((3 - 4i) + (2 + 5i)) =$

$((3 + 2) + (-4 + 5)i) =$

$(5 + i)$


Subtraction

$(a + bi) - (c + di) = (a - c) + (b - d)i$


Multiplication

Multiplication is similar to multiplying binomials but with complex numbers we work with the real and imaginary parts separately.

Complex * Real

$c(a + bi) = (c * a) + (c * b)i$

Example:

$3(6 + 2i) =$

$(3 * 6) + (3 * 2i) =$ # Distribute

$(18 * 6i)$ # Simplify


Complex * Complex

$(a + bi)(c + di) = ac + adi + bci + bdi^2$

  • Because$i^2 = -1$, we can simplify the expression to:

$(a + bi)(c + di) = ac + adi + bci - bd$

  • Simplifying, we combine the real parts, and then the imaginary parts:

$(a + bi)(c + di) =$

$(ac - bd) + (ad + bc)i$

Example:

$(4 + 3i)(2 - 5i) =$

$(4 * 2) + (4 * (-5i)) + (3i * 2) + (3i * (-5i)) =$

$8 - 20i + 6i - 15i^2 =$

$8 + 15 - 20i + 6i =$

$(23 - 14i)$


Expanding a Complex Number

Here is an example on how to expand a squared complex number:

$(a + bi)^2 =$

$(a * a) + (a * bi) + (a * bi) - (bi * bi)$

$(a^2 - bi^2) + 2(a * bi))$

  • The real part is$(a^2 - b^2)$;
  • The imaginary part is$2(a * bi)$;

Complex Plane

We can take complex numbers and plot them in a plane known as theComplex Plane.

This plane is formed by the mapping of the real and imaginary parts of a complex number to a Cartesian coordinate system. The real part mapped to thex-axis and the imaginary part to they-axis.


Fractals

Fractals are infinitely complex self-similar patterns across multiple scales.

Generated by:

  • Initializing a complex number$z = (x + yi)$ where:$i^2 = -1$
  • x andy are image pixel coordinates mapped to a range between -2 to 2.
  • A formula is iterated until the value of|z| becomes greater than2.
    • If the point never escapes the range it IS considered to be part of the set.
    • If the point escapes the range it means it is NOT part of the set.
    • The color of each pixel is determined by the number of iterations it took to escape the set.

Julia Set

Formula :$f(z_{n+1}) = z_n^2 + c$

There are infinitely many Julia sets. To generate them, we use the same complex numberc for all pixels.

  • For each pixel in the image:
    • z is initially set to 0.
    • z is updated repeatedly following the formula$z_{n+1} = z^2 + c$.
    • c is a complex number that seeds a specific Julia set.

Julia Fractol Demo


Mandelbrot Set

Formula :$f(z_{n+1}) = z_n^2 + c$

For the Mandelbrot set, we use different complex numbers for each pixel. It is the one map to all Julia sets.

  • For each pixel in the image:
    • z is initially set to 0.
    • z is updated repeatedly following the formula$z_{n+1} = z^2 + c$.
    • c is a complex constant defined as:$c = (x + yi)$ where:$i^2 = -1$

Mandelbrot Fractol Demo


Burning Ship Set

$f(z_{n+1}) = (|{Re}(z_n)| + |{Im}(z_n)|i)^2 + c$

The Burning Ship Set is generated by the equation above where:

  • $z_n$ is the current complex number;
  • c is a complex constant (just like in the Julia Set formula);
  • $z_{n+1}$ is the next complex number in the sequence;
  • The real and imaginary components are set to their absolute values before squaring at each iteration.

This modification results in the distinctive "burning ship" appearance of the fractal.

Burning Ship Fractol Demo


Tricorn Set

Formula :$f(z_{n+1}) = \overline{z_n}^2 + c$

The Tricorn fractal is a variant of the Mandelbrot set and is characterized by its triangular shape. It is generated by using a slightly different formula where:

  • The complex conjugate ofz is squared instead ofz itself.
  • The complex conjugate ofz is represented by$\overline{z_n}$
  • c is a complex constant that varies for each pixel in the image.

Note

To get thecomplex conjugate of a complex number$z_n = (a + bi)$, we simply invert the sign of the imaginary part like so:$\overline{z_n} = (a - bi)$

For example: The conjugate of(4 + 7i) is(4 - 7i).

Tricorn Fractol Demo


Footnotes

Footnotes

  1. The Fractal Geometry of Nature - Benoit B. Mandelbrot - Google Livros

  2. Are Fractals or Fractal Curves Differentiable?

  3. How to Draw Fractals by Hand: A Beginner's Guide

  4. Complete List of Books by Benoit Mandelbrot


[8]ページ先頭

©2009-2025 Movatter.jp