Add the julia set and an input option
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 25 Apr 2024 13:56:33 +0000 (15:56 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 25 Apr 2024 13:56:33 +0000 (15:56 +0200)
The input is interpreted as thousands so that "float to int" needs not
be implemented.

inc/fractals.h
inc/fractol.h
src/fractals.c
src/main.c

index 9a3a5539199d37c3ae7b73e17b2717c3787eddb7..a3277de25ea541abd348b1d394081a88fad1556e 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/01/19 10:56:55 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/25 09:43:50 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/04/25 15:10:14 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 
 # include "fractol.h"
 
-double general_julia(void *zeroth, double resolution,
-                                               void (*tested_f)(void *), int (*is_over_thresh)(void *));
+//double       general_julia(void *zeroth, double resolution,
+//                                             void (*tested_f)(void *), int (*is_over_thresh)(void *));
+
 double mandelbrot(t_set *settings, double x, double y);
 double tricorn(t_set *settings, double x, double y);
+double julia(t_set *settings, double x, double y);
 
 #endif //FRACTALS_H
index cd5e86a04254d825bb2d9f5b1b03cd9a5db394b9..b0404ef828daa20100b2f8352b0771797469c546 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2023/11/11 18:51:29 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/25 09:41:47 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/04/25 15:06:22 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -16,6 +16,7 @@
 # include "libft.h"
 # include "color.h"
 # include "vect2.h"
+# include "complex.h"
 
 struct s_img
 {
@@ -46,10 +47,17 @@ struct s_view
 };
 typedef struct s_view  t_view;
 
+union u_input
+{
+       t_complex       cpx;
+};
+typedef union u_input  t_input;
+
 struct s_set
 {
-       int     detail;
-       int     color_stability;
+       int             detail;
+       int             color_stability;
+       t_input input;
 };
 typedef struct s_set   t_set;
 
index 069fc4cd160c11b80f9f20d72656ae5b6f9d8ce7..605049592f97fe4c8ca2965f12e1025e0e8e13ca 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2023/12/05 19:57:50 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/25 11:13:38 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/04/25 15:14:16 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -22,6 +22,7 @@ double        normalize_count(int count, double norm, double color_stability)
        return (fmod((double)(count + 1 - log(log(norm) / log(2)) / log(2)) / color_stability, 1.));
 }
 
+/*
 double general_julia(void *zeroth, double resolution,
                                                void (*tested_f)(void *), int (*is_over_thresh)(void *))
 {
@@ -35,7 +36,30 @@ double       general_julia(void *zeroth, double resolution,
        }
        if (count == 100 * resolution)
                return (-1);
-       return (fmod(count / 100., 1.));
+       return (normalize_count(count, norm(zeroth), color_stability);
+}
+*/
+
+double julia(t_set *settings, double x, double y)
+{
+       int                     count;
+       t_complex       c;
+       t_complex       z;
+
+       c = settings->input.cpx;
+       z.r = x;
+       z.i = y;
+       count = 4;
+       if (complex_norm(c) > THRESHOLD)
+               return (normalize_count(count, THRESHOLD, settings->color_stability));
+       while (complex_norm(z) <= THRESHOLD && count < settings->detail)
+       {
+               z = complex_add(complex_mul(z, z), c);
+               ++count;
+       }
+       if (count == settings->detail)
+               return (-1);
+       return (normalize_count(count, complex_norm(z), settings->color_stability));
 }
 
 double mandelbrot(t_set *settings, double x, double y)
index e258329936f8a87eeb6d5d085490f08d4ff21a5c..d083ea5a82adfaf42c2f887360279e6ea4f34e44 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2023/10/27 14:29:26 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/25 14:46:40 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/04/25 15:45:14 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -220,6 +220,7 @@ void        set_default(t_session *s)
        s->view.palette = tri_color;
        s->view.color_shift_speed = -0.001;
        s->set.color_stability = 100;
+       s->set.input.cpx = (t_complex){.r = -0.4, .i = 0.6};
        s->view.pixel_size.x = 0.01;
        s->view.pixel_size.y = 0.01;
        s->view.color_shift = 0;
@@ -232,10 +233,50 @@ t_fractal to_fractal(const char *name)
                return (mandelbrot);
        else if (!ft_strcmp(name, "tri") || !ft_strcmp(name, "tricorn"))
                return (tricorn);
+       else if (!ft_strcmp(name, "ju") || !ft_strcmp(name, "julia"))
+               return (julia);
        else
                return (NULL);
 }
 
+// The input has to be a single string of the form i1,i2,... without whitespace
+// There has to be correct number of inputs for the chosen fractal
+// The input has to be composed of integers
+int    is_correct_input(const char *str, t_fractal fractal)
+{
+       int     count;
+
+       count = 0;
+       while (*str)
+       {
+               ++count;
+               while (ft_isdigit(*str) || *str == '-')
+                       ++str;
+               if (*str == ',')
+                       ++str;
+               else if (*str != '\0')
+                       return (0);
+       }
+       if (fractal == julia && count != 2)
+               return (0);
+       return (1);
+}
+
+t_input        parse_input(const char *str, t_fractal fractal)
+{
+       t_input res;
+
+       if (fractal == julia)
+       {
+               res.cpx.r = ft_atoi(str) / 1000.;
+               while (ft_isdigit(*str) || *str == '-')
+                       ++str;
+               ++str;
+               res.cpx.i = ft_atoi(str) / 1000.;
+       }
+       return (res);
+}
+
 int    parse_arg(char **argv, t_session *s, int *i)
 {
                if (!ft_strcmp(argv[*i], "-w") && ft_isint(argv[*i + 1]) && ft_atoi(argv[*i + 1]) > 0)
@@ -247,11 +288,13 @@ int       parse_arg(char **argv, t_session *s, int *i)
                else if (!ft_strcmp(argv[*i], "-d") && ft_isint(argv[*i + 1]))
                        s->set.detail = ft_atoi(argv[++*i]);
                else if (!ft_strcmp(argv[*i], "-f") && to_fractal(argv[*i + 1]) != NULL)
-                       s->view.fractal = to_fractal(argv[*i + 1]);
+                       s->view.fractal = to_fractal(argv[++*i]);
                else if (!ft_strcmp(argv[*i], "-s") && ft_isint(argv[*i + 1]))
                        s->view.color_shift_speed = ft_atoi(argv[++*i]) / 1000.;
                else if (!ft_strcmp(argv[*i], "-c") && ft_isint(argv[*i + 1]))
                        s->set.color_stability = 10000 / ft_atoi(argv[++*i]);
+               else if (!ft_strcmp(argv[*i], "-i") && is_correct_input(argv[*i + 1], s->view.fractal))
+                       s->set.input = parse_input(argv[++*i], s->view.fractal);
                else
                        return (1);
                return (0);
@@ -287,6 +330,12 @@ static const char  *help_str =
        "\t-f\n\t\tOne of these fractals:\n"
        "\t\t\tman[delbrot]\n"
        "\t\t\ttri[corn]\n"
+       "\t\t\tju[lia]\n"
+       "\t-i\n\t\tInput for selected fractal. Has to be after -f option.\n"
+       "\t\t\tmandelbrot\t- no input\n"
+       "\t\t\ttricorn\t\t- no input\n"
+       "\t\t\tjulia\t\t- a complex number in the form real,complex\n"
+       "\t\t\t\t\t- the complex number will be divided by 1000 after input\n"
        "\t-s\n\t\tSpeed of color change (negative values reverse the direction)\n"
        "\t-c\n\t\tColorfulness\n"
        "\nControls:\n"