diff --git a/CMakeLists.txt b/CMakeLists.txt index bf22b05..171bccc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,18 +8,22 @@ link_directories(libft minilibx) # libraries set(SOURCE_FILES src/main.c - src/help_func.c - src/color.c + src/help_func.c + src/color.c src/fractol_init.c src/hooks.c src/image_routine.c - src/complex.c src/julia.c src/mandelbrot.c) # sources + src/complex.c + src/julia.c + src/threads_routine.c + src/mandelbrot.c + src/burning_ship.c + src/fractal_routine.c + src/hooks_funcs.c + src/parse_input.c + src/hooks_funcs_1.c + src/hooks_funcs_2.c) # sources add_executable(fractol ${SOURCE_FILES}) # compilation -target_link_libraries(fractol - -lft - -lmlx - "-framework OpenGL" - "-framework AppKit" - -lpthread) # linkage +target_link_libraries(fractol -lft -lmlx "-framework OpenGL" "-framework AppKit") # linkage diff --git a/Makefile b/Makefile index 53bae0e..08b9506 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: gtertysh +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2016/12/14 16:54:48 by gtertysh #+# #+# # -# Updated: 2017/03/20 15:31:33 by gtertysh ### ########.fr # +# Updated: 2017/03/24 13:59:39 by gtertysh ### ########.fr # # # # **************************************************************************** # @@ -82,7 +82,7 @@ $(NAME): $(LIBFT_DIR)$(LIBFT) $(MLX_DIR)$(MLX) $(OBJ) $(OBJ_DIR)%.o: $(SRC_DIR)%.c $(FRACTOL_INC)$(FRACTOL_HEADER) @echo "$(CYAN)Compiling object files: $(BLUE)$@$(NORMAL)" - @$(CC) $(CC_FLAGS) $(INC) -c $< -o $@ + @$(CC) $(CC_FLAGS) $(OPT) $(INC) -c $< -o $@ $(LIBFT_DIR)$(LIBFT): @echo "$(CYAN)Compiling libft library...$(NORMAL)" diff --git a/inc/fractol.h b/inc/fractol.h index 58bd6ed..0214459 100644 --- a/inc/fractol.h +++ b/inc/fractol.h @@ -6,7 +6,7 @@ /* By: gtertysh +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/03/16 20:59:04 by gtertysh #+# #+# */ -/* Updated: 2017/03/20 15:32:52 by gtertysh ### ########.fr */ +/* Updated: 2017/03/24 14:00:01 by gtertysh ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,19 +17,13 @@ # include "mlx.h" # include # include -#include -#include +# include +# include +# include +# include -# define HEIGHT 1200 -# define WIDTH 1200 -# define COLOR1 0 -# define COLOR2 16777215 -# define INIT_X 30 -# define INIT_Y -20 -# define INIT_Z -45 -# define INIT_X_SCALE 0.9 -# define INIT_Y_SCALE 0.9 -# define INIT_Z_SCALE 0.1 +# define HEIGHT 700 +# define WIDTH 1300 # define RED 16711680 # define ORANGE 16744448 @@ -39,92 +33,121 @@ # define INDIGO 4915330 # define VIOLET 8323327 # define BLACK 0 +# define WHITE 16777215 -# define JUL_MAX_ITER 300 +# define NUM_COLORS 8 + +# define FRAC_MAX_ITR 150 + +# define NUM_THREADS 24 -# define NUM_THREADS 4 typedef struct s_complex { - double rl; - double im; + long double rl; + long double im; } t_complex; -typedef struct s_color -{ - int red; - int green; - int blue; -} t_color; - -typedef struct s_mw -{ - void *mlx; - void *win; -} t_mw; - typedef struct s_move { - int x; - int y; - double z; + long double x; + long double y; + long double z; } t_move; -typedef struct s_pixel +typedef struct s_color { - int x; - int y; -} t_pixel; + int red; + int grn; + int blu; +} t_color; -typedef struct s_julia +typedef struct s_gradient { - t_complex jul_const; - t_color color; + t_color grd[NUM_COLORS]; +} t_gradient; + +typedef struct s_frac_data +{ + t_complex com_const; + t_gradient grd; t_move mov; - int x; - int y; int max_itr; -} t_julia; + int com_rl_im_change; + int allow_mouse_change; + int frac_type; +} t_frac_data; -typedef struct s_fractals +typedef struct s_image { - t_julia *jul; -} t_fractals; + void *ptr; + char *data; + int l_size; + int end; + int bpp; +} t_image; + +typedef t_color (*frac_func)(t_frac_data *data, int x, int y); typedef struct s_fractol { - t_mw *mw; - t_fractals *fractals; + void *mlx; + void *win; + t_frac_data *frac; + frac_func fr_funcs[3]; int w_height; int w_width; - int bpp; - int line_size; - void *image; - char *image_data; - int endian; + t_image *img; } t_fractol; -int tab_length(char **tab); -void free_tab(char **tab); +typedef struct s_thread_data +{ + t_fractol fr; + int y_start; + int y_end; + frac_func fractal_func; +} t_thread_data; + void quit(t_fractol *fractol); void print_help(void); -t_color color_init(int red, int green, int blue); -t_color color_lerp(t_color c1, t_color c2, double step); -int rainbow(int step, int max_step); +void parse_input(int ac, char **av); -t_color int_to_color(int c); -int color_to_int(t_color c); -t_fractol *fractol_init(void); +t_color gradient(float value, t_gradient gradient); +t_gradient default_gradient(void); +t_gradient random_gradient(void); +int color_to_int(t_color c); + +t_fractol *fractol_init(void *mlx, int frac_type); int key_hook(int keycode, void *m); int mouse_move_hook( int x, int y, void *fr); int mouse_button_hook(int btn, int x, int y, void *fr); -void put_pixel_to_image(int x, int y, t_color *col, t_fractol *fr); +void put_pixel_to_image(int x, int y, t_color col, t_fractol *fr); void new_and_clear_image(t_fractol *fr); void complex_equal(double real, double imag, t_complex *c); -void draw_julia(t_fractol *fr); +t_frac_data *frac_init(int frac_type); +void *fractal_routine(void *th_data); +t_color julia(t_frac_data *ju, int x, int y); +t_color mandelbrot(t_frac_data *ma, int x, int y); +t_color ship(t_frac_data *sh, int x, int y); + +void fractal_fork(int frac_type); +void parallel_fractal(t_fractol *fr); + +void zoom_in(t_fractol *frm, int x, int y); +void zoom_out(t_fractol *fr); +void move_left(t_fractol *fr); +void move_right(t_fractol *fr); +void move_up(t_fractol *fr); +void move_down(t_fractol *fr); +void reset(t_fractol *fr); +void change_limit_down(t_fractol *fr); +void change_limit_up(t_fractol *fr); +int change_real(t_fractol *fr, int x, int *start_x); +int change_imagianry(t_fractol *fr, int x, int *start_x); +void gradient_hook(t_fractol *fr); #endif diff --git a/src/burning_ship.c b/src/burning_ship.c new file mode 100644 index 0000000..8ca265b --- /dev/null +++ b/src/burning_ship.c @@ -0,0 +1,32 @@ +#include "fractol.h" + +int complex_ship(t_complex new, t_complex com_const, t_frac_data *data) +{ + int i; + t_complex old; + + i = 0; + while (i < data->max_itr) + { + old = new; + new.rl = fabsl(old.rl * old.rl - old.im * old.im + com_const.rl); + new.im = fabsl(2 * old.rl * old.im + com_const.im); + if((new.rl * new.rl + new.im * new.im) > 4) + break ; + i++; + } + return (i); +} + +t_color ship(t_frac_data *sh, int x, int y) +{ + t_complex new; + int i; + + new.rl = 1.5 * (x - WIDTH / 2) / (0.5 * sh->mov.z * WIDTH) + + sh->mov.x - 0.5; + new.im = (y - HEIGHT / 2) / (0.5 * sh->mov.z * HEIGHT) + + sh->mov.y - 0.5; + i = complex_ship(sh->com_const, new, sh); + return (gradient((float)i / sh->max_itr, sh->grd)); +} diff --git a/src/color.c b/src/color.c index 8051c5a..6bc0440 100644 --- a/src/color.c +++ b/src/color.c @@ -12,89 +12,75 @@ #include "fractol.h" -t_color color_init(int red, int green, int blue) -{ - t_color c; - - c.red = red; - c.green = green; - c.blue = blue; - return (c); -} - -t_color color_lerp(t_color c1, t_color c2, double step) -{ - t_color new; - double red; - double green; - double blue; - - red = (double)(c2.red - c1.red) * step + c1.red; - green = (double)(c2.green - c1.green) * step + c1.green; - blue = (double)(c2.blue - c1.blue) * step + c1.blue; - new.red = (int)red; - new.green = (int)green; - new.blue = (int)blue; - return (new); -} - -int color_to_int(t_color c) -{ - return ((c.red << 16) | (c.green << 8) | c.blue); -} - -t_color int_to_color(int c) +t_color int_to_color(int c) { t_color new; - new.blue = c & 0x0000FF; - new.green = (c >> 8) & 0x0000FF; + new.blu = c & 0x0000FF; + new.grn = (c >> 8) & 0x0000FF; new.red = (c >> 16) & 0x0000FF; return (new); } -// -//int rainbow(int step, int max_step) -//{ -// if (step >= 0 && step < max_step / 8) -// return (RED); -// if (step >= max_step / 8 && step <= max_step / 4) -// return (ORANGE); -// if (step >= max_step / 4 && step <= max_step / 8 * 3) -// return (YELLOW); -// if (step >= max_step / 8 * 3 && step <= max_step / 2) -// return (BLUE); -// if (step >= max_step / 2 && step <= max_step / 8 * 5) -// return (VIOLET); -// if (step >= max_step / 8 * 5 && step <= max_step / 8 * 6) -// return (BLACK); -// return (0); -//} -int rainbow(int step, int max_step) +int color_to_int(t_color c) { - if (step >= 0 && step < max_step / 8) - return (color_to_int( - color_lerp(int_to_color(RED), int_to_color(ORANGE), - (float)step / (float)max_step))); - if (step >= max_step / 8 && step <= max_step / 8 * 2) - return (color_to_int( - color_lerp(int_to_color(ORANGE), int_to_color(YELLOW), - step / max_step / 8 * 2))); - if (step >= max_step / 8 * 2 && step <= max_step / 8 * 3) - return (color_to_int( - color_lerp(int_to_color(YELLOW), int_to_color(GREEN), - step / max_step / 8 * 3))); - if (step >= max_step / 8 * 3 && step <= max_step / 8 * 4) - return (color_to_int( - color_lerp(int_to_color(GREEN), int_to_color(BLUE), - step / max_step / 8 * 4))); - if (step >= max_step / 8 * 4 && step <= max_step / 8 * 5) - return (color_to_int( - color_lerp(int_to_color(BLUE), int_to_color(VIOLET), - step / max_step / 8 * 5))); - if (step >= max_step / 8 * 5 && step <= max_step / 8 * 6) - return (color_to_int( - color_lerp(int_to_color(VIOLET), int_to_color(BLACK), - step / max_step / 8 * 6))); - return (0); + return ((c.red << 16) | (c.grn << 8) | c.blu); } + +t_gradient default_gradient(void) +{ + t_gradient grad; + + grad.grd[0] = int_to_color(BLACK); + grad.grd[1] = int_to_color(BLUE); + grad.grd[2] = int_to_color(VIOLET); + grad.grd[3] = int_to_color(INDIGO); + grad.grd[4] = int_to_color(RED); + grad.grd[5] = int_to_color(ORANGE); + grad.grd[6] = int_to_color(YELLOW); + grad.grd[7] = int_to_color(WHITE); + return (grad); +} + +t_gradient random_gradient(void) +{ + t_gradient grad; + int i; + t_color c; + + i = 0; + while (i < NUM_COLORS) + { + c.red = rand() % 255; + c.grn = rand() % 255; + c.blu = rand() % 255; + grad.grd[i++] = c; + } + return (grad); +} + +t_color gradient(float value, t_gradient grad) +{ + int id1; + int id2; + float frac; + t_color c; + + frac = 0; + if(value <= 0) + id1 = id2 = 0; + else if(value >= 1) + id1 = id2 = NUM_COLORS - 1; + else + { + value = value * (NUM_COLORS - 1); + id1 = (int)floor(value); + id2 = id1 + 1; + frac = value - (float)id1; + } + c.red = (grad.grd[id2].red - grad.grd[id1].red) * frac + grad.grd[id1].red; + c.blu = (grad.grd[id2].blu - grad.grd[id1].blu) * frac + grad.grd[id1].blu; + c.grn = (grad.grd[id2].grn - grad.grd[id1].grn) * frac + grad.grd[id1].grn; + return (c); +} + diff --git a/src/fractal_routine.c b/src/fractal_routine.c new file mode 100644 index 0000000..b2435e2 --- /dev/null +++ b/src/fractal_routine.c @@ -0,0 +1,56 @@ +#include "fractol.h" + +void *fractal_routine(void *th_data) +{ + int x; + t_color col; + t_thread_data *data; + + data = (t_thread_data *)th_data; + while (data->y_start < HEIGHT && data->y_start < data->y_end) + { + x = 0; + while(x < data->fr.w_width) + { + col = data->fractal_func(data->fr.frac, x, data->y_start); + put_pixel_to_image(x, data->y_start, col, &data->fr); + x++; + } + data->y_start++; + } + free(data); + pthread_exit(NULL); +} + +t_frac_data *frac_init(int frac_type) +{ + t_frac_data *f; + + f = malloc(sizeof(t_frac_data)); + f->max_itr = FRAC_MAX_ITR; + f->grd = default_gradient(); + if (frac_type == 0) + complex_equal(-0.4, 0.6, &f->com_const); + else + complex_equal(0, 0, &f->com_const); + f->com_rl_im_change = 1; + f->allow_mouse_change = -1; + f->mov.x = 0; + f->mov.y = 0; + f->mov.z = 1; + f->frac_type = frac_type; + return (f); +} + +void fractal_fork(int frac_type) +{ + t_fractol *fr; + + fr = fractol_init(mlx_init(), frac_type); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); + mlx_hook(fr->win, 2, 5, key_hook, fr); + mlx_hook(fr->win, 6, (1L<<6), mouse_move_hook, fr); + mlx_hook(fr->win, 4, (1L<<0), mouse_button_hook, fr); + mlx_loop(fr->mlx); +} \ No newline at end of file diff --git a/src/fractol_init.c b/src/fractol_init.c index 14d6900..58ca081 100644 --- a/src/fractol_init.c +++ b/src/fractol_init.c @@ -12,41 +12,17 @@ #include "fractol.h" -static t_mw *mlx_and_win_ptr_init(int x, int y) +t_image *img_init(void *mlx) { - t_mw *mw; + t_image *img; - if ((mw = malloc(sizeof(t_mw)))) - { - mw->mlx = mlx_init(); - mw->win = mlx_new_window(mw->mlx, x, y, "FRCTL"); - } - return (mw); + img = malloc(sizeof(t_image)); + img->ptr = mlx_new_image(mlx, WIDTH, HEIGHT); + img->data = mlx_get_data_addr(img->ptr, &img->bpp, &img->l_size, &img->end); + return (img); } -t_julia *jul_init(void) -{ - t_julia *j; - - j = malloc(sizeof(t_julia)); - complex_equal(-0.7, 0.27015, &j->jul_const); - j->max_itr = JUL_MAX_ITER; - j->mov.x = 0; - j->mov.y = 0; - j->mov.z = 1; - return (j); -} - -t_fractals *frac_init(void) -{ - t_fractals *f; - - f = malloc(sizeof(t_fractals)); - f->jul = jul_init(); - return (f); -} - -t_fractol *fractol_init(void) +t_fractol *fractol_init(void *mlx, int frac_type) { t_fractol *fractol; @@ -54,9 +30,13 @@ t_fractol *fractol_init(void) { fractol->w_height = HEIGHT; fractol->w_width = WIDTH; - fractol->fractals = frac_init(); - fractol->mw = mlx_and_win_ptr_init(WIDTH, HEIGHT); - fractol->image = NULL; + fractol->mlx = mlx; + fractol->win = mlx_new_window(fractol->mlx, WIDTH, HEIGHT, "FRCTL"); + fractol->img = img_init(fractol->mlx); + fractol->frac = frac_init(frac_type); + fractol->fr_funcs[0] = julia; + fractol->fr_funcs[1] = mandelbrot; + fractol->fr_funcs[2] = ship; } return (fractol); } diff --git a/src/help_func.c b/src/help_func.c index 35e556c..fc8e9bd 100644 --- a/src/help_func.c +++ b/src/help_func.c @@ -12,17 +12,10 @@ #include "fractol.h" -void free_tab(char **tab) -{ - while (*tab) - free(*tab++); - free(*tab); -} - void quit(t_fractol *fr) { - if (fr && fr->mw->mlx && fr->mw->win) - mlx_destroy_window(fr->mw->mlx, fr->mw->win); + if (fr && fr->mlx && fr->win) + mlx_destroy_window(fr->mlx, fr->win); exit(0); } @@ -30,27 +23,8 @@ void print_help(void) { ft_putstr( "Usage: " - "fdf [OPTIONS] MAP_PATH" + "fractol [FRACTALS..]" "\n\n" - "Opitons:\n" - "--heatmap \"R,G,B - R,G,B\"" - "\toptional parameter for specifying color range of\n" - "\t\t\t\theatmap in RGB format. Each color component\n" - "\t\t\t\tshould be between 0 and 255.\n" - "\t\t\t\tPlease, put range in double quotes, for example:\n\n" - "\t\t\t\tfdf --heatmap \"125,255,6 - 250,41,1\" ~/maps/42.fdf\n\n"); -} - -int tab_length(char **tab) -{ - int len; - - len = 0; - if (tab) - while (*tab) - { - tab++; - len++; - } - return (len); -} + "Fractals:\n" + "\033[32mjulia\033[0m \033[34mship \033[36mmandelbrot\033[0m\n"); +} \ No newline at end of file diff --git a/src/hooks.c b/src/hooks.c index 7a88667..6e61d4b 100644 --- a/src/hooks.c +++ b/src/hooks.c @@ -6,7 +6,7 @@ /* By: gtertysh +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2017/03/16 18:59:03 by gtertysh #+# #+# */ -/* Updated: 2017/03/20 15:29:10 by gtertysh ### ########.fr */ +/* Updated: 2017/03/24 14:02:46 by gtertysh ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,35 +17,51 @@ int key_hook(int keycode, void *fr) printf("%d\n", keycode); if (keycode == 53) quit(fr); -// if (keycode == 89) -// aclock_rot(fdf); -// if (keycode == 86) -// left_rot(fdf); -// if (keycode == 88) -// right_rot(fdf); -// if (keycode == 87) -// back_rot(fdf); -// if (keycode == 91) -// forw_rot(fdf); -// if (keycode == 92) -// clock_rot(fdf); -// if (keycode == 83) -// scale_up_z(fdf); -// if (keycode == 84) -// scale_down_z(fdf); -// if (keycode == 69) -// zoom_in(fdf); -// if (keycode == 78) -// zoom_out(fdf); -// if (keycode == 82) -// reset(fdf); + if (keycode == 49) + gradient_hook(fr); + if (keycode == 124) + move_left(fr); + if (keycode == 123) + move_right(fr); + if (keycode == 125) + move_up(fr); + if (keycode == 126) + move_down(fr); + if (keycode == 69) + change_limit_up(fr); + if (keycode == 78) + change_limit_down(fr); return (0); } +/* + * beware!! shitcode on lines 48-49. + */ + int mouse_move_hook( int x, int y, void *fr) { - fr = 0; + static int start_x = WIDTH / 2; + int to_render; + t_fractol *fr_p; + + to_render = 0; + y = to_render; printf("x = %d, y = %d\n", x, y); + to_render = y; + fr_p = (t_fractol *)fr; + if (fr_p->frac->com_rl_im_change == 1 && + fr_p->frac->allow_mouse_change == 1) + to_render = change_real(fr_p, x, &start_x); + else if (fr_p->frac->com_rl_im_change == -1 && + fr_p->frac->allow_mouse_change == 1) + to_render = change_imagianry(fr_p, x, &start_x); + if (to_render) + { + new_and_clear_image(fr_p); + parallel_fractal(fr_p); + mlx_put_image_to_window(fr_p->mlx, fr_p->win, fr_p->img->ptr, 0, 0); + + } return (0); } @@ -53,9 +69,14 @@ int mouse_button_hook(int btn, int x, int y, void *fr) { printf("x = %d, y = %d, btn = %d\n", x, y, btn); if (btn == 4) - { - ((t_fractol *)fr)->fractals->jul->mov.z += 0.3; - draw_julia((t_fractol *)fr); - } + zoom_in(fr, x, y); + if (btn == 5) + zoom_out(fr); + if (btn == 3) + ((t_fractol *)fr)->frac->com_rl_im_change *= -1; + if (btn == 2) + ((t_fractol *)fr)->frac->allow_mouse_change *= -1; + if (btn == 1) + reset(fr); return (0); } diff --git a/src/hooks_funcs.c b/src/hooks_funcs.c new file mode 100644 index 0000000..a90bc28 --- /dev/null +++ b/src/hooks_funcs.c @@ -0,0 +1,61 @@ +#include "fractol.h" + +void gradient_hook(t_fractol *fr) +{ + fr->frac->grd = random_gradient(); + new_and_clear_image(fr); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); +} + +int change_imagianry(t_fractol *fr, int x, int *start_x) +{ + int to_render; + + to_render = 0; + if (x > *start_x) + { + if (fr->frac->com_const.im < 3) + { + fr->frac->com_const.im += 0.01; + to_render = 1; + } + *start_x = x; + } + else if (x < *start_x) + { + if (fr->frac->com_const.im > -4) + { + fr->frac->com_const.im -= 0.1; + to_render = 1; + } + *start_x = x; + } + return (to_render); +} + +int change_real(t_fractol *fr, int x, int *start_x) +{ + int to_render; + + to_render = 0; + if (x > *start_x) + { + if (fr->frac->com_const.rl < 3) + { + fr->frac->com_const.rl += 0.1; + to_render = 1; + } + *start_x = x; + } + else if (x < *start_x) + { + if (fr->frac->com_const.rl > -4) + { + fr->frac->com_const.rl -= 0.1; + to_render = 1; + } + *start_x = x; + } + return (to_render); +} \ No newline at end of file diff --git a/src/hooks_funcs_1.c b/src/hooks_funcs_1.c new file mode 100644 index 0000000..29dc049 --- /dev/null +++ b/src/hooks_funcs_1.c @@ -0,0 +1,54 @@ +#include "fractol.h" + +void move_down(t_fractol *fr) +{ + printf("z %Lf\n", fr->frac->mov.z); + fr->frac->mov.y += 1.f / fr->frac->mov.z * 0.2; + new_and_clear_image(fr); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); +} + +void move_up(t_fractol *fr) +{ + printf("z %Lf\n", fr->frac->mov.z); + fr->frac->mov.y -= 1.f / fr->frac->mov.z * 0.2; + new_and_clear_image(fr); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); +} + +void reset(t_fractol *fr) +{ + fr->frac->mov.x = 0; + fr->frac->mov.y = 0; + fr->frac->mov.z = 1; + fr->frac->max_itr = FRAC_MAX_ITR; + fr->frac->grd = default_gradient(); + if (fr->frac->frac_type == 0) + complex_equal(-0.4, 0.6, &fr->frac->com_const); + else + complex_equal(0, 0, &fr->frac->com_const); + new_and_clear_image(fr); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); +} + +void change_limit_up(t_fractol *fr) +{ + fr->frac->max_itr +=50; + new_and_clear_image(fr); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); +} + +void change_limit_down(t_fractol *fr) +{ + if (fr->frac->max_itr >= 100) + { + fr->frac->max_itr -= 50; + new_and_clear_image(fr); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); + } +} \ No newline at end of file diff --git a/src/hooks_funcs_2.c b/src/hooks_funcs_2.c new file mode 100644 index 0000000..5ac874c --- /dev/null +++ b/src/hooks_funcs_2.c @@ -0,0 +1,44 @@ +#include "fractol.h" + +void zoom_in(t_fractol *fr, int x, int y) +{ + int center_x; + int center_y; + + center_x = WIDTH / 2; + center_y = HEIGHT / 2; + new_and_clear_image(fr); + fr->frac->mov.z *= 1.5; + fr->frac->mov.x += ((float)x - center_x) / (center_x * fr->frac->mov.z) * 0.8; + fr->frac->mov.y += ((float)y - center_y) / (center_y * fr->frac->mov.z) * 0.8; + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); + +} + +void zoom_out(t_fractol *fr) +{ + new_and_clear_image(fr); + fr->frac->mov.z /= 2; + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); + +} + +void move_left(t_fractol *fr) +{ + printf("z %Lf\n", fr->frac->mov.z); + fr->frac->mov.x -= 1.f / fr->frac->mov.z * 0.2; + new_and_clear_image(fr); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); +} + +void move_right(t_fractol *fr) +{ + printf("z %Lf\n", fr->frac->mov.z); + fr->frac->mov.x += 1.f / fr->frac->mov.z * 0.2; + new_and_clear_image(fr); + parallel_fractal(fr); + mlx_put_image_to_window(fr->mlx, fr->win, fr->img->ptr, 0, 0); +} diff --git a/src/image_routine.c b/src/image_routine.c index 2dc35c2..b6a31eb 100644 --- a/src/image_routine.c +++ b/src/image_routine.c @@ -16,21 +16,21 @@ void new_and_clear_image(t_fractol *fr) { if (fr) { - if (fr->image) - mlx_destroy_image(fr->mw->mlx, fr->image); - fr->image = mlx_new_image(fr->mw->mlx, WIDTH, HEIGHT); - fr->image_data = mlx_get_data_addr( - fr->image, - &fr->bpp, - &fr->line_size, - &fr->endian); + if (fr->img->ptr) + mlx_destroy_image(fr->mlx, fr->img->ptr); + fr->img->ptr = mlx_new_image(fr->mlx, WIDTH, HEIGHT); + fr->img->data = mlx_get_data_addr( + fr->img->ptr, + &fr->img->bpp, + &fr->img->l_size, + &fr->img->end); } } -void put_pixel_to_image(int x, int y, t_color *col, t_fractol *fr) +void put_pixel_to_image(int x, int y, t_color col, t_fractol *fr) { if (x < 0 || y < 0 || x >= fr->w_width || y >= fr->w_height) return ; - *(int *)((fr->image_data + x * fr->bpp / 8 + y * fr->line_size)) = - color_to_int(*col); + *(int *)((fr->img->data + x * fr->img->bpp / 8 + y * fr->img->l_size)) = + color_to_int(col); } diff --git a/src/julia.c b/src/julia.c index 8bfa36d..e933095 100644 --- a/src/julia.c +++ b/src/julia.c @@ -1,12 +1,12 @@ #include "fractol.h" -int complex_parallel(t_complex new, t_complex com_const) +int complex_jul(t_complex new, t_complex com_const, t_frac_data *data) { int i; t_complex old; i = 0; - while (i < JUL_MAX_ITER) + while (i < data->max_itr) { old = new; new.rl = old.rl * old.rl - old.im * old.im + com_const.rl; @@ -18,67 +18,14 @@ int complex_parallel(t_complex new, t_complex com_const) return (i); } -void *julia_computation(void *fr) +t_color julia(t_frac_data *ju, int x, int y) { t_complex new; - t_julia *ju; int i; - int x; - int y; - ju = ((t_fractol *)fr)->fractals->jul; - x = ju->x; - y = ju->y; new.rl = 1.5 * (x - WIDTH / 2) / (0.5 * ju->mov.z * WIDTH) + ju->mov.x; new.im = (y - HEIGHT / 2) / (0.5 * ju->mov.z * HEIGHT) + ju->mov.y; - i = complex_parallel(new, ju->jul_const); - ju->color = int_to_color(rainbow(i, ju->max_itr)); - put_pixel_to_image(x, y, &((t_fractol *)fr)->fractals->jul->color, fr); - return (0); + i = complex_jul(new, ju->com_const, ju); + return (gradient((float)i / ju->max_itr, ju->grd)); } -//void julia_parralel(t_fractol *fr) -//{ -// pthread_t threads[NUM_THREADS]; -// t_fractol *fr_tmp; -// int rc; -// int i; -// -// i = 0; -// while (i < NUM_THREADS && fr->fractals->jul->y < fr->w_width) -// { -// fr_tmp = malloc(sizeof(t_fractol)); -// *fr_tmp = *fr; -//// printf("In main: creating thread %d\n", i); -// rc = pthread_create(&threads[i], NULL, julia_computation, (void *)fr_tmp); -// if (rc){ -// printf("ERROR; return code from pthread_create() is %d\n", rc); -// exit(-1); -// } -// free(fr_tmp); -// fr->fractals->jul->y++; -// i++; -// } -//} - - -void draw_julia(t_fractol *fr) -{ - int x; - int y; - new_and_clear_image(fr); - y = 0; - while (y < fr->w_height) - { - x = 0; - while(x < fr->w_width) - { - fr->fractals->jul->x = x; - fr->fractals->jul->y = y; - julia_computation(fr); - x++; - } - y++; - } - mlx_put_image_to_window(fr->mw->mlx, fr->mw->win, fr->image, 0, 0); -} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 35f1a32..1396f0f 100644 --- a/src/main.c +++ b/src/main.c @@ -12,19 +12,9 @@ #include "fractol.h" - - -int main(void) +int main(int argc, char **argv) { - t_fractol *fr; - - fr = NULL; - - fr = fractol_init(); - draw_julia(fr); - mlx_hook(fr->mw->win, 2, 5, key_hook, fr); - mlx_hook(fr->mw->win, 4, 0, mouse_button_hook, fr); - mlx_hook(fr->mw->win, 6, 0, mouse_move_hook, fr); - mlx_loop(fr->mw->mlx); - pthread_exit(NULL); + srand(time(NULL)); + parse_input(argc, argv); + return (0); } diff --git a/src/mandelbrot.c b/src/mandelbrot.c index 82ebaca..5a829cb 100644 --- a/src/mandelbrot.c +++ b/src/mandelbrot.c @@ -1,43 +1,32 @@ #include "fractol.h" -//static void julia_computation(int x, int y, t_julia *ju) -//{ -// t_complex new; -// t_complex old; -// int i; -// -// new.rl = 1.5 * (x - WIDTH / 2) / (0.5 * ju->mov.z * WIDTH) + ju->mov.x; -// new.im = (y - HEIGHT / 2) / (0.5 * ju->mov.z * HEIGHT) + ju->mov.y; -// i = 0; -// while (i < ju->max_iterations) -// { -// old = new; -// new.rl = old.rl * old.rl - old.im * old.im + ju->jul_const.rl; -// new.im = 2 * old.rl * old.im + ju->jul_const.im; -// if((new.rl * new.rl + new.im * new.im) > 4) -// break ; -// i++; -// } -// ju->color = int_to_color(rainbow(i, ju->max_iterations)); -//} -// -// -//void draw_julia(t_fractol *fr) -//{ -// int x; -// int y; -// -// x = 0; -// while (x < fr->w_width) -// { -// y = 0; -// while(y < fr->w_height) -// { -// julia_computation(x, y, fr->fractals->jul); -// put_pixel_to_image(x, y, &fr->fractals->jul->color, fr); -// y++; -// } -// x++; -// } -// mlx_put_image_to_window(fr->mw->mlx, fr->mw->win, fr->image, 0, 0); -//} \ No newline at end of file +int complex_man(t_complex new, t_complex com_const, t_frac_data *data) +{ + int i; + t_complex old; + + i = 0; + while (i < data->max_itr) + { + old = new; + new.rl = old.rl * old.rl - old.im * old.im + com_const.rl; + new.im = 2 * old.rl * old.im + com_const.im; + if((new.rl * new.rl + new.im * new.im) > 4) + break ; + i++; + } + return (i); +} + +t_color mandelbrot(t_frac_data *ma, int x, int y) +{ + t_complex new; + int i; + + new.rl = 1.5 * (x - WIDTH / 2) / (0.5 * ma->mov.z * WIDTH) + + ma->mov.x - 0.7; + new.im = (y - HEIGHT / 2) / (0.5 * ma->mov.z * HEIGHT) + + ma->mov.y; + i = complex_man(ma->com_const, new, ma); + return (gradient((float)i / ma->max_itr, ma->grd)); +} diff --git a/src/parse_input.c b/src/parse_input.c new file mode 100644 index 0000000..a8dd5e7 --- /dev/null +++ b/src/parse_input.c @@ -0,0 +1,43 @@ +#include + +int check_argument(char *arg) +{ + if (!ft_strcmp(arg, "julia")) + return (0); + if (!ft_strcmp(arg, "mandelbrot")) + return (1); + if (!ft_strcmp(arg, "ship")) + return (2); + return (-1); +} + +void error(void) +{ + print_help(); + quit(0); +} + +void parse_input(int ac, char **av) +{ + int i; + int frac_type; + int pid; + + if (ac < 2) + error(); + i = 0; + while (i < ac - 1) + if (((frac_type = check_argument(av[i + 1])) != -1)) + { + pid = fork(); + if (pid > 0) + { + fractal_fork(frac_type); + break ; + } + if (pid == 0) + i++; + } + else + error(); +} \ No newline at end of file diff --git a/src/threads_routine.c b/src/threads_routine.c new file mode 100644 index 0000000..149b03b --- /dev/null +++ b/src/threads_routine.c @@ -0,0 +1,37 @@ +#include "fractol.h" + +t_thread_data *thread_data_init(t_fractol *fr, int i) +{ + t_thread_data *data; + int img_strip; + + img_strip = (int)ceil(HEIGHT / NUM_THREADS) + 1; + data = malloc(sizeof(t_thread_data)); + data->y_start = img_strip * i; + data->y_end = data->y_start + img_strip; + data->fr = *fr; + data->fractal_func = fr->fr_funcs[fr->frac->frac_type]; + return (data); +} + +void parallel_fractal(t_fractol *fr) +{ + pthread_t threads[NUM_THREADS]; + pthread_attr_t attr; + t_thread_data *data; + int i; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + i = 0; + while (i < NUM_THREADS) + { + data = thread_data_init(fr, i); + pthread_create(&threads[i], &attr, fractal_routine, (void *)data); + i++; + } + pthread_attr_destroy(&attr); + i = 0; + while (i < NUM_THREADS) + pthread_join(threads[i++], NULL); +} \ No newline at end of file