{"id":18877287,"url":"https://github.com/pedrozappa/42_fractol","last_synced_at":"2025-09-24T02:23:15.696Z","repository":{"id":226243782,"uuid":"749719731","full_name":"PedroZappa/42_fractol","owner":"PedroZappa","description":"42 Project : Fract'ol","archived":false,"fork":false,"pushed_at":"2024-03-19T16:19:05.000Z","size":129680,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-03-19T17:38:23.204Z","etag":null,"topics":["42","42born2code","42cursus","c","fractol","fractol-42","gdb","make","minilibx"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PedroZappa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-01-29T09:03:26.000Z","updated_at":"2024-04-15T11:08:16.921Z","dependencies_parsed_at":"2024-03-19T17:49:52.803Z","dependency_job_id":null,"html_url":"https://github.com/PedroZappa/42_fractol","commit_stats":null,"previous_names":["pedrozappa/42_fractol"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedroZappa%2F42_fractol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedroZappa%2F42_fractol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedroZappa%2F42_fractol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PedroZappa%2F42_fractol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PedroZappa","download_url":"https://codeload.github.com/PedroZappa/42_fractol/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239833540,"owners_count":19704628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["42","42born2code","42cursus","c","fractol","fractol-42","gdb","make","minilibx"],"created_at":"2024-11-08T06:18:00.156Z","updated_at":"2025-09-24T02:23:15.685Z","avatar_url":"https://github.com/PedroZappa.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"**Note** : If you found this repo you should stop for a second and [read this](https://atomys.me/en/s42-sunset-story/)\n\n\u003ca name=\"readme-top\"\u003e\u003c/a\u003e\n\u003cdiv align=\"center\"\u003e\n\n# Fract'ol\n\n This project is about creating graphically beautiful fractals.\n\n\u003cp\u003e\n    \u003cimg src=\"https://img.shields.io/badge/score-%20%2F%20100-success?style=for-the-badge\" /\u003e\n    \u003cimg src=\"https://img.shields.io/github/repo-size/PedroZappa/42_minitalk?style=for-the-badge\u0026logo=github\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/languages/count/PedroZappa/42_minitalk?style=for-the-badge\u0026logo=\" /\u003e\n    \u003cimg src=\"https://img.shields.io/github/languages/top/PedroZappa/42_minitalk?style=for-the-badge\" /\u003e\n    \u003cimg src=\"https://img.shields.io/github/last-commit/PedroZappa/42_minitalk?style=for-the-badge\" /\u003e\n\u003c/p\u003e\n\n\u003cimg alt=\"Fractol Demo Overview\" src=\"./video/fractol_intro.gif\" width=\"100%\" /\u003e\n\n___\n\n\u003ch3\u003eTable o'Contents\u003c/h3\u003e\n\n\u003c/div\u003e\n\n\u003c!-- mtoc-start --\u003e\n\n* [About 📌](#about-)\n  * [Mandatory Features](#mandatory-features)\n  * [Bonus Features](#bonus-features)\n* [Implementation 📜](#implementation-)\n  * [`t_display` Structure](#t_display-structure)\n  * [`ft_args.c` : Argument Parsing Functions](#ft_argsc--argument-parsing-functions)\n    * [`ft_no_args()`  ](#ft_no_args--)\n    * [`ft_args()`  ](#ft_args--)\n      * [`ft_select_fractal()`](#ft_select_fractal)\n      * [`ft_set_args()`](#ft_set_args)\n  * [`ft_init.c` : Initialization Functions](#ft_initc--initialization-functions)\n    * [`ft_init_display()`](#ft_init_display)\n    * [`ft_init_events()`](#ft_init_events)\n      * [`ft_kill_handle()`;](#ft_kill_handle)\n      * [`ft_handle_keys()`;](#ft_handle_keys)\n      * [`ft_handle_mouse()`;](#ft_handle_mouse)\n    * [`ft_init_data()`](#ft_init_data)\n    * [`ft_usage()`](#ft_usage)\n    * [`ft_render()`](#ft_render)\n    * [`mlx_loop()`](#mlx_loop)\n* [Usage 🏁](#usage-)\n* [Testing 🧪 ](#testing--)\n* [Appendixes](#appendixes)\n  * [MinilibX 🪟](#minilibx-)\n    * [X-Window System](#x-window-system)\n    * [X client-server Architecture](#x-client-server-architecture)\n  * [Complex Numbers](#complex-numbers)\n  * [Complex Arithmetic](#complex-arithmetic)\n    * [Addition](#addition)\n    * [Subtraction](#subtraction)\n    * [Multiplication](#multiplication)\n      * [Complex * Real](#complex--real)\n      * [Complex * Complex](#complex--complex)\n    * [Expanding a Complex Number](#expanding-a-complex-number)\n  * [Complex Plane](#complex-plane)\n  * [Fractals](#fractals)\n    * [Julia Set](#julia-set)\n    * [Mandelbrot Set](#mandelbrot-set)\n    * [Burning Ship Set](#burning-ship-set)\n    * [Tricorn Set](#tricorn-set)\n* [Footnotes](#footnotes)\n\n\u003c!-- mtoc-end --\u003e\n\n## About 📌\n\n\u003e **Fract'ol** is the first computer graphics project of the Common Core curriculum.\n\u003e\n\u003e It is a simple graphics program using `minilibx`, an opportunity to learn how to use the mathematical notion of **complex numbers**, have a first contact with the concept of **optimization** in computer graphics, and **event handling**. \n\n___\n### Mandatory Features\n\n* **General**\n\t* The program must take the type of the fractal to be displayed as a parameter and any other relevant option.\n\t* The program must display the fractal in the window powered by `minilibx`.\n\t* The project must contain a `Makefile` that compiles all sources. It must not relink.\n\t* Global variables are forbidden.\n\n* **Rendering**\n\t* The program must offer the **Julia** and **Mandelbrot** sets.\n\t* The mouse wheel zooms in and out almost infinitely, within the limits of the computer.\n\t* A different **Julia** set must be rendered if the program is passed the appropriate parameters.\n\t* A parameter passed on startup must be the type of the fractal to be rendered.\n\t\t* Adding more parameters is optional.\n\t\tIf no parameter is provided, or the parameters are invalid, it displays the help page and exits cleanly.\n\t* A few different color schemes must be implemented.\n\n* **Graphic Management**\n\t* The program has to display the image in a window.\n\t* The management of the window must remain smooth.\n\t* Pressing `ESC` must close the window and exit the program in a clean way.\n\t* Clicking on the cross on the top window frame must have the same effect.\n\t* It is mandatory to use `images` from `minilibx`.\n\n___\n### Bonus Features\n\n* One extra fractal.\n* The zoom follows the mouse position.\n* Moving the view by pressing the arrow keys.\n* Make the color range shift.\n\n___\n## Implementation 📜\n\nBefore anything else, the `main()` function declares a `t_display` variable named `display` that stores all the necessary data, conveniently packed to be passed around the program.\n\n___\n### `t_display` Structure\n```c \ntypedef struct s_display\n{\n\t// mlx Data\n\tvoid        *mlx_conn;   // Stores pointer to mlx connection\n\tvoid        *mlx_win;    // Stores pointer to mlx window\n\tt_img       img;         // Stores the image data\n\tint         width;       // Stores the width of the window\n\tint         height;      // Stores the height of the window\n\tt_range     win_size;    // Stores the size of the window\n\tdouble      x_offset;    // Stores how much to shift when moving the view \n\tdouble      y_offset;    // Stores how much to shift when moving the view\n\tdouble      zoom;        // Stores the zoom factor\n\t// Fractal Data\n\tchar        *name;       // Stores the name of the fractal\n\tint         set;         // Stores the type of fractal\n\tlong        iter;        // Stores the number of iterations\n\tt_complex   z;           // Stores z for Mandelbrot/Julia/Tricorn/Burning Ship\n\tt_complex   c;           // Stores c for Mandelbrot/Tricorn/Burning Ship\n\tt_complex   c_julia;     // Stores c for Julia\n\tt_complex   z_newton;    // Stores z for Newton\n\tt_range     frac_range;  // Stores the range of the complex plane\n\tdouble      escape;      // Stores the complex plane escape value\n\tdouble      newton_esc;  // Stores escape value for Newton\n\tt_range     color_iter;  // Stores a range of 0 to n iterations \n\tt_range     color_range; // Stores a range from black to white\n\tint         color;       // Stores a color for the Newton fractal\n}               t_display;\n```\n___\n### `ft_args.c` : Argument Parsing Functions\n\n\u003e The main logic for argument parsing can be found inside the `ft_args.c` file.\n\n`ft_no_args()` and `ft_args()` are used to parse the input arguments and ensure that if there is something wrong the program exits correctly (without memory leaks).\n```c\nif (argc \u003c 2)\n\treturn (ft_no_args());\nelse if (!ft_args(\u0026display, argc, argv))\n\texit(EXIT_FAILURE);\n```\n___\n#### `ft_no_args()`  \n\n\u003e If the program is passed no arguments:\n* It prints an error to `stderr`;\n* Displays the help page and exits cleanly.\n\n___\n#### `ft_args()`  \n\n\u003e Checks if the arguments passed are valid. \n\n```c\nint\tft_args(t_display *d, int argc, char **argv)\n{\n\tif (!ft_select_fractal(d, argc, argv))\n\t\treturn (ft_invalid_args(argv[1]));\n\tif (!ft_set_args(d, argc, argv))\n\t\treturn (0);\n\treturn (1);\n}\n```\n\n* First checks if the fractal type selected is valid.\n* Then attempts to set the input arguments:\n\n___\n##### `ft_select_fractal()`\n\n\u003e This function checks if the fractal type is valid. \n* It first converts the fractal type (first argument) to lowercase.\n* If it is valid, `ft_set_fractal()` is called and the function outputs 1.\n* If it is NOT valid it outputs 0.\n\n___\n##### `ft_set_args()`\n\n\u003e Here we make sure we got the right number of arguments and check if they are the right type before the program initializes anything.\n\n* First checks the iterations argument:\n\t* If the 2nd argument is a valid input for the number of iterations, we set it to `d-\u003eiter`. In case it is a negative value a default value is set instead.\n\t* Otherwise the program prints an error to `stderr` and exits.\n\n* Then we check for the Julia case in which we get a complex number as the third and fourth arguments.\n\t* If the input arguments are a valid doubles we set them to `d-\u003ec_julia.r` and `d-\u003ec_julia.i`.\n\t* Otherwise the program prints an error to `stderr` and exits.\n\n___\n### `ft_init.c` : Initialization Functions\n\n\u003e After all validation tests are passed, the program calls `ft_init_display()`. \n\n___\n#### `ft_init_display()`\n```c\nft_init_display(\u0026display, argv);\n```\n\nIt initializes:\n* the `mlx` connection into `d-\u003emlx_conn` by calling `mlx_init()`;\n* the `mlx` window into `d-\u003emlx_win` by calling `mlx_new_window()`;\n* the image pointer into `d-\u003eimg.img` by calling `mlx_new_image()`;\n* the image pixels into `d-\u003eimg.pix` by calling `mlx_get_data_addr()`;\n\n\u003e All these calls are properly protected by calls to cleanup functions in case a initialization error arises.\n\nAfter everything is properly allocated we proceed to initialize the **event handling** functionality.\n\n___\n#### `ft_init_events()`\n\nThis function initializes three **event handlers** to be triggered when certain events are received:\n\n___\n##### `ft_kill_handle()`;\n* Listens for `DestroyNotify` event;\n\t* Destroys the image data;\n\t* Destroys the `mlx` window;\n\t* Destroys the `mlx` connection;\n\t* Frees the `t_display` pointer to the `mlx_conn`;\n\n___\n##### `ft_handle_keys()`;\n* Listens for `KeyPress` events;\n\t* If \u003ckbd\u003eEscape\u003c/kbd\u003e is received, it exits by calling `ft_kill_handle()`;\n\t* If the arrow keys are pressed, `ft_handle_offsets()` is called;\n\t* If \u003ckbd\u003ePageUp\u003c/kbd\u003e or \u003ckbd\u003ePageDown\u003c/kbd\u003e are pressed, the `d-\u003eiter` is increased or decreased by 1 respectively;\n\t* If \u003ckbd\u003eSpace\u003c/kbd\u003e, \u003ckbd\u003e1\u003c/kbd\u003e, \u003ckbd\u003e2\u003c/kbd\u003e, \u003ckbd\u003e3\u003c/kbd\u003e, \u003ckbd\u003e4\u003c/kbd\u003e, \u003ckbd\u003e5\u003c/kbd\u003e are pressed, `ft_swith_set()` is called.\n\t* If \u003ckbd\u003eLeft-Shift\u003c/kbd\u003e, \u003ckbd\u003eRight-Shift\u003c/kbd\u003e, \u003ckbd\u003er\u003c/kbd\u003e, \u003ckbd\u003eg\u003c/kbd\u003e or \u003ckbd\u003eb\u003c/kbd\u003e are pressed, `ft_switch_color()` is invoked.\n\t* Else if the key press received is not being handled, a message with the keysym value is printed to `stdout`.\n\t* If an event was successfully caught `ft_render()` is called causing a re-render of the window.\n\t\n___\n##### `ft_handle_mouse()`;\n* Listens for `ButtonPress` events;\n\t* 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 its `c` set to the current mouse position;\n\t* Else if the right button is pressed the window re-renders the Mandelbrot set.\n\t* Else if the mouse wheel is scrolled up or down `ft_handle_zoom()` is called.\n\n\u003e [!Note]\n\u003e Understanding `ft_handle_zoom()` :\n\u003e\n\u003e **Centering \u0026 Scaling**\n\u003e\n\u003e The keys to zooming in computer graphics are :\n\u003e * Adjusting the view's center, by changing the `d-\u003ex_offset` and `d-\u003ey_offset`;\n\u003e * Adjusting the view's scale, by changing the `d-\u003ezoom` factor;\n\u003e\n\u003e **Mouse Position \u0026 Zoom Center**\n\u003e\n\u003e The `x` and `y` coordinates of the mouse are used to determine the zoom center;\n\u003e * This is done by mapping the mouse position to the range of the complex plane;\n\u003e\n\u003e **Zoom Factor \u0026 Scaling**\n\u003e\n\u003e * The zoom factor (`SCALE_FACTOR`) determines how much the view is scaled with each zoom operation.\n\u003e * Increasing the zoom level, divides `d-\u003ezoom` value by the `SCALE_FACTOR`, enlarging the view;\n\u003e * Decreasing the zoom level, multiplies `d-\u003ezoom` value by the `SCALE_FACTOR`, shrinking the view. \n\u003e * `fabs()` is used to ensure that the scale factor is always positive, regardless of the current zoom level.\n\u003e\n\u003e **Offset Adjustment** \n\u003e\n\u003e * The offset adjustment (0.13 * fabs(d-\u003ezoom)) is a scaling factor that controls how much the view is moved in response to zooming.\n\u003e * 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.\n\nNow that we got the X connection, the window and event handling up and running all there is left to do it the data initialization.\n\n___\n#### `ft_init_data()`\n\nIn this function we initialize the data inside the `t_display` structure to be passed and used by the program.\n```c\nft_init_display(\u0026display, argv);\n\n```\n\n\u003e Check out [ft_init.c](https://github.com/PedroZappa/42_fractol/blob/main/src/ft_init.c) and [fractol.h](https://github.com/PedroZappa/42_fractol/blob/main/src/fractol.h) for a closer look at what is being initialized and to what values.\n\n___\n#### `ft_usage()`\n\nThe `ft_usage()` function prints the usage of the program and all available commands to `stdout`.\n```c\nft_usage();\n```\n\n___\n#### `ft_render()`\n\nThis is where the pixel-by-pixel drawing of the window takes place.\n```c\nft_render(\u0026display);\n```\n* It iterates over each pixel in the window;\n* Selects the rendering function based on the chosen fractal type;\n* For each pixel it evaluates the function describing the selected set;\n```c\nwhile (++y \u003c= HEIGHT)\n{\n\tx = -1;\n\twhile (++x \u003c WIDTH)\n\t\tft_select_set(d, x, y);\n\tft_printf(\"\\r%sRendering:%s [%d%%]\", YEL, NC, ((y * 100) / d-\u003eheight));\n}\nft_printf(\"\\t%sComplete!%s\\n\", MAG, NC);\n```\n\n* Once the calculations are done `mlx_put_image_to_window()` is called to render the image to the window.\n```c\nmlx_put_image_to_window(d-\u003emlx_conn, d-\u003emlx_win, d-\u003eimg.img, 0, 0);\n```\n* Then `ft_render_ui()` is called to print a simple UI to the window.\n```c\nft_render_ui(d);\n```\n\u003e [!Note]\n\u003e This is a function that can produce memory leaks if the usage of `ft_itoa()` and `ft_strjoin()` are not handled correctly. Take a look for yourself at [ft_ui.c](https://github.com/PedroZappa/42_fractol/blob/main/src/ft_ui.c) for details.\n\n___\n#### `mlx_loop()`\n\nFinally, the program enters an infinite loop, keeping the window open listening for user events.\n```c\nmlx_loop(d-\u003emlx_conn);\n```\n\n___\n## Usage 🏁\n\nFirst, clone the contents of this repository over SSH:\n```sh\ngit clone git@github.com:PedroZappa/42_fractol.git\n```\nThen, make sure that the program is compiled with all its dependencies using `make`:\n```sh\nmake\n```\nOne way to find out all available startup options and keybindings, is to run the program without arguments:\n```sh\n./fractol\n```\n___\n## Testing 🧪 \n\nIf you want to test the program with `valgrind`, you can use the following `make` rule:\n```sh\nmake valgrind\n```\n\nThere is also a convenient `make` rule to run a `Norminette` check:\n```sh\nmake norm\n``` \n___\n## Appendixes\n___\n### MinilibX 🪟\n\n**MinilibX** is a small library, a simplified version of **XLib** (X11R6) written in C , designed to introduce students to the **X-Window System**. [^1]\n\n___\n#### X-Window System\n\nThe **X-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.\n\n\u003e [!Note]\n\u003e\n\u003e In computing, a `bitmap` (also known as `bit array` or `bitmap index`) is a mapping from a given domain (for instance, a range of integers) to bits. [^3]\n\n___\n#### X client-server Architecture\n\nX is based on a client-server model: \n\n* one **X server** connects to multiple **X client** programs.\n```mermaid\nflowchart TB\n\tDisplay[Display]\n\tKeys[Keyboard]\n\tMouse[Mouse]\n\n\tKeys[Keyboard] ---\u003e|input| Xserv[X Server]\n\tMouse[Mouse] ---\u003e|input| Xserv\n\tDisplay[Display] \u003c---|output| Xserv\n\tsubgraph W[User Workstation]\n\t\tXserv[X Server]\n\t\tXserv --\u003e X-client[X client1]\n\t\tXserv --\u003e X-client2[X client2]\n\tend\n\tsubgraph Remote Machine\n\t\tXserv --\u003e|Network Conn| X-client3[X client3]\n\tend\n```\n\nThe X Server receives requests to output graphics on the display (through windows) and sends back user input (from a keyboard, mouse, etc).\n\n\u003e [!Note]\n\u003e\n\u003e There are many implementations of the X Window System (Xlib), minilibx being just one among many following the X Consortium standard; [^4]\n\u003e - [Xlib : X Consortium Standard](https://www.x.org/releases/current/doc/libX11/libX11/libX11.html)\n\n____\n### Complex Numbers\n\n`Complex numbers` are numbers in the form `(a + bi)` where:\n\n* `a` is the real part:\n* `b` is the imaginary part;\n* `i` is the imaginary unit, defined by the equation $i^2 = -1$.\n\n\u003e [!Note]\n\u003e\n\u003e $i = \\sqrt-1$\n\n___\n### Complex Arithmetic\n\nLike with real numbers, we can perform **arithmetic** on complex numbers.\n\n___\n#### Addition\n\n\u003e $(a + bi) + (c + di) = (a + c) + (b + d)i$\n\nExample of how to add two complex numbers:\n\n\u003e $((3 - 4i) + (2 + 5i)) =$\n\u003e\n\u003e $((3 + 2) + (-4 + 5)i) =$\n\u003e\n\u003e $(5 + i)$\n\n___\n#### Subtraction\n\n\u003e $(a + bi) - (c + di) = (a - c) + (b - d)i$\n\n___\n#### Multiplication\n\nMultiplication is similar to multiplying binomials but with complex numbers we work with the real and imaginary parts separately.\n\n##### Complex * Real\n\n\u003e $c(a + bi) = (c * a) + (c * b)i$\n\nExample:\n\n\u003e $3(6 + 2i) =$\n\u003e\n\u003e $(3 * 6) + (3 * 2i) =$ # Distribute\n\u003e\n\u003e $(18 * 6i)$ # Simplify\n\n___\n##### Complex * Complex\n\n\u003e $(a + bi)(c + di) = ac + adi + bci + bdi^2$\n\n* Because $i^2 = -1$, we can simplify the expression to:\n\n\u003e $(a + bi)(c + di) = ac + adi + bci - bd$\n\n* Simplifying, we combine the real parts, and then the imaginary parts:\n\n\u003e $(a + bi)(c + di) =$\n\u003e \n\u003e $(ac - bd) + (ad + bc)i$\n\nExample:\n\n\u003e $(4 + 3i)(2 - 5i) =$\n\u003e\n\u003e $(4 * 2) + (4 * (-5i)) + (3i * 2) + (3i * (-5i)) =$\n\u003e\n\u003e $8 - 20i + 6i - 15i^2 =$\n\u003e\n\u003e $8 + 15 - 20i + 6i =$\n\u003e\n\u003e $(23 - 14i)$\n\n___\n#### Expanding a Complex Number\n\nHere is an example on how to expand a squared complex number:\n\n\u003e $(a + bi)^2 =$\n\u003e\n\u003e $(a * a) + (a * bi) + (a * bi) - (bi * bi)$\n\u003e\n\u003e $(a^2 - bi^2) + 2(a * bi))$\n\n* The real part is $(a^2 - b^2)$;\n* The imaginary part is $2(a * bi)$;\n\n___\n### Complex Plane\n\nWe can take complex numbers and plot them in a plane known as the `Complex Plane`.\n\n\u003e 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 the `x`-axis and the imaginary part to the `y`-axis.\n\n___\n### Fractals\n\n\u003e Fractals are infinitely complex self-similar patterns across multiple scales.\n\nGenerated by:\n\n* Initializing a complex number $z = (x + yi)$ where: $i^2 = -1$\n* `x` and `y` are image pixel coordinates mapped to a range between -2 to 2.\n* A formula is iterated until the value of `|z|` becomes greater than `2`.\n\t* If the point never escapes the range it IS considered to be part of the set.\n\t* If the point escapes the range it means it is NOT part of the set.\n\t* The color of each pixel is determined by the number of iterations it took to escape the set.\n\n___\n#### Julia Set\n\n\u003e **Formula** :  $f(z_{n+1}) = z_n^2 + c$\n\nThere are infinitely many Julia sets. To generate them, we use the same complex number `c` for all pixels. \n\n* For each pixel in the image:\n\t* `z` is initially set to 0.\n\t* `z` is updated repeatedly following the formula $z_{n+1} = z^2 + c$.\n\t* `c` is a complex number that seeds a specific Julia set.\n\n\u003cimg alt=\"Julia Fractol Demo\" src=\"./video/fractol_julia.gif\" width=\"100%\" /\u003e\n\n___\n#### Mandelbrot Set\n\n\u003e **Formula** :  $f(z_{n+1}) = z_n^2 + c$\n\nFor the Mandelbrot set, we use different complex numbers for each pixel. It is the one map to all Julia sets.\n\n* For each pixel in the image:\n\t* `z` is initially set to 0.\n\t* `z` is updated repeatedly following the formula $z_{n+1} = z^2 + c$.\n\t* `c` is a complex constant defined as: $c = (x + yi)$ where: $i^2 = -1$\n\n\u003cimg alt=\"Mandelbrot Fractol Demo\" src=\"./video/fractol_mandelbrot.gif\" width=\"100%\" /\u003e\n\n___\n#### Burning Ship Set\n\n\u003e $f(z_{n+1}) = (|{Re}(z_n)| + |{Im}(z_n)|i)^2 + c$\n\nThe Burning Ship Set is generated by the equation above where:\n* $z_n$ is the current complex number;\n* `c` is a complex constant (just like in the Julia Set formula);\n* $z_{n+1}$ is the next complex number in the sequence;\n* The real and imaginary components are set to their absolute values before squaring at each iteration.\n\nThis modification results in the distinctive \"burning ship\" appearance of the fractal.\n\n\u003cimg alt=\"Burning Ship Fractol Demo\" src=\"./video/fractol_burning.gif\" width=\"100%\" /\u003e\n\n___\n#### Tricorn Set\n\n\u003e **Formula** :  $f(z_{n+1}) = \\overline{z_n}^2 + c$\n\nThe 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:\n* The complex conjugate of `z` is squared instead of `z` itself.\n* The complex conjugate of `z` is represented by $\\overline{z_n}$ \n* `c` is a complex constant that varies for each pixel in the image.\n\n\u003e [!Note]\n\u003e To get the `complex 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)$\n\u003e\n\u003e For example: The conjugate of `(4 + 7i)` is `(4 - 7i)`.\n\n\u003cimg alt=\"Tricorn Fractol Demo\" src=\"./video/fractol_tricorn.gif\" width=\"100%\" /\u003e\n\n___\n## Footnotes\n\n[^1]: [The Fractal Geometry of Nature - Benoit B. Mandelbrot - Google Livros](https://books.google.pt/books?id=0R2LkE3N7-oC\u0026redir_esc=y)\n[^2]: [Are Fractals or Fractal Curves Differentiable?](https://nnart.org/are-fractals-differentiable/)\n[^3]: [How to Draw Fractals by Hand: A Beginner's Guide](https://nnart.org/how-to-draw-fractals-by-hand-a-beginners-guide/)\n[^4]: [Complete List of Books by Benoit Mandelbrot](https://nnart.org/complete-list-of-books-by-benoit-mandelbrot/)\n[^5]: [How Are Fractals Used in Technology and Engineering?](https://nnart.org/how-are-fractals-used-in-technology-and-engineering/)\n[^6]: [Style Guide: How Did Jackson Pollock Paint?](https://nnart.org/style-guide-jackson-pollock/)\n[^7]: [How Do Fractals Appear in Nature? 10 Outstanding Examples](https://nnart.org/fractals-in-nature/)\n[^8]: [How Are Fractals Used in Technology and Engineering?](https://nnart.org/how-are-fractals-used-in-technology-and-engineering/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrozappa%2F42_fractol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedrozappa%2F42_fractol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrozappa%2F42_fractol/lists"}