diff options
-rw-r--r-- | flam3.c | 6 | ||||
-rw-r--r-- | flam3.h | 8 | ||||
-rw-r--r-- | genome.c | 4 | ||||
-rw-r--r-- | interpolation.c | 1 | ||||
-rw-r--r-- | math.h | 12 | ||||
-rw-r--r-- | parser.c | 2 | ||||
-rw-r--r-- | variations.c | 40 |
7 files changed, 71 insertions, 2 deletions
@@ -484,6 +484,8 @@ void flam3_copy_params(flam3_xform * restrict dest, flam3_xform * restrict src, dest->mobius_im_b = src->mobius_im_b; dest->mobius_im_c = src->mobius_im_c; dest->mobius_im_d = src->mobius_im_d; + } else if (varn==VAR_ASTERIA) { + dest->asteria_alpha = src->asteria_alpha; } } @@ -1238,6 +1240,10 @@ static void flam3_print_xform(FILE *f, flam3_xform *x, int final_flag, fprintf(f, "mobius_im_d=\"%g\" ", x->mobius_im_d); break; + case VAR_ASTERIA: + fprintf(f, "asteria_alpha=\"%g\" ", x->asteria_alpha); + break; + case VAR_SEPARATION: fprintf(f, "separation_x=\"%g\" ", x->separation_x); fprintf(f, "separation_y=\"%g\" ", x->separation_y); @@ -30,7 +30,7 @@ extern char *flam3_variation_names[]; -#define flam3_nvariations 99 +#define flam3_nvariations 100 #define flam3_interpolation_linear 0 #define flam3_interpolation_smooth 1 @@ -144,6 +144,7 @@ typedef enum { #define VAR_AUGER 96 #define VAR_FLUX 97 #define VAR_MOBIUS 98 +#define VAR_ASTERIA 99 #include "vector.h" #include "random.h" @@ -366,6 +367,11 @@ typedef struct xform { double super_shape_pm_4; double super_shape_pneg1_n1; + /* asteria */ + double asteria_alpha; + /* precalc */ + double asteria_sina, asteria_cosa; + int num_active_vars; double active_var_weights[flam3_nvariations]; int varFunc[flam3_nvariations]; @@ -253,6 +253,10 @@ static void random_xform_param (flam3_xform * const xform, const unsigned int i, xform->mobius_re_d = rand_d11(rc); xform->mobius_im_d = rand_d11(rc); break; + + case VAR_ASTERIA: + xform->asteria_alpha = rand_d01(rc); + break; } } diff --git a/interpolation.c b/interpolation.c index 5fa1e07..4eae663 100644 --- a/interpolation.c +++ b/interpolation.c @@ -472,6 +472,7 @@ void flam3_interpolate_n(flam3_genome *result, int ncp, INTERP(xform[i].mobius_im_c); INTERP(xform[i].mobius_re_d); INTERP(xform[i].mobius_im_d); + INTERP(xform[i].asteria_alpha); for (j = 0; j < flam3_nvariations; j++) INTERP(xform[i].var[j]); @@ -109,6 +109,18 @@ inline double sum(const double2 in) { return in[0] + in[1]; } +inline double square (const double in) { + return in * in; +} + +inline double2 square_d2 (const double2 in) { + return in * in; +} + +inline double squaresum (const double2 in) { + return sum (square_d2 (in)); +} + inline void normalize (double * const a, const size_t n) { double sum = 0.0; for (unsigned int j = 0; j < n; j++) { @@ -1085,6 +1085,8 @@ static int parse_xform_xml(xmlNode *chld_node,flam3_xform *this_xform, int *num_ this_xform->mobius_im_c = flam3_atof(att_str); } else if (!xmlStrcmp(cur_att->name, (const xmlChar *)"Im_D") || !xmlStrcmp(cur_att->name, (const xmlChar *)"mobius_im_d")) { this_xform->mobius_im_d = flam3_atof(att_str); + } else if (!xmlStrcmp(cur_att->name, (const xmlChar *)"asteria_alpha")) { + this_xform->asteria_alpha = flam3_atof(att_str); } else { int v = var2n((char *) cur_att->name); if (v != flam3_variation_none) diff --git a/variations.c b/variations.c index f42c623..caf661b 100644 --- a/variations.c +++ b/variations.c @@ -129,6 +129,7 @@ char *flam3_variation_names[1+flam3_nvariations] = { "auger", "flux", "mobius", + "asteria", 0 }; @@ -1829,6 +1830,35 @@ static double2 var98_mobius (const double2 in, const flam3_iter_helper * const f return rad_v * (double2) { (re_u*re_v + im_u*im_v), (im_u*re_v - re_u*im_v) }; } +static double2 var99_asteria (const double2 in, const flam3_iter_helper * const f, double weight) { + /* from jwildfire: asteria by dark-beam, + * http://jwildfire.org/forum/viewtopic.php?f=23&t=1464 */ + const double2 w = weight * in; + double r = squaresum (in); + double xx = square (fabs(in[0]) - 1.); + double yy = square (fabs(in[1]) - 1.); + const double r2 = sqrt(yy + xx); + bool in1 = r < 1.; + const bool out2 = r2 < 1.; + if (in1 && out2) { + in1 = rand_d01 (f->rc) > 0.35; + } else { + in1 = !in1; + } + + if (in1) { + return var0_linear (in, f, weight); + } else { + const double sina = f->xform->asteria_sina; + const double cosa = f->xform->asteria_cosa; + xx = w[0] * cosa - w[1] * sina; + yy = w[0] * sina + w[1] * cosa; + const double nx = xx / sqrt(1. - yy * yy) * (1. - sqrt(1. - square(-fabs(yy) + 1.))); + xx = nx * cosa + yy * sina; + yy = -nx * sina + yy * cosa; + return (double2) { xx, yy }; + } +} /* Precalc functions */ @@ -1892,6 +1922,11 @@ static void supershape_precalc(flam3_xform *xf) { xf->super_shape_pneg1_n1 = -1.0 / xf->super_shape_n1; } +static void asteria_precalc (flam3_xform * const xf) { + xf->asteria_sina = sin (M_PI * xf->asteria_alpha); + xf->asteria_cosa = cos (M_PI * xf->asteria_alpha); +} + /* Precalculate constants (i.e. not depending on position) for variations */ void xform_precalc (flam3_xform * const xform) { @@ -1903,6 +1938,7 @@ void xform_precalc (flam3_xform * const xform) { disc2_precalc(xform); supershape_precalc(xform); wedgeJulia_precalc(xform); + asteria_precalc (xform); } static double adjust_percentage(double in) { @@ -2013,7 +2049,7 @@ int prepare_precalc_flags(flam3_genome *cp) { xf->precalc_atan_yx_flag=1; } else if (j==VAR_LOG) { xf->precalc_atan_yx_flag=1; - } + } totnum++; } @@ -2264,6 +2300,8 @@ int apply_xform(const flam3_xform * const xf, const double4 p, double4 *q_ret, accum += var97_flux(t, &f, weight); break; case (VAR_MOBIUS): accum += var98_mobius(t, &f, weight); break; + case VAR_ASTERIA: + accum += var99_asteria (t, &f, weight); break; } } |