summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flam3.c8
-rw-r--r--flam3.h9
-rw-r--r--genome.c5
-rw-r--r--interpolation.c2
-rw-r--r--parser.c4
-rw-r--r--variations.c33
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;
}
}