Fractol 1.0
A fractal visualization project implemented in C.
Loading...
Searching...
No Matches
mandelbrot.c
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* mandelbrot.c :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: meghribe <meghribe@student.42barcelona.co +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2024/12/24 19:20:48 by meghribe #+# #+# */
9/* Updated: 2025/01/05 14:17:32 by meghribe ### ########.fr */
10/* */
11/* ************************************************************************** */
12
13#include "fractol.h"
14
15/**
16 * @file mandelbrot.c
17 * @brief Implementation of the Mandelbrot set rendering.
18 *
19 * This file contains all the functions necessary to compute and render the
20 * Mandelbrot set fractal.
21 * The Mandelbrot set is a visual representation off a mathematical formula
22 * applied to complex numbers. THe complexity and beauty of its patterns arise
23 * from how quickly or slowly each point "escapes" beyond a defined boundary.
24 *
25 * ### For Technical Users:
26 * - **Core Algorithm:** The Mandelbrot set uses the formula `z = z^2 + c`,
27 * where:
28 * - `z` starts at (0, 0) for every point.
29 * - `c` is the complex number corresponding to the pixel's position on the
30 * screen.
31 * - Iterations continue until `|z|2 > 4` (escape condition) or the maximum
32 * number of iterations is reached.
33 * - **Optimization:**
34 * - **Escape Checks:** Early checks prevent unnecessary calculations for
35 * points.
36 * - **Precomputed Coordinates:** Reduces redundant computations of pixel
37 * coordinates.
38 * - **Row-Based Rendering:** Processes the fractal row by row for efficient
39 * memory and rendering operations.
40 * - **Color Mapping:** The number of iteerations determines the color of
41 * each pixexl, creating vibrant and intricaate fractal patterns.
42 *
43 * ### For Non-Technical Users:
44 * - **What is the Mandelbrot Set?**
45 * The Mandelbrot set is a mathematical design created by repeatedly
46 * applying a simple formula to point on a grid. Points that "escape"
47 * quickly create bright colors, while points that stay "trapped"
48 * generate the darker areas of the fractal.
49 *
50 */
51/**
52 * @brief Computes the next iteration for a single point in the Mandelbrot set.
53 */
54static void compute_next_iteration(t_render_vars *vars, int i)
55{
56 double temp_z_re;
57
58 temp_z_re = vars->z_squared[COMPLEX_RE] - vars->z_squared[COMPLEX_IM];
59 temp_z_re += vars->c_re[i];
60 vars->z[COMPLEX_IM] = (2.0 * vars->z[COMPLEX_RE] * vars->z[COMPLEX_IM]);
61 vars->z[COMPLEX_IM] += vars->c_im;
62 vars->z[COMPLEX_RE] = temp_z_re;
63 vars->z_squared[COMPLEX_RE] = vars->z[COMPLEX_RE] * vars->z[COMPLEX_RE];
64 vars->z_squared[COMPLEX_IM] = vars->z[COMPLEX_IM] * vars->z[COMPLEX_IM];
65}
66
67/**
68 * @brief Performs the iterations for a single point in the Mandelbrot set.
69 */
70static void mandelbrot_iterations(t_render_vars *vars, int i)
71{
72 double current_magnitude_squared;
73 double escape_radius_squared;
74
75 escape_radius_squared = 4.0;
76 vars->z[COMPLEX_RE] = 0.0;
77 vars->z[COMPLEX_IM] = 0.0;
78 vars->z_squared[COMPLEX_RE] = 0;
79 vars->z_squared[COMPLEX_IM] = 0;
80 vars->iterations = 0;
81 while (1)
82 {
83 current_magnitude_squared = vars->z_squared[COMPLEX_RE];
84 current_magnitude_squared += vars->z_squared[COMPLEX_IM];
85 if (vars->iterations >= MAX_ITERATIONS)
86 break ;
87 if (current_magnitude_squared > escape_radius_squared)
88 break ;
90 vars->iterations++;
91 }
92}
93
94/**
95 * @brief Performs an early scape check for a point in the Mandelbrot set.
96 */
97static int mandelbrot_escape_check(t_render_vars *vars, int i, t_data *data)
98{
99 int max_color;
100 double dist_sq;
101 double esc_chk;
102 double bound_condition;
103
104 max_color = calculate_color(MAX_ITERATIONS);
105 vars->c_re_centered = vars->c_re[i] - 0.25;
106 dist_sq = vars->c_re_centered * vars->c_re_centered;
107 dist_sq += vars->c_im * vars->c_im;
108 esc_chk = dist_sq * (dist_sq + vars->c_re_centered);
109 if ((data->zoom > 1.0) && (esc_chk < 0.25 * vars->c_im * vars->c_im))
110 return (vars->row[i] = max_color, 1);
111 bound_condition = (vars->c_re[i] + 1) * (vars->c_re[i] + 1);
112 bound_condition += vars->c_im * vars->c_im;
113 if (bound_condition < 0.0625)
114 return (vars->row[i] = max_color, 1);
115 return (0);
116}
117
118/**
119 * @brief Renders a single row of the Mandelbrot set.
120 */
121static void render_mandelbrot_row(t_render_vars *vars, t_data *data, int y)
122{
123 int x;
124 int i;
125
126 x = 0;
127 while (x < WIDTH)
128 {
129 vars->row = vars->pixels + (y * WIDTH + x);
130 vars->c_re[0] = vars->start[COMPLEX_RE] + x * vars->scale[SCALE_X];
131 vars->c_re[1] = vars->start[COMPLEX_RE];
132 vars->c_re[1] += (x + 1) * vars->scale[SCALE_X];
133 i = 0;
134 while (i < 2)
135 {
136 if (mandelbrot_escape_check(vars, i, data))
137 {
138 i++;
139 continue ;
140 }
141 mandelbrot_iterations(vars, i);
142 vars->row[i++] = calculate_color(vars->iterations);
143 }
144 x += 2;
145 }
146}
147
148/**
149 * @brief Renders the Mandelbrot set fractal.
150 */
152{
153 t_render_vars vars;
154 double *precomputed_c_re;
155 double *precomputed_c_im;
156 int y;
157
158 calculate_scales_and_limits(&vars, data);
159 if (!precompute_coords(&precomputed_c_re, &precomputed_c_im, &vars))
160 return ;
161 y = 0;
162 while (y < HEIGHT)
163 {
164 vars.c_im = precomputed_c_im[y];
165 render_mandelbrot_row(&vars, data, y++);
166 }
167 free(precomputed_c_re);
168 free(precomputed_c_im);
169}
int precompute_coords(double **c_re, double **c_im, t_render_vars *vars)
Precomputes the coordinates for each pixel in the fractal.
Definition calcs.c:78
void calculate_scales_and_limits(t_render_vars *vars, t_data *data)
Calculates the scales and starting points for the fractal rendering.
Definition calcs.c:52
int calculate_color(int iterations)
Calculates the color of a pixel based on how many iterations it takes to "escape".
Definition calcs.c:131
#define MAX_ITERATIONS
Definition fractol.h:193
#define WIDTH
Definition fractol.h:188
@ SCALE_X
Definition fractol.h:43
@ COMPLEX_IM
Definition fractol.h:53
@ COMPLEX_RE
Definition fractol.h:52
#define HEIGHT
Definition fractol.h:189
static void render_mandelbrot_row(t_render_vars *vars, t_data *data, int y)
Renders a single row of the Mandelbrot set.
Definition mandelbrot.c:121
void render_mandelbrot(t_data *data)
Renders the Mandelbrot set fractal.
Definition mandelbrot.c:151
static void mandelbrot_iterations(t_render_vars *vars, int i)
Performs the iterations for a single point in the Mandelbrot set.
Definition mandelbrot.c:70
static void compute_next_iteration(t_render_vars *vars, int i)
Computes the next iteration for a single point in the Mandelbrot set.
Definition mandelbrot.c:54
static int mandelbrot_escape_check(t_render_vars *vars, int i, t_data *data)
Performs an early scape check for a point in the Mandelbrot set.
Definition mandelbrot.c:97
Data structure for fractal rendering.
Definition fractol.h:92
double zoom
Definition fractol.h:93
Variables used for fractal rendering calculations.
Definition fractol.h:105
double z_squared[2]
Definition fractol.h:110
double scale[2]
Definition fractol.h:107
uint32_t * row
Definition fractol.h:115
double c_im
Definition fractol.h:113
double c_re[2]
Definition fractol.h:111
double start[2]
Definition fractol.h:108
double c_re_centered
Definition fractol.h:112
uint32_t * pixels
Definition fractol.h:114
double z[2]
Definition fractol.h:109