Menu

General

Foaly

This page provides a bit of information about escape-time fractals (like the Mandelbrot) - at least how I perceive them - and how they are rendered as orbit fractals.
For general information about the Buddhabrot fractal, see also: https://en.wikipedia.org/wiki/Buddhabrot
A basic understanding about complex numbers (https://en.wikipedia.org/wiki/Complex_number) is also useful. (They are basically numbers made from two components.)

Escape time fractal
An escape time fractal is defined by a function fn(C).
This formula is usually defined in a recursive way, e. g. the Mandelbrot formula is
f0(C) = 0
fn+1(C) = fn(C)2 + C
One orbit is defined by a C (in the range from -2-2i to +2+2i) and consists of many points (f1(C), f2(C), f3(C),...)
When the magnitude of a fn(C) becomes greater than 2, it is said to have bailed out. (This is called the bailout test.)
Some orbits bail out, some do never.
If a orbit bails out, the number of iterations it takes before bailing out is called the orbit length.

Usually, these escape fractals are rendered in the following way:
1. The C is set to the pixel coordinate.
2. fn(C) is computed iteratively for an increasing n, until it bails out or n > the maximum number of iterations
3. The pixel is colored according to the highest n computed for that pixel.

Instead, when rendering the Buddhabrot (or other fractals using this method), we draw the full orbits:
1. A random C is chosen.
2. The orbit for that C is computed.
3. If the orbit bails out, every fn(C) is drawn as a point in the image.

Also, formulas are often written using Z instead of f(C).

Writing formulas for Buddhabrot Max / Mag
(For all available functions and constants, see FormulaHelp.txt in the Formulas folder.)
Also see the .max files for example formulas.

So a formula is defined by three thing:
1. It's initilization (e. g. Z0 = 0 for the Mandelbrot)
2. The iteration (e. g. Zn+1 = Zn2 + C for the Mandelbrot)
3. The bailout test (e. g. |Zn| > 2 for the Mandelbrot)

The formula would translate like this to the simple formula language:

_INIT_

_LOOP_
Z[n+1] = Z[n]^2 + C;

_BAIL_
absSq(Z[n+1]) > 4;

Every statement is finished with a ";".

The INIT block contains the initialization. There's nothing here, because Zn is implicitly initilized to 0.

LOOP contains the iteration. There are three Zs that you can use:
Z[n+1]: The Z computed in this iteration. It's the only one that can be assigned.
Z[n]: The previous Z.
Z[0]: Cannot be assigned, is always 0 or the perturbation.

BAIL contains the bailout condition.
absSq(x) computes the squared magnitude of x, which is faster than the regular magnitude (abs(x)).
It is compared to 4, because that's the square of 2.


Another example: The Manowar Formula
It is given by Zn+1 = Zn2 + Zn-1 + C
However it is not possible to access arbitrary Zi, so we have to use a separate variable to store Zn-1.

_INIT_
complex z1;
z1 = Z[0];

 _LOOP_ 
Z[n+1] = Z[n]^2 + z1 + C;
z1 = Z[n];

_BAIL_
absSq(Z[n+1]) > 4;

Here, we declare a new variable called z1 in the INIT block. Then we assign it to be the same value as Z0.
You always have to declare all variables before using any of them.

In LOOP, we can then use this variable. We first read from it, then we store the Zn in it, so it will contain Zn-1 in the next iteration.


So, writing formulas is actually pretty straightforward, it's pretty much experimentation and seeing what looks nice.