From b45a8220069ee29de5080545452558321c666798 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 2 Nov 2023 11:19:40 +0100 Subject: [PATCH] Make program print Mandelbrot set, close on ESC --- Makefile | 12 +++---- complex.c | 34 ++++++++++++++++++ complex.h | 16 +++++++++ fractol.h | 24 +++++++++++++ main.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 181 insertions(+), 11 deletions(-) create mode 100644 complex.c create mode 100644 complex.h create mode 100644 fractol.h diff --git a/Makefile b/Makefile index e3038fc..2edfab6 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ +CC := gcc - -CFLAGS := -Wall -Wextra -Werror #-g -INCGRAPH := -Iminilibx-linux -LINKGRAPH := -Lminilibx-linux -lmlx_Linux -L/usr/lib -lXext -lX11 -lm -lz +CFLAGS := -Wall -Wextra -Werror -g +INCGRAPH := -Iminilibx-linux -I/usr/include -ILibft +LINKGRAPH := -Lminilibx-linux -lmlx -L/usr/lib -lXext -lX11 -lm -lbsd -LLibft -lft NAME := fractol MLXDIR := minilibx-linux/ @@ -10,13 +10,13 @@ MLX := $(MLXDIR)libmlx_Linux.a LFTDIR := Libft/ LFT := $(LFTDIR)libft.a -SRCS := main.c +SRCS := main.c complex.c OBJS := $(SRCS:%.c=%.o) all : $(NAME) $(NAME) : $(OBJS) $(LFT) $(MLX) - $(CC) $(CFLAGS) $(LINKGRAPH) $^ -o $@ + $(CC) $(CFLAGS) $(OBJS) -o $@ $(LINKGRAPH) %.o : %.c $(CC) $(CFLAGS) $(INCGRAPH) -c $< -o $@ diff --git a/complex.c b/complex.c new file mode 100644 index 0000000..e5dcc81 --- /dev/null +++ b/complex.c @@ -0,0 +1,34 @@ +#include +#include "complex.h" + +t_complex to_complex(double x, double y) +{ + t_complex res; + + res.r = x; + res.i = y; + return (res); +} + +t_complex complex_add(t_complex x, t_complex y) +{ + t_complex res; + + res.r = x.r + y.r; + res.i = x.i + y.i; + return (res); +} + +t_complex complex_mul(t_complex x, t_complex y) +{ + t_complex res; + + res.r = x.r * y.r - x.i * y.i; + res.i = x.i * y.r + x.r * y.i; + return (res); +} + +double complex_norm(t_complex x) +{ + return (sqrt(x.r * x.r + x.i * x.i)); +} diff --git a/complex.h b/complex.h new file mode 100644 index 0000000..05a11ae --- /dev/null +++ b/complex.h @@ -0,0 +1,16 @@ +#ifndef COMPLEX_H +# define COMPLEX_H + +struct s_complex +{ + double r; + double i; +}; +typedef struct s_complex t_complex; + +t_complex to_complex(double x, double y); +t_complex complex_add(t_complex x, t_complex y); +t_complex complex_mul(t_complex x, t_complex y); +double complex_norm(t_complex x); + +#endif diff --git a/fractol.h b/fractol.h new file mode 100644 index 0000000..14669c5 --- /dev/null +++ b/fractol.h @@ -0,0 +1,24 @@ + +#ifndef FRACTOL_H +# define FRACTOL_H + +struct s_img +{ + void *img; + char *addr; + int bpp; + int bpl; + int endian; +}; +typedef struct s_img t_img; + +typedef unsigned int color; + +struct s_session +{ + void *mlx; + void *win; +}; +typedef struct s_session t_session; + +#endif diff --git a/main.c b/main.c index b38e40f..38766f4 100644 --- a/main.c +++ b/main.c @@ -10,15 +10,111 @@ /* */ /* ************************************************************************** */ +#include +#include +#include #include +#include "libft.h" +#include "fractol.h" +#include "complex.h" + +color *to_color_ptr(char *addr) +{ + return ((color *)addr); +} + +void ft_putpx_img(t_img *img, int x, int y, color color) +{ + *to_color_ptr(img->addr + y * img->bpl + x * img->bpp / CHAR_BIT) = color; + return ; +} + +color basic_palette(double normalized_par) +{ + unsigned char a; + unsigned char r; + unsigned char g; + unsigned char b; + color res; + + if (normalized_par == 0.) + return (0x00000000); + a = 0x00; + r = 0x00 + normalized_par * 0xFF; + g = 0x00 + normalized_par * 0xFF; + b = 0xFF - normalized_par * 0xFF; + res = (a << 24) | (r << 16) | (g << 8) | b; + return (res); +} + +color mandelbrot(t_complex c, double threshold, int max_count, color (*palette)(double)) +{ + const double min_threshold = 2.5; + int count; + t_complex z; + + if (threshold < min_threshold) + threshold = min_threshold; + count = 0; + z.r = 0; + z.i = 0; + while (complex_norm(z) < threshold && count < max_count) + { + z = complex_add(complex_mul(z, z), c); + ++count; + } + if (count == max_count) + count = 0; + return (palette((double)count / max_count)); +} + +void close_session(t_session *s) +{ + mlx_destroy_window(s->mlx, s->win); + mlx_loop_end(s->mlx); + return ; +} + +int handle_key_press(int keycode, t_session *s) +{ + if (keycode == XK_Escape) + close_session(s); + return (0); +} + +int handle_button_rel(int button_code, __attribute__((unused)) t_session *s) +{ + ft_printf("Button_code:\t%i\n", button_code); + return (0); +} int main(void) { - void *mlx; - void *mlx_win; + t_session s; + int x; + int y; + t_img img; - mlx = mlx_init(); - mlx_win = mlx_new_window(mlx, 1920, 1080, "Hello world!"); - mlx_loop(mlx); + s.mlx = mlx_init(); + s.win = mlx_new_window(s.mlx, 1920, 1080, "Hello world!"); + img.img = mlx_new_image(s.mlx, 1920, 1080); + img.addr = mlx_get_data_addr(img.img, &img.bpp, &img.bpl, &img.endian); + y = 0; + while (y <= 1080) + { + x = 0; + while (x <= 1920) + { + //ft_putpx_img(&img, x, y, basic_palette(x/1920.*y/1080.)); + ft_putpx_img(&img, x, y, mandelbrot(to_complex(5*(x/1920. - 0.5), 5*1080/1920*(y/1080. - 0.5)), 1000000, 100, basic_palette)); + ++x; + } + mlx_put_image_to_window(s.mlx, s.win, img.img, 0, 0); + ++y; + } + mlx_put_image_to_window(s.mlx, s.win, img.img, 0, 0); + mlx_hook(s.win, KeyPress, KeyPressMask, handle_key_press, &s); + mlx_hook(s.win, ButtonRelease, ButtonRelease, handle_button_rel, &s); + mlx_loop(s.mlx); return (0); } -- 2.30.2