# Stripe Colouring
# 1 Definition
Stripe average colouring involves accumulating \(\sin(s \arg Z)\) during iteration of escape time fractals like the Mandelbrot set and Burning Ship.
It turns out that generally all the interesting appearance comes from the last few iterations.
# 2 Example
# 3 Modification
I found that it’s possible to skip accumulating during iteration and just apply a slightly different algorithm after the point has escaped. This works for a subset of escape time formulas, that escape to infinity like monomial power:
-
at escape, keep the integer iteration count and calculate the fractional iteration count in the normal way;
-
normalize Z to magnitude 1, or provide data like final angle that allows this to be reconstructed.
-
run modified stripe average algorithm for a few iterations (e.g. 5 or so): do the formula without adding C
-
fade the first and last items summed using the fractional iteration count
This basically assumes that if Z escaped, then adding C does almost nothing, and to avoid huge values that might overflow, the Z value is kept normalized to 1, which has the small added benefit that \(\sin(\arg(z)) = \Im(Z)\), which can save some mathops if the stripe density is 1, as in the implementation below.
# 4 Implementation
# 4.1 Fraktaler 3 GLSL
For Fraktaler 3 version 3 unreleased WIP.
Switch statement body must match formula definition, currently set up for M-BS-M-M. Adjustments are needed for non-power-2 formulas.
const float pi = 3.141592653;
const int phases = 4; // number of parts of formula
const int stripes = 5; // octaves of effect
float getStripe(void)
{
float f = getNF(); // NF fractional part of smooth iteration count
float t = getT() * 2.0 * pi; // T is arg at escape in turns
int phase = int(getN0()) % phases; // N0 is integer part of smooth iteration count
vec2 z = vec2(cos(t), sin(t)); // ignore +c as after escape |z|>>|c|
float w = 1.0 - f; // fade between iteration bands
float g = 0.0; // accumulated gradient
for (int stripe = 0; stripe < stripes; ++stripe)
{
g += w * z.y;
w = 1.0;
switch ((phase + stripe) % phases)
{
case 1: // burning ship part
z = vec2(abs(z.x), -abs(z.y));
break;
default: // mandelbrot part
break;
}
// complex squaring
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y);
}
w = f;
g += w * z.y;
g /= float(stripes);
// now use g in [-1,1] as index for whichever colouring algorithm
return g;
}
# 5 References
- “On Smooth Fractal Coloring Techniques”, Jussi Härkönen, Master’s Thesis, Department of Mathematics, Åbo Akademi University, 2007. archived hi-res PDF (76MB) archived lo-res PDF (13MB)