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.