diff --git a/include/fractol.h b/include/fractol.h index 7acf51b..416fc87 100644 --- a/include/fractol.h +++ b/include/fractol.h @@ -6,7 +6,7 @@ /* By: lgaudin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/15 18:46:11 by lgaudin #+# #+# */ -/* Updated: 2023/06/17 14:19:15 by lgaudin ### ########.fr */ +/* Updated: 2023/06/17 18:30:16 by lgaudin ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,6 +25,9 @@ # define R 15 # define C 8 # define H 4 +# define J 38 +# define P 35 +# define M 46 // MOUSECODES # define SCROLL_UP 4 @@ -50,6 +53,7 @@ typedef struct s_fractal double offset_y; double zoom; char *name; + int max_iterations; } t_fractal; # include "libft/libft.h" @@ -59,6 +63,8 @@ typedef struct s_fractal // utils.c void put_color_to_pixel(t_fractal *fractal, int x, int y, int colour); int exit_fractal(t_fractal *fractal); +double generate_random_c(void); +void change_iterations(t_fractal *fractal, int key_code); // init.c void init_fractal(t_fractal *fractal); @@ -68,10 +74,13 @@ void init_mlx(t_fractal *fractal); void calculate_mandelbrot(t_fractal *fractal); // julia.c -void calculate_julia(t_fractal *fractal); +void calculate_julia(t_fractal *fractal, double cx, double cy); + +// burning_ship.c +void calculate_burning_ship(t_fractal *fractal); // main.c -int draw_fractal(t_fractal *fractal, char *query); +int draw_fractal(t_fractal *fractal, char *query, double cx, double cy); // mouse_and_keys.c int key_hook(int key_code, t_fractal *fractal); diff --git a/src/burning_ship.c b/src/burning_ship.c new file mode 100644 index 0000000..54c4121 --- /dev/null +++ b/src/burning_ship.c @@ -0,0 +1,50 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* burning_ship.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lgaudin +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/06/16 13:55:52 by lgaudin #+# #+# */ +/* Updated: 2023/06/17 18:33:00 by lgaudin ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "../include/fractol.h" + +/** + * @brief Calculates the Burning Ship fractal for one pixel. + * + * The z variables are set to 0, the beginning of the suite. + * + * The c constants are set to the coordinates of the pixel. + * + * @param fractal + */ +void calculate_burning_ship(t_fractal *fractal) +{ + int i; + double x_temp; + + fractal->name = "ship"; + i = 0; + fractal->zx = 0.0; + fractal->zy = 0.0; + fractal->cx = (fractal->x / fractal->zoom) + fractal->offset_x; + fractal->cy = (fractal->y / fractal->zoom) + fractal->offset_y; + while (++i < fractal->max_iterations) + { + x_temp = fractal->zx * fractal->zx - fractal->zy * fractal->zy + + fractal->cx; + fractal->zy = fabs(2.0 * fractal->zx * fractal->zy) + fractal->cy; + fractal->zx = fabs(x_temp); + if (fractal->zx * fractal->zx + fractal->zy + * fractal->zy >= __DBL_MAX__) + break ; + } + if (i == fractal->max_iterations) + put_color_to_pixel(fractal, fractal->x, fractal->y, 0x000000); + else + put_color_to_pixel(fractal, fractal->x, fractal->y, (fractal->color + * i)); +} diff --git a/src/init.c b/src/init.c index 570206f..3bcc722 100644 --- a/src/init.c +++ b/src/init.c @@ -6,7 +6,7 @@ /* By: lgaudin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/16 13:32:20 by lgaudin #+# #+# */ -/* Updated: 2023/06/17 14:21:03 by lgaudin ### ########.fr */ +/* Updated: 2023/06/17 18:23:17 by lgaudin ### ########.fr */ /* */ /* ************************************************************************** */ @@ -25,6 +25,7 @@ void init_fractal(t_fractal *fractal) fractal->zoom = 300; fractal->offset_x = -1.21; fractal->offset_y = -1.21; + fractal->max_iterations = 42; } /** diff --git a/src/julia.c b/src/julia.c index 7bfb936..4bd25a6 100644 --- a/src/julia.c +++ b/src/julia.c @@ -6,35 +6,46 @@ /* By: lgaudin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/16 13:55:52 by lgaudin #+# #+# */ -/* Updated: 2023/06/17 14:08:43 by lgaudin ### ########.fr */ +/* Updated: 2023/06/17 18:31:13 by lgaudin ### ########.fr */ /* */ /* ************************************************************************** */ #include "../include/fractol.h" -void calculate_julia(t_fractal *fractal) +/** + * @brief Calculates the Julia fractal for one pixel. + * + * The z variables are set to the coordinates of the pixel. + * + * The c constants are set to the provided values, as every value produces + * a different fractal. + * + * @param fractal + */ +void calculate_julia(t_fractal *fractal, double cx, double cy) { int i; double tmp; fractal->name = "julia"; - i = 0; - fractal->cx = -0.808; - fractal->cy = 0.168; + fractal->cx = cx; + fractal->cy = cy; fractal->zx = fractal->x / fractal->zoom + fractal->offset_x; fractal->zy = fractal->y / fractal->zoom + fractal->offset_y; - while (fractal->zx * fractal->zx + fractal->zy * fractal->zy < 4 - && i < MAX_ITERATIONS) + i = 0; + while (++i < fractal->max_iterations) { tmp = fractal->zx; - fractal->zx = fractal->zx * fractal->zx - fractal->zy - * fractal->zy + fractal->cx; + fractal->zx = fractal->zx * fractal->zx - fractal->zy * fractal->zy + + fractal->cx; fractal->zy = 2 * fractal->zy * tmp + fractal->cy; - i++; + if (fractal->zx * fractal->zx + fractal->zy + * fractal->zy >= __DBL_MAX__) + break ; } - if (i == MAX_ITERATIONS) + if (i == fractal->max_iterations) put_color_to_pixel(fractal, fractal->x, fractal->y, 0x000000); else - put_color_to_pixel(fractal, fractal->x, fractal->y, - (fractal->color * (i % 255))); + put_color_to_pixel(fractal, fractal->x, fractal->y, (fractal->color * (i + % 255))); } diff --git a/src/main.c b/src/main.c index 9900f94..94509d0 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: lgaudin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/13 22:55:04 by lgaudin #+# #+# */ -/* Updated: 2023/06/17 14:24:25 by lgaudin ### ########.fr */ +/* Updated: 2023/06/17 18:29:37 by lgaudin ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,7 +19,7 @@ * @param fractal The fractal structure. * @param query The name of the fractal to draw. */ -int draw_fractal(t_fractal *fractal, char *query) +int draw_fractal(t_fractal *fractal, char *query, double cx, double cy) { fractal->x = 0; fractal->y = 0; @@ -27,12 +27,12 @@ int draw_fractal(t_fractal *fractal, char *query) { while (fractal->y < SIZE) { - if (ft_strncmp(query, "mandelbrot", 11) == 0) + if (ft_strncmp(query, "mandel", 7) == 0) calculate_mandelbrot(fractal); else if (ft_strncmp(query, "julia", 6) == 0) - calculate_julia(fractal); - // else if (ft_strcmp(query, "burningship") == 0) - // calculate_burningship(fractal); + calculate_julia(fractal, cx, cy); + else if (ft_strncmp(query, "ship", 5) == 0) + calculate_burning_ship(fractal); else { ft_putendl_fd("Available fractals: mandelbrot, julia, burningship", 1); @@ -64,7 +64,7 @@ int main(int argc, char **argv) mlx_key_hook(fractal->window, key_hook, fractal); mlx_mouse_hook(fractal->window, mouse_hook, fractal); mlx_hook(fractal->window, 17, 0L, exit_fractal, fractal); - draw_fractal(fractal, argv[1]); + draw_fractal(fractal, argv[1], -0.745429, 0.05); mlx_loop(fractal->mlx); return (0); } diff --git a/src/mandelbrot.c b/src/mandelbrot.c index 2606b52..741d514 100644 --- a/src/mandelbrot.c +++ b/src/mandelbrot.c @@ -6,7 +6,7 @@ /* By: lgaudin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/16 13:27:23 by lgaudin #+# #+# */ -/* Updated: 2023/06/17 13:56:26 by lgaudin ### ########.fr */ +/* Updated: 2023/06/17 18:31:26 by lgaudin ### ########.fr */ /* */ /* ************************************************************************** */ @@ -27,8 +27,8 @@ * pow(x, 2) function. * * The exit conditions of the loop are the following: - * - The absolute value of z is greater than 7, then we can assure - * that the suite will diverge to infinity. + * - The absolute value of z is greater than the system's max values, then + * we can assure that the suite will diverge to infinity. * - The number of iterations is too high, then we can assure that * the suite will stay stuck in an infinite loop. * @@ -43,21 +43,23 @@ void calculate_mandelbrot(t_fractal *fractal) int i; double x_temp; - fractal->name = "mandelbrot"; + fractal->name = "mandel"; i = 0; fractal->zx = 0.0; fractal->zy = 0.0; fractal->cx = (fractal->x / fractal->zoom) + fractal->offset_x; fractal->cy = (fractal->y / fractal->zoom) + fractal->offset_y; - while (fractal->zx * fractal->zx + fractal->zy * fractal->zy < (__DBL_MAX__ - * __DBL_MAX__) * 2 && ++i < MAX_ITERATIONS) + while (++i < fractal->max_iterations) { x_temp = fractal->zx * fractal->zx - fractal->zy * fractal->zy + fractal->cx; fractal->zy = 2. * fractal->zx * fractal->zy + fractal->cy; fractal->zx = x_temp; + if (fractal->zx * fractal->zx + fractal->zy + * fractal->zy >= __DBL_MAX__) + break ; } - if (i == MAX_ITERATIONS) + if (i == fractal->max_iterations) put_color_to_pixel(fractal, fractal->x, fractal->y, 0x000000); else put_color_to_pixel(fractal, fractal->x, fractal->y, (fractal->color diff --git a/src/mouse_and_keys.c b/src/mouse_and_keys.c index 36122e9..93a6c9b 100644 --- a/src/mouse_and_keys.c +++ b/src/mouse_and_keys.c @@ -6,12 +6,20 @@ /* By: lgaudin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/16 18:11:08 by lgaudin #+# #+# */ -/* Updated: 2023/06/17 14:19:09 by lgaudin ### ########.fr */ +/* Updated: 2023/06/17 18:04:16 by lgaudin ### ########.fr */ /* */ /* ************************************************************************** */ #include "../include/fractol.h" +/** + * @brief Zooms or dezooms the fractal. + * + * @param fractal + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + * @param zoom 1 for zoom, -1 for dezoom. + */ void zoom(t_fractal *fractal, int x, int y, int zoom) { double zoom_level; @@ -36,10 +44,42 @@ void zoom(t_fractal *fractal, int x, int y, int zoom) else return ; } +/** + * @brief Sets the constants of Julia to random values. + * + * @param cx A pointer to the cx constant. + * @param cy A pointer to the cy constant. + */ +void set_random_julia(double *cx, double *cy) +{ + *cx = generate_random_c(); + *cy = generate_random_c(); +} +/** + * @brief The handler for keyboard events. + * ESC: exit the program. + * LEFT: move the fractal to the left. + * RIGHT: move the fractal to the right. + * UP: move the fractal up. + * DOWN: move the fractal down. + * R: reset the fractal. + * C: change the color scheme. + * J: set the constants of Julia to random values. + * P: increase the max iterations. + * M: reduce the max iterations. + * + * @param key_code + * @param fractal + */ int key_hook(int key_code, t_fractal *fractal) { - if (key_code == 53) + double cx; + double cy; + + cx = fractal->cx; + cy = fractal->cy; + if (key_code == ESC) exit(1); else if (key_code == LEFT) fractal->offset_x -= 42 / fractal->zoom; @@ -53,17 +93,29 @@ int key_hook(int key_code, t_fractal *fractal) init_fractal(fractal); else if (key_code == C) fractal->color += (255 * 255 * 255) / 100; - draw_fractal(fractal, fractal->name); + else if (key_code == J) + set_random_julia(&cx, &cy); + else if (key_code == M || key_code == P) + change_iterations(fractal, key_code); + draw_fractal(fractal, fractal->name, cx, cy); return (0); } - +/** + * @brief The handler for mouse events. + * SCROLL_UP: zoom in. + * SCROLL_DOWN: zoom out. + * + * @param mouse_code The code of the mouse event. + * @param x The x coordinate of the mouse. + * @param y The y coordinate of the mouse. + * @param fractal + */ int mouse_hook(int mouse_code, int x, int y, t_fractal *fractal) { if (mouse_code == SCROLL_UP) zoom(fractal, x, y, 1); else if (mouse_code == SCROLL_DOWN) zoom(fractal, x, y, -1); - draw_fractal(fractal, fractal->name); + draw_fractal(fractal, fractal->name, fractal->cx, fractal->cy); return (0); } - diff --git a/src/utils.c b/src/utils.c index 50e3b3e..5e1e022 100644 --- a/src/utils.c +++ b/src/utils.c @@ -6,7 +6,7 @@ /* By: lgaudin +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/06/16 13:27:37 by lgaudin #+# #+# */ -/* Updated: 2023/06/17 14:17:10 by lgaudin ### ########.fr */ +/* Updated: 2023/06/17 17:58:49 by lgaudin ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,7 +20,6 @@ * @param y The graphic y coordinate * @param color The color to put to the pixel. */ - void put_color_to_pixel(t_fractal *fractal, int x, int y, int color) { int *buffer; @@ -29,6 +28,11 @@ void put_color_to_pixel(t_fractal *fractal, int x, int y, int color) buffer[(y * fractal->size_line / 4) + x] = color; } +/** + * @brief Exits the program. + * + * @param fractal + */ int exit_fractal(t_fractal *fractal) { mlx_destroy_image(fractal->mlx, fractal->image); @@ -38,3 +42,33 @@ int exit_fractal(t_fractal *fractal) exit(1); return (0); } +/** + * @brief Generates a random double between -1.5 and 1.5. + * + * @return double The random double. + */ +double generate_random_c(void) +{ + return (((double)rand() / RAND_MAX) * 3.0 - 1.5); +} + +/** + * @brief Increases or decreases the number of iterations. + * The lower the number of iterations is, the faster the fractal is generated. + * + * @param fractal + * @param key_code + */ +void change_iterations(t_fractal *fractal, int key_code) +{ + if (key_code == M) + { + if (fractal->max_iterations > 42) + fractal->max_iterations -= 42; + } + else if (key_code == P) + { + if (fractal->max_iterations < 4200) + fractal->max_iterations += 42; + } +}