From 0d847838c533c4ba96ced4fec7d7b12697de9685 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Sun, 17 Jul 2016 12:07:26 +0200 Subject: Import bcollide from jwildfire --- flam3.c | 8 ++++++++ flam3.h | 9 +++++++-- genome.c | 5 +++++ interpolation.c | 2 ++ parser.c | 4 ++++ variations.c | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 59 insertions(+), 2 deletions(-) diff --git a/flam3.c b/flam3.c index 9bb8130..950fa82 100644 --- a/flam3.c +++ b/flam3.c @@ -486,6 +486,9 @@ void flam3_copy_params(flam3_xform * restrict dest, flam3_xform * restrict src, dest->mobius_im_d = src->mobius_im_d; } else if (varn==VAR_ASTERIA) { dest->asteria_alpha = src->asteria_alpha; + } else if (varn==VAR_BCOLLIDE) { + dest->bcollide_num = src->bcollide_num; + dest->bcollide_a = src->bcollide_a; } } @@ -1251,6 +1254,11 @@ static void flam3_print_xform(FILE *f, flam3_xform *x, int final_flag, fprintf(f, "separation_yinside=\"%g\" ", x->separation_yinside); break; + case VAR_BCOLLIDE: + fprintf(f, "bcollide_num=\"%g\" ", x->bcollide_num); + fprintf(f, "bcollide_a=\"%g\" ", x->bcollide_a); + break; + default: /* pass */ break; diff --git a/flam3.h b/flam3.h index 8415974..b26c57a 100644 --- a/flam3.h +++ b/flam3.h @@ -30,8 +30,6 @@ extern char *flam3_variation_names[]; -#define flam3_nvariations 100 - #define flam3_interpolation_linear 0 #define flam3_interpolation_smooth 1 @@ -145,6 +143,8 @@ typedef enum { #define VAR_FLUX 97 #define VAR_MOBIUS 98 #define VAR_ASTERIA 99 +#define VAR_BCOLLIDE 100 +#define flam3_nvariations 101 #include "vector.h" #include "random.h" @@ -372,6 +372,11 @@ typedef struct xform { /* precalc */ double asteria_sina, asteria_cosa; + /* bcollide */ + double bcollide_num, bcollide_a; + /* precalc */ + double bcollide_bCa, bcollide_bCn_pi, bcollide_bCa_bCn, bcollide_pi_bCn; + int num_active_vars; double active_var_weights[flam3_nvariations]; int varFunc[flam3_nvariations]; diff --git a/genome.c b/genome.c index 1a063af..8221749 100644 --- a/genome.c +++ b/genome.c @@ -257,6 +257,11 @@ static void random_xform_param (flam3_xform * const xform, const unsigned int i, case VAR_ASTERIA: xform->asteria_alpha = rand_d01(rc); break; + + case VAR_BCOLLIDE: + xform->bcollide_num = rand_d01(rc)*(1<<16); + xform->bcollide_a = rand_d01(rc); + break; } } diff --git a/interpolation.c b/interpolation.c index 4eae663..f665160 100644 --- a/interpolation.c +++ b/interpolation.c @@ -473,6 +473,8 @@ void flam3_interpolate_n(flam3_genome *result, int ncp, INTERP(xform[i].mobius_re_d); INTERP(xform[i].mobius_im_d); INTERP(xform[i].asteria_alpha); + INTERP(xform[i].bcollide_num); + INTERP(xform[i].bcollide_a); for (j = 0; j < flam3_nvariations; j++) INTERP(xform[i].var[j]); diff --git a/parser.c b/parser.c index d99dfe8..ca74577 100644 --- a/parser.c +++ b/parser.c @@ -1087,6 +1087,10 @@ static int parse_xform_xml(xmlNode *chld_node,flam3_xform *this_xform, int *num_ 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 if (!xmlStrcmp(cur_att->name, (const xmlChar *)"bcollide_num")) { + this_xform->bcollide_num = flam3_atof(att_str); + } else if (!xmlStrcmp(cur_att->name, (const xmlChar *)"bcollide_a")) { + this_xform->bcollide_a = 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 caf661b..00d49b7 100644 --- a/variations.c +++ b/variations.c @@ -130,6 +130,7 @@ char *flam3_variation_names[1+flam3_nvariations] = { "flux", "mobius", "asteria", + "bcollide", 0 }; @@ -1860,6 +1861,28 @@ static double2 var99_asteria (const double2 in, const flam3_iter_helper * const } } +static double2 var100_bcollide (const double2 in, const flam3_iter_helper * const f, double weight) { + /* from jwildfire: bCollide by Michael Faber, + * http://michaelfaber.deviantart.com/art/bSeries-320574477 */ + const flam3_xform *xf = f->xform; + + const double tau = 0.5 * (log(square (in[0] + 1.0) + square (in[1])) - log(square (in[0] - 1.0) + square (in[1]))); + double sigma = M_PI - atan2(in[1], in[0] + 1.0) - atan2(in[1], 1.0 - in[0]); + + const int alt = (int) (sigma * xf->bcollide_bCn_pi); + if (alt % 2 == 0) { + sigma = alt * xf->bcollide_pi_bCn + fmod(sigma + xf->bcollide_bCa_bCn, xf->bcollide_pi_bCn); + } else { + sigma = alt * xf->bcollide_pi_bCn + fmod(sigma - xf->bcollide_bCa_bCn, xf->bcollide_pi_bCn); + } + const double sinht = sinh(tau); + const double cosht = cosh(tau); + double sins, coss; + sincos (sigma, &sins, &coss); + const double temp = cosht - coss; + return (double2) { weight * sinht / temp, weight * sins / temp }; +} + /* Precalc functions */ static void perspective_precalc(flam3_xform *xf) { @@ -1927,6 +1950,13 @@ static void asteria_precalc (flam3_xform * const xf) { xf->asteria_cosa = cos (M_PI * xf->asteria_alpha); } +static void bcollide_precalc (flam3_xform * const xf) { + xf->bcollide_bCn_pi = xf->bcollide_num * M_1_PI; + xf->bcollide_pi_bCn = M_PI / xf->bcollide_num; + xf->bcollide_bCa = M_PI * xf->bcollide_a; + xf->bcollide_bCa_bCn = xf->bcollide_bCa / xf->bcollide_num; +} + /* Precalculate constants (i.e. not depending on position) for variations */ void xform_precalc (flam3_xform * const xform) { @@ -1939,6 +1969,7 @@ void xform_precalc (flam3_xform * const xform) { supershape_precalc(xform); wedgeJulia_precalc(xform); asteria_precalc (xform); + bcollide_precalc (xform); } static double adjust_percentage(double in) { @@ -2302,6 +2333,8 @@ int apply_xform(const flam3_xform * const xf, const double4 p, double4 *q_ret, accum += var98_mobius(t, &f, weight); break; case VAR_ASTERIA: accum += var99_asteria (t, &f, weight); break; + case VAR_BCOLLIDE: + accum += var100_bcollide (t, &f, weight); break; } } -- cgit v1.2.3