## About the maths

### Warning: Dubious mathematics ahead

I'm not a mathematician. You may find this discussion insultingly oversimplified or just plain wrong.

### The Mandelbrot Set

The Mandelbrot may be
defined as the set of all complex numbers which, when you
repeatedly square them and add them again, never become infinite. (The
official definition of the set is somewhat different: it is the set of
points in the complex plane whose corresponding Julia sets are
connected. These end up being the same thing.)
We can tell that a number will eventually reach infinity if it ever
gets outside a circle of radius 2 around the origin. Unfortunately, we
can't tell in general that a point will *never*
become infinite, so we have to estimate by trying a large number of
times before giving up.

In Gnofract 4D, the formula is:

Mandelbrot1 { init: z = 0 loop: z = z^2 + c bailout: |z| < 4.0 }

(|z| means the square of the magnitude of z). We calculate the loop function repeatedly until the bailout condition is false or we've performed the maximum number of iterations. At that point, if we "bailed out", we know we're outside the set: otherwise we're (probably) inside.

We do this repeatedly for each position on the screen, setting
*c* to a different value for each point. This gives
rise to the familiar Mandelbrot set:

All the points inside the set are (as is traditional) coloured black. The points outside the set are different colours depending on how long it takes them to escape from the set. These colours aren't very mathematically significant, but they look nice.

So what happens if *z* is initially set to a
complex value other than zero? (Strictly speaking, you shouldn't do
this. Zero is important because it is the *critical
value* of z^2+c - other values are not mathematically
meaningful. However, as with most fractal programs, Gnofract 4D allows you
to draw anything which looks interesting, regardless of its
mathematical purity.)
Well, you get a rather odd-looking, deformed M-set. This initial
value, which we'll call *z0*, is called the intial
perturbation, and sets which have a non-zero *z0*
are known as *perturbed* sets:

### The Julia Set

The Julia set is actually drawn by the same procedure as the
Mandelbrot set. But instead of changing the value of
*c* for each pixel, we keep *c*
constant and change *z0*. There is a different
Julia set for each value of *c*; here's the one for
*c*=0.

Boring, isn't it? That's because we're just squaring the value at each
iteration without adding anything to it. So any value which starts
with a magnitude less than 1 will shrink forever (and hence is a
member of the set). All other values will grow forever, and so we've
just discovered a rather inefficient way of drawing perfect circles.
If we use a different value of *c* we get something more
interesting:

### The Julibrot

Here we come to the heart of the matter. I said above that both the
Julia and Mandelbrot sets are drawn with the *same
function*.

julibrot(z0,c) { init: z = z0 loop: z = z^2 + c bailout: |z| < 4.0 }

The Julibrot function has two complex parameters, or four real
ones. In Gnofract 4D I refer to the real parameters as x, y, z, and w:
these are c.re , c.im, z0.re and z0.im respectively.
The only difference is which points we choose to draw. To draw the
Mandelbrot set, we keep *z0* constant and change
*c* with each pixel. To draw the Julia set, we keep
*c* constant and change *z0*. If
you squint with your brain a bit, you can imagine both sets as
orthogonal "slices" through the same four-dimensional object. In
Gnofract 4D terms, the Mandelbrot set is the *xy*
plane, and the Julia set is the *zw* plane. We can
also look at other planes: here's an image of the
*xw* plane:

### Viewing in Four Dimensions

However, we can draw any 2D slice we like, not just those which are
parallel to the Julibrot axes. To do this we'll need to describe our
scene by four things. First, the (*x,y,z,w*)
coordinates of the center of the screen. Second, a vector for the
x-axis of the screen. This tells us how to change the parameters to
the Julibrot function as we proceed across the screen. Third, a vector
for the y-axis. Fourth and finally, the size of the image. For the
Mandelbrot set, our "default" view, the screen is centered at
[0,0,0,0], the x-vector is [1,0,0,0] and the y-vector is
[0,1,0,0]. The initial size is 4, because the whole Mandelbrot set
fits inside the 2x2 square. We can zoom into the set by changing
*x* and *y* and the zoom factor.

If we want to draw other slices, we need to rotate our view through
four dimensions. In 3D, we can rotate in 3 directions: around the
*x*, *y*, and
*z* axes. In 4D, we rotate around a *
plane * rather than a line, and we can rotate in 6
directions: around the *xy, xz, xw, yz, yw* and
*zw* planes. For example, if we rotate through 90
degrees in the xz and yw directions, our screen vectors become
[0,0,1,0] and [0,0,0,1]: in other words, the Julia set. If we rotate
only part of the way, we get a "hybrid" between the two sets, which
looks decidedly odd:

In fact, we can rotate to any angle in each of the planes, creating a whole world of bizarre pictures.

### Hypercomplex Fractals and Quaternions

There are other kinds of fractal which are commonly described as "four-dimensional" - hypercomplex and quaternion-based fractals. Hypercomplex numbers have four components (one real and three imaginary) where complex numbers have two. Since the hypercomplex mandelbrot has two hypercomplex parameters, in Gnofract 4D terms it's actually an eight-dimensional object. Gnofract 4D allows you to set four of these as part of the view - the other four have to be set via parameters. Gnofract 4D doesn't support quaternions at present.