#include <X11/keysym.h>
#include <limits.h>
#include <stdlib.h>
+#include <math.h>
#include <mlx.h>
#include "libft.h"
#include "fractol.h"
#include "complex.h"
#include "color.h"
+#include "vect2.h"
void ft_putpx_img(t_img *img, int x, int y, t_color c)
{
return ;
}
-int handle_key_press(int keycode, t_window *w)
+int is_black(t_img *img, int x, int y)
{
- if (keycode == XK_Escape)
- mlx_destroy_window(w->s, w->s->windows[w->index]);
- return (0);
-}
+ char *px_addr;
-int handle_button_rel(int button_code, __attribute__((unused)) t_session *s)
-{
- ft_printf("Button_code:\t%i\n", button_code);
- return (0);
+ px_addr = img->addr + y * img->bpl + x * img->bpp / CHAR_BIT;
+ return (!(px_addr[0] || px_addr[1] || px_addr[2] || px_addr[3]));
}
+
void free_session(t_session *s)
{
- size_t i;
-
- i = 0;
- while (i < s->win_count)
- mlx_destroy_window(s->mlx, s->windows[i]);
- free(s->windows);
+ mlx_destroy_display(s->mlx);
free(s->mlx);
return ;
}
-void free_img(t_img *i)
-{
- free(i->img);
- free(i->addr);
- return ;
-}
-
-enum mlx_status add_mlx_window(t_session *s, int x, int y, char *name)
-{
- void **tmp;
-
- tmp = malloc((s->win_count + 1) * sizeof(s->windows));
- if (!tmp)
- return (mlx_window_error);
- ft_memcpy(tmp, s->windows, s->win_count);
- free(s->windows);
- s->windows = tmp;
- (s->windows)[s->win_count] = mlx_new_window(s->mlx, x, y, name);
- if (!(s->windows)[s->win_count])
- return (mlx_window_error);
- ++(s->win_count);
- return (mlx_success);
-}
-
-t_color mandelbrot(t_complex c, double threshold, int max_count, t_color (*palette)(double))
+double mandelbrot(double x, double y, double resolution)
{
+ double threshold;
const double min_threshold = 2.5;
+ double max_count;
int count;
+ t_complex c;
t_complex z;
+ c.r = x;
+ c.i = y;
+ max_count = 100 * resolution;
+ threshold = 3;
if (threshold < min_threshold)
threshold = min_threshold;
count = 0;
++count;
}
if (count == max_count)
- count = 0;
- return (palette((double)count / max_count));
+ return (0);
+ return (fmod(count / 100., 1.));
}
-/*
-int main(void)
+
+
+int draw_fractal(t_session *s)
{
- t_session s;
- t_img img;
+ int x;
+ int y;
+ double palette_param;
- s.win_count = 0;
- s.windows = NULL;
- s.mlx = mlx_init();
- add_mlx_window(&s, 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);
- mlx_hook(s.windows[0], KeyPress, KeyPressMask, handle_key_press, &(t_window){.s=&s, .index=0});
- mlx_hook(s.windows[0], ButtonRelease, ButtonRelease, handle_button_rel, &s);
- mlx_loop(s.mlx);
- mlx_destroy_image(s.mlx, img.img);
- mlx_destroy_display(s.mlx);
- free_img(&img);
- free_session(&s);
+ x = 0;
+ while (x < s->img.width)
+ {
+ y = 0;
+ while (y < s->img.height)
+ {
+ if(!is_black(&s->img, x, y) && !s->view.draw_whole)
+ {
+ ++y;
+ continue ;
+ }
+ palette_param = s->view.fractal(
+ s->view.window_coord.x + s->view.pixel_size.x * x,
+ s->view.window_coord.y - s->view.pixel_size.y * y,
+ s->view.resolution);
+ ft_putpx_img(&s->img, x, y, s->view.palette(palette_param));
+ ++y;
+ }
+ ++x;
+ }
+ mlx_put_image_to_window(s->mlx, s->win, s->img.img, 0, 0);
return (0);
}
-*/
-
-typedef struct
+void change_zoom(t_view *view, t_vect2 invariant, double d_zoom)
{
- void *mlx;
- void *win;
-} t_test;
+ view->pixel_size.x /= d_zoom;
+ view->pixel_size.y /= d_zoom;
+ view->window_coord.x += view->pixel_size.x * invariant.x * (d_zoom - 1);
+ view->window_coord.y -= view->pixel_size.y * invariant.y * (d_zoom - 1);
+ view->resolution = 1;
+ view->draw_whole = 1;
+ return ;
+}
-int esc_close(int keycode, t_test *t)
+int handle_key_press(int keycode, t_session *s)
{
if (keycode == XK_Escape)
- mlx_destroy_window(t->mlx, t->win);
+ mlx_destroy_window(s->mlx, s->win);
+ return (0);
+}
+
+int handle_mouse_press(int button, int x, int y, t_session *s)
+{
+ double delta_zoom;
+
+ if (button == Button4)
+ delta_zoom = 0.5;
+ else if (button == Button5)
+ delta_zoom = 2;
+ if (button == Button4 || button == Button5)
+ {
+ change_zoom(&s->view, (t_vect2){.x = x, .y = y}, delta_zoom);
+ draw_fractal(s);
+ }
return (0);
}
-int no_event(__attribute__((unused)) t_test *t)
+int no_event_handle(__attribute__((unused)) t_session *s)
{
+ if (s->view.resolution < 100)
+ {
+ s->view.draw_whole = 0;
+ s->view.resolution *= 2;
+ draw_fractal(s);
+ }
return (0);
}
-int main(void)
+void init_view(t_session *s)
+{
+ s->view.fractal = mandelbrot;
+ s->view.palette = tri_color;
+ s->view.pixel_size.x = 0.01;
+ s->view.pixel_size.y = 0.01;
+ s->view.window_coord.x = -s->img.width / 2 * s->view.pixel_size.x;
+ s->view.window_coord.y = s->img.height / 2 * s->view.pixel_size.y;
+ s->view.resolution = 1;
+ s->view.draw_whole = 1;
+ return ;
+}
+
+void parse_args(int argc, char **argv, t_session *s)
+{
+ if (argc == 0)
+ free(argv);
+ s->img.width = 1024;
+ s->img.height = 768;
+ init_view(s);
+ return ;
+}
+
+int main(int argc, char **argv)
{
- t_test t;
-
- t.mlx = mlx_init();
- t.win = mlx_new_window(t.mlx, 1920, 1080, "TEST");
- mlx_hook(t.win, KeyPress, KeyPressMask, esc_close, &t);
- mlx_loop_hook(t.mlx, no_event, &t);
- mlx_loop(t.mlx);
- mlx_destroy_display(t.mlx);
- free(t.mlx);
+ t_session s;
+
+ parse_args(argc, argv, &s);
+ s.mlx = mlx_init();
+ s.win = mlx_new_window(s.mlx, s.img.width, s.img.height, "Fract-ol");
+ s.img.img = mlx_new_image(s.mlx, s.img.width, s.img.height);
+ s.img.addr = mlx_get_data_addr(s.img.img, &s.img.bpp, &s.img.bpl, &s.img.endian);
+ mlx_hook(s.win, KeyPress, KeyPressMask, handle_key_press, &s);
+ mlx_hook(s.win, ButtonPress, ButtonPressMask, handle_mouse_press, &s);
+ mlx_loop_hook(s.mlx, no_event_handle, &s);
+ draw_fractal(&s);
+ mlx_loop(s.mlx);
+ mlx_destroy_image(s.mlx, s.img.img);
+ free_session(&s);
return (0);
}