logo
Home
Doc
Doc
Download
Links
Links

Fractals in Higher Dimensions

Contents

INTRODUCTION

bowl-children JavaQuat grew out of a program to generate fractals in the complex plane. I received some email encouraging me to write a program to explore fractals in higher dimensions. I had seen 3D slices of 4-dimensional quaternion fractals, and not being a graphics expert, I set out to write a program that would at least be able to draw 2D slices of the 4-dimensional quaternion space. This page describes that journey to the present.

COMPLEX NUMBERS

"What is a Quaternion?", you may ask. To answer that it helps to understand what complex numbers are. From a simple mathematical point of view, they are pairs of numbers that are treated as if they were a single entity. They have special rules of arithmetic. When you add them, you add them component-wise. That is you use regular single number addition on the first elements of the pairs, and you do the same for the second elements. There is no connection between the first elements and the second elements in addition. Therefore if you had a couple of complex numbers (3, 4.05) being one, and (-2, 7) being the other, the sum would be (1, 11.05).

Complex numbers have their own sort of mulitplication also. That is more complicated. The product of our example above would be (-34.35, 12.9). The way you get that is to multiply the first numbers and get -6, then multiply the second numbers and get 28.35, then subtract the second product from the first and get -34.35. That is the first number of the result. To get the second result number you mulitply the first part of the first complex number by the second part of the second complex number, 3 * 7 = 21. Then you multiply the second part of the first complex number by the first part of the second complex number, 4.05 * -2 = -8.1. You add these together for the second part of the answer, 12.9. (Here I have used "*" to represent multiplication, as is standard in computer languages.)

In general, if you have two complex numbers, (a, b) and (m, n) the rules are

(a, b) + (m, n) = (a+m, b+n)
(a, b) * (m, n) = (a*m - b*n, a*n + b*m)

Often people think and speak of complex numbers as having a real and imaginary part. The real part is the first number of the pair and the imaginary part is the second number of the pair. That is because they think of a complex number as a sum of unlike things: so much regular number plus so much of the square root of -1.

"The square root of -1?", you think. "There isn't any number that can be multiplied by itself to give -1". To that the mathematician answers simply, "True, but suppose there were, and go from there." Call this imaginary square root of -1 by the name "i", for imaginary. Now real, regular numbers and imaginary ones, that is something like 5 of i, are like apples and oragnes, they don't mix. So when you add 3 of the regular number 1 to 5 of i you get 3 and 5 of i, not 8 of something. People write this as 3 + 5*i, or 3 + 5i for short. If you think of (a, b) as a + bi then you might expect that

a + bi + m + ni = a + m + (b+ n)i
and
(a + bi) * (m + ni) = a*m + a*ni + bi*m + bi*ni
Now by bi*ni we mean b*i*n*i or b*n*i*i. But since i*i = -1, this is -b*n. If we group the real and imaginary parts of the product a*m + a*ni + bi*m + bi*ni we get

(a + bi) * (m + ni) = a*m - b*n + (a*n + b*m)i, just as above.

Before we go on to quaternions, let's do one last thing. Let's represent the rules of complex number multiplication as a table. If we let "r" represent 1, that is one real part, and let "i" represent one imaginary part, then complex multiplication can be written

      ____________
   *  ||  r |  i |
  ================
  | r ||  r |  i |
  ________________
  | i ||  i | -r |
  ________________

This table is read as, "real * real is real, real * imaginary is imaginary, imaginary * real is imaginary, and imaginary * imaginary is real with an extra minus sign added to the product.

By way of notation, I should point out that complex numbers are often represented with a single variable. One may find a Z (or some other letter) in a formula about complex numbers. Though there is only one letter, it is understood that it represents the whole complex number, both real part and imaginary part. It's just quicker to write a single symbol if you don't plan to have to think about its real and imaginary components separately.

QUATERNIONS

So, now what are quaternions. They are sets of four numbers, with rules of addition and multiplication. We still add component-wise, first to first, second to second, etc. Mulitplication is complicated. In fact you would have to work a bit, looking at the multiplication formula to see what is going on. Instead of bothering with that, we can represent the multiplication rule with a table as we just did for complex numbers. That's easy to understand, so that's what I always use myself.

In order to make the table easy to write we will give names to the four parts of the general quaternion. Just as the two parts of a complex number were represented in the table above with r and i, we will label the four parts of our quaternion r, i, j, and k.

The table is then

      ______________________
   *  ||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  j |  k |
  __________________________
  | i ||  i | -r |  k | -j |
  __________________________
  | j ||  j | -k | -r |  i |
  __________________________
  | k ||  k |  j | -i | -r | 
  __________________________

Equivalently, if we have two quaternions (a, b, c, d) and (m, n, p, q) and mulitply them together to get some answer which we can represent as (w, x, y, z) we have

w = a * m - b * n - c * p - d * q
x = a * n + b * m + c * q - d * p
y = a * p - b * q + c * m + d * n
z = a * q + b * p - c * n + d * m

It might help to put the (a, b, c, d) down the left hand side of the talbe, the (m, n, p, q) across the top, and the w in the body of the table for r, the x for i, etc. Thus...

      ______________________
   *  ||  m |  n |  p |  q |
  ==========================
  | a ||  w |  x |  y |  z |
  __________________________
  | b ||  x | -w |  z | -y |
  __________________________
  | c ||  y | -z | -w |  x |
  __________________________
  | d ||  z |  y | -x | -w | 
  __________________________

This would then be interpreted as saying, for instance, b * m is part of x, and that c * p is part of -w, or better that -(c * p) is part of w.

As an interesting aside, at least I think so, we have an interesting feature lacking in quaternion multiplication. To appreciate this let's look at some simpler number systems of lower dimensions. Let's get really simple and look at addition of real numbers. You may never have thought about it before but there are four very basic things that we take for granted about addition of real numbers. First there is a special real number that when added to any real number gives that real number as the sum. Of course I'm talking about zero. Second, given any real number there is a number you can add to it to get that special zero. It is the negative of the number: 5 + (-5) = 0. Third addition of three real numbers can be done in any order, either add the first two and then the third, or add the second and third, then the first. Either way you get the same answer, of course. Mathematicians call this the associative rule. And finally, the fourth thing is that 5 + 3 = 3 + 5. That is, which number is on which side doesn't matter. If you're adding real numbers the numbers can swap places without affecting the answer. This is called the commutative rule. Well, you knew all that.

Maybe you didn't realize that the very same set of rules holds true for multiplication. There is a special number that doesn't change things when multiplying, it's one. Each number has an inverse that it can be multiplied by to get you back to one. If your number is 0.25 then multiply by 4. If it's 105 multiply by 1/105. Again we have the associative rule and the commutative rule being true.

There is also a rule or two, depending on how you count, about how addition and multiplication of real numbers relate. And that's all the rules I'm going to mention in case you were worried. This relational rule states that 5 * (2 + 3) = (5 * 2) + (5 * 3). (Here again I've used standard computer notation, using partheses to indicate which part of an expression gets done first. That's standard in math too.) And though it looks silly to consider it separately, to those who haven't seen systems where it isn't true, our real number arithematic also satisfies the rule that (2 + 3) * 5 = (2 * 5) + (3 + 5). These are the distributive rules.

What you may not have realized is that the initial 4 rules are true for addition of complex numbers. They are also true for multiplication of complex numbers. The distributive rules are true too.

"Ah, they are always true!" you are probably thinking at this point. The four rules are true for addition of quaternions, but they are NOT true for multiplication of quaternions. It turns out that (a, b, c, d) * (m, n, p, q) = -(m, n, p, q) * (a, b, c, d). Yes, switching the order gives the negative. "Ah, you could maybe define the multiplication table differently, remove the minus signs or something?" No, as you add dimensions you loose properties in a general sort of way. Actually only the spaces whose dimensionality is a power of two are at all well behaved, that is 1 dimensional space (1 = 20), 2D complex space, 4D quaternion space, 8D space. You can't define a 3D space with all the nice intuitive rules of 1D or 2D or even 4D space. 4D is not as nice as 2D, and things get worse from there, try as you may to make them nice. Well, I thought that was interesting, anyway.

FRACTAL FORMULAS

The Mandelbrot Set

The most famous fractal is, the Mandelbrot set, discovered by Benois Mandelbrot. For a description of the Mandelbrot set and the Julia sets that led to its discovery see "Julia Sets" The Mandelbrot set is defined by the sequence
ZN+1 = ZN2 + Z0
and by the condition that a complex number Z0 is a member of the Mandelbrot set when the magnitude of ZN does not get arbitrarely large as N gets larger.

"What was that?" Well, first understand that we are talking about a sequence of complex numbers. Z0 is what we'll call the first one. "Why?", because computer people like to start numbering things at zero, it makes their programs simpler. Then there is Z1, Z2, and so on. The sequence definition says that an arbitrary element, ZN+1 where N could be any whole real number, is obtained by taking ZN, the complex number just before ZN+1 in the sequence, squaring that, and adding Z0, the first complex number in the sequence.

Coordinates 2 "So what is 'magnitude'"? The magnitude of of a complex number (a, b), or equivalently a + bi is just the square root of (a2 + b2). This may be thought of as if you were using the pair of numbers (a, b) as coordinates on a map. Mathematicians usually think of a as being in the horizontal direction with values increasing from zero in the middle as you go to the right, and b as being vertical with values increasing from zero in the middle as you go up. Then the magnitude is just the distance on the map from (0, 0) to (a, b). This map is called the " Complex Plane".

"'Arbitarily large', what does that mean?" Well, consider that you drew a circle on the complex plane with its center at (0, 0), which is known as "the origin". "Arbitarily large" means you get to pick as big a circle as you want. For the sequence to get arbitarily large means that no matter how big you draw the circle, you can then eventually find a number in the sequence that will be outside that circle. This is also refered to as the sequence "diverging". The definition of the Mandelbrot set is then all the different choices of Z0 that give sequences that don't diverge. It is an interesting, and useful, fact that if the magnitude of one of the numbers in a Mandelbrot sequence gets bigger than 2 then the sequence will diverge. It's somewhat amazing that the complex numbers in the Mandelbrot set form a single shape, and much more so that it is such an interesting, pleasing, and complicated shape.

Other Fractals Formulas

Since 1985, when I started drawing fractals, I've written all sorts of different formulas (formulae, if you prefer). The results are mildly interesting, but much of what you get looks very much like the Mandelbrot set. One sequence definition, however caught my attention with the odd "collisions" it contained, as well as other features.
ZN+1 = ZN3 + 3 * Z0

The Snake I had been interested in higher powers than the squaring in the Mandelbrot set, and had multipled by 3 due to some mistaken thinking about being able to tell when the sequence was diverging. It was a very fortunate mistake, for the multiplication by 3, or any number greater than 1 would have done the trick, added a wealth of variety that using the third power did not. One of the first things I found was "The Snake " staring back at me. The fractal contained a lot of interesting areas. There were so many in fact that my wife and I thought we might make a fractal calendar if we could find a way to print them. This was 1987, and color printers and film recorders were rare.

Polynomial Pitfalls

I tried various polynomial formulas to see what pictures would turn up. There are lots of images similar to what I obtained, all over the internet. I recently ran across someone's fractal with a formula something like
ZN+1 = ZN-2.5 + (ZN5i)-2i + Z0

Dividing by Zero

Formulas can contain all sorts of useless or unpleasant things, and this contains several. One of them is the fact that we'll be dividing by 0, an undefined operation that gives computers heartburn should Z turn out to be 0 (i.e. 0 + 0i). That's because ZN-2.5 means 1/(ZN2.5) and when Z is zero that's 1/0.

Powers of Powers

Another has to do with the second term, (ZN5i)-2i. Let's remember what powers mean by looking at a simple example.

23 is 2 * 2 * 2.

Now if we raise that to a power, say 4, then we get

(23)4 = (2 * 2 * 2) * (2 * 2 * 2) * (2 * 2 * 2) * (2 * 2 * 2)

The parentheses have no effect on the result, so this is really 212. To generalize,

(ab)c = ab * c

Although the powers in the fractal formula above are imaginary and one of them is negative, the same rule applies. Therefore, the formula could have been written more simply and so as to run more quickly on a computer as

ZN+1 = ZN-2.5 + ZN10 + Z0

Fractional Powers and Discontinuities

There is yet another problem with the formula, though this one is more subtle. This has to do with fractional powers. It is most easily understood with the aid of a rather interesting fact. That fact has to do with looking at complex numbers in terms of polar coordinates.

Polar Coordinates

We return to the idea of the complex plane, a portion of which is pictured to the left. We have a complex number (x, y) (i.e. x + yi). Each complex number can be represented as a unique point in the complex plane. Likewise, each point in the complex plane represents some complex number. Rather than specifying where a point is in terms of its horizontal position (i.e. its real part) and its vertical position (i.e. its imaginary part) we use another method. If we draw a line from the origin (i.e. 0 + 0i) to the point we can give the length of the line (also known as the magnitude of the complex number) and what angle the line makes with the positive real axis. Note that the angle is always measured from the positive real axis, the heavy line in the diagram, going in the counter-clockwise (or anti-clockwise) direction. This is a different, but equally reasonable way to identify a point in the plane, and so to identify a complex number. When we refer to the position of the complex number point in the complex plane by the real and imaginary parts, (x, y), we are said to be using "rectangular coordinates". When we instead use the magnitude and angle, (m, a)p, we are said to be using "polar coordinates". Note that when using polar coordinates you will see a "p" so there won't be any confusion.

What is rather interesting is the formula for multiplying complex numbers when you write them in polar coordinates. If (m, a)p and (n, b)p are the polar coordinate representations of two complex numbers then

(m, a)p * (n, b)p = (m * n, a + b)p

When you multiply two complex numbers the result is what you get by multiplying the lengths and adding the angles.

The simplicity of this formula makes it easy to think about what happens when we take powers of complex numbers. For example suppose we have the complex number (1, 1)2. Now (1, 1) has a magnitude of the square root of 2 and an angle of 45 degrees from the positive real axis (the heavy line in the diagram above). Therefore the square has magnitude 2 and angle 90 degrees. Ninety degrees is straight up the imaginary axis, so the result is 2i.

Now if we have a complex number (m, a)p in polar coordinates, taken to some power p, the result is (mp, p * a)p. We have multiplied m together p times and added up angle a p times. Of course I'm assuming that p is an integer, but in fact mathematics is quite consistent and the formula is true if p is a fraction or even another complex number.

Now let's look at the case of a fractional power. A simple one, 1/2, will be sufficient to illustrate the problem that we will encounter with any fractional power. Now what does it mean to take the 1/2 power of something? Let's observe that

(Z2)1/2 = Z2 * 1/2 = Z1 = Z

So the 1/2 power effectively undoes squaring. Taking the square root does that. That's exactly what the 1/2 power means, take the square root. Just as squaring a complex number doubles the polar angle, taking the 1/2 power halves the angle.

Let's consider a complex number Z that is on the positive real axis. In polar coordinates we have an angle of 0 degrees. If we take the 1/2 power of Z the resulting angle is half of 0, which is 0. Now consider a neighboring point Y that is just a very short distance below the positive real axis. The angle is just less than 360 degrees. When we take the 1/2 power, the result has an angle just less than 180 degrees. The disturbing thing is that neighboring points give non-neighboring answers when we take the 1/2 power.

You may not have thought about it, but addition has a very natural-seeming property called continuity. To illustrate consider the situation where we add

2 + 3 = 5

Continuity of addition of real numbers says in effect that we can get a result as close to 5 as desired from numbers other than 2 and 3 so long as we make those numbers sufficiently close to 2 and 3 respectively. Of course I have used 2, 3, and 5 to give a concrete example. (I always say that doing mathematics with concrete puts it on a solid foundation.) In general we would say that you can get an arbitrarely close sum by adding numbers sufficiently close to the original numbers.

In the Mandelbrot sequence

ZN+1 = ZN2 + Z0

we are adding and taking an integer power. You may be able to convince yourself by looking at the polar representation of squaring complex numbers, that that operation is continuous also. So long as the difference in magnitudes is sufficiently small the differences in the squares of the magnitudes can be made as small as we like. So long as the difference in the angles is sufficiently small the difference in double the angles will be as small as we like.

Now lets think about the Mandelbrot sequence for two points, Y0 and Z0

YN+1 = YN2 + Y0

ZN+1 = ZN2 + Z0

We can guarantee that Y1 and Z1 are as close as we like by making Y0 and Z0 sufficiently close.

We can guarantee that Y2 and Z2 are as close as we like if Y1 and Z1 very close, and we can guarantee that by making Y0 and Z0 very close.

We can guarantee that Y3 and Z3 are as close as we like in a similar way, we just have to make Y0 and Z0 sufficiently close. And the same can be said in general for YN+1 and ZN+1.

Now by definition of the Mandelbrot set, and a little additional math, we know that Y0 is not in the Mandelbrot set if the magnitude of YN+1 (for some value of N) ever gets bigger than 2. That is YN+1 is somewhere outside of a circle of radius 2 around the origin (i.e. 0 + 0i in the complex plane). Now let's say that k is the amount that YN+1 is bigger than 2. That is 2 + k is the magintude of YN+1. Imagine a circle drawn around YN+1 where the radius is less than k. That is, this possibly little circle around YN+1 does not overlap our circle of radius 2 around the origin. From the previous paragraph we know that if we are talking about a complex number Z0 that is very, very close to Y0 then ZN+1 will be not be so far away from YN+1 as to put it outside our possibly little circle around YN+1. But then ZN+1 is outside the circle of radius 2 and so its magnitude is bigger than 2, and so Z0 is not a member of the Mandelbrot set either.

The preceeding paragraph says that each point not in the Mandelbrot set is surrounded by points that are not in the Mandelbrot set either. (Those points that are not in the Mandelbrot set are sometimes refered to collectively as the complement of the Mandelbrot set.) What this means is that we will never find a line in the Mandelbrot set complement which has the Mandelbrot set just beyond it.

Discontinuous Fractal No such statement can be made for a Mandelbrot-like sequence using the power 1/2.

ZN+1 = ZN1/2 + Z0

As pointed out above, given the complex number (4, 0)p we get (2, 0)p when we take the half power, but for a point just below it in the complex plane, we get something close to (2, 180)p when we take the half power. That's because the slightly lower point has an angle of almost 360 degrees, taking the 1/2 power cuts the angle to almost 180 degrees. So there is no guarantee that close starting points will wind up generating close sequences of numbers, and in fact they don't. The illustration shows such a situation. Right down the middle runs what is called a discontinuity. To the left of the line we have divergent sequences (i.e. the sequences generated from the above formula eventually contain complex numbers with magnitudes greater than 2). To the right we have non-divergent sequences (and then as we go farther to the right in the picture we get into a different area of divergence unrelated to that on the left).

Such fractals where the "picture" suddenly changes across some striaght or curved line are a hallmark of fractional powers. The longer the sequences go the more such lines creap into the picture. The lines are not always separators of divergent and non-divergent sequences. It is common to see lines through non-divergent areas where one picture abruptly ends and another different picture begins.

Oh yes, I overlooked something. In fact you may be saying to yourself, "Wait a minute. There are two square roots to every real number and I bet the same is true of complex numbers too." You are right. Again thinking in polar coordinates, if complex number (m, a)p has square root (m1/2, a/2)p then it also has square root (m1/2, 180o + a/2)p.

So when we were looking at the square root of (4, 0)p we could have picked (2, 180o)p. That would have been close to the square root of the point just below (4, 0)p. That's true, but consider this. If you never add the 180o you get a discontinuity. If you always add the 180o you get a discontinuity because the square root of (4, 0)p1/2 is (2, 180o)p and that of a point just below it is close to (2, 360o)p. If you decide to switch somewhere between 0o and 360o from not adding in the 180 degrees to adding it, you get a discontinuity there. There is no way to avoid the discontinuities with the half power, nor with any other fractional power.

The original example that I mentioned, somewhere above, used the power 2.5. If you remember as an example that

Z3 * Z4 = (Z * Z * Z) * (Z * Z * Z * Z) = Z7 = Z3 + 4

you will see that Z2.5 = Z2 * Z1/2, and the 1/2 causes discontinuities.

As a matter of personal taste, I don't like discontinuities and I do not draw fractals that have them.

NON-QUATERNION SPACES

So the question in my mind was, "What else can I explore?" I tried quaterions space. It turned out to be rather dull. If you take a look at the r and i axes you have the complex plane. If you look at the r and j axes you have the equivalent of the complex plane. You may notice that the interaction of just r and j in the multiplication table is just like that of r and i, and for that matter r and k.

Quaternion Sq, j-i slice. Quaternion Sq, j-i slice. If you think of the 3D space of the r, i, and j dimensions where k = 0, the fractal you have is what you would get from spinning the Mandelbrot set around the r axis. The same is true for r, i, and k 3D space with j = 0. It is like a table leg cut on a lathe set to follow a Mandelbrot contour. Nice, but not very interesting, for if you look at a 2D slice all you get is circles. Admittedly, you can write some functions that are more interesting than just a simple Mandelbrot-like sequence, but I wanted something different.

The pictures you see above are across the i and j axes, with r = -0.74 and k = 0. To the left we have low magnification and a center of i = j = 0. The picture to the right is a zoom in on a part of the picture on the left.

Rather than try to come up with fancy polynimials I decided to try altering the definition of multiplication. Of course I no longer had quaternions, I had something else. The question was, "What, and would it be interesting and/or pretty?"

Loop428disk Escargot Of course there are lots of ways to alter the multiplication table. Some turn out to be interesting, some have yet to yield an interesting picture. Some have produced pretty pictures and some have not, at least to my eye. JavaQuat, my fractal drawing program, can easily work with 2, 3, and 4 dimensional spaces. As a general rule it seems that multiplication tables that have a pattern produce orderly pictures and those that do not produce pictorial, pardon the expression, chaos.

For the sake of local completeness here, I'll repeat the multiplication talbe for quaternions:


      ______________________
   *  ||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  j |  k |
  __________________________
  | i ||  i | -r |  k | -j |
  __________________________
  | j ||  j | -k | -r |  i |
  __________________________
  | k ||  k |  j | -i | -r | 
  __________________________

Equivalently, if (a, b, c, d) * (m, n, p, q) = (w, x, y, z) we have

w = a * m - b * n - c * p - d * q
x = a * n + b * m + c * q - d * p
y = a * p - b * q + c * m + d * n
z = a * q + b * p - c * n + d * m

Notice the patterns are more apparent in the latter description.

I have also had good pictures in the Java classes Loop 322 and Loop428 which define multiplication as follows.

      _________________             ______________________
  322*||  r |  i |  j |         428*||  r |  i |  j |  k |
  =====================         ==========================
  | r ||  r |  i |  j |         | r ||  r |  i |  j |  k |
  _____________________         __________________________
  | i ||  i | -j |  r |         | i ||  i | -j |  k |  r |
  _____________________         __________________________
  | j ||  j | -r | -i |         | j ||  j | -k | -r |  i |
  _____________________         __________________________
                                | k ||  k | -r | -i | -j |
                                __________________________

The only sequences I've tried are the basic Mandelbrot-like sequences

ZN+1 = ZN2 + C * Z0 + T

where C and T are 4D parameters that can be supplied from the JavaQuat control panel. There is still much left to explore.

There are also various other loop classes in JavaQuat that define other multiplication tables. These are listed below. I will be adding others as time premits, and I'll try to keep this list updated, but I make no promises. Anyone who takes the trouble to download JavaQuat can look at the loop class files themselves. Each one that redefines multiplication has a table in the file as a comment to show what's going on.

Recently (Oct. 1997) JavaQuat has been enhanced to allow Z in the above formula to be constant and for C or T to be varied along two of their four dimensions. With just a little practice this can be a great aid in finding interesting spots in fractals. The sequence really exists in a 12 dimensional space, with 4 dimensions each for Z, C, and T. JavaQuat now allows you to explore all 12 dimensionals.

The person who downloads JavaQuat and knows or learn a small bit of Java or C++ can define his own loop classes, modeled on the ones provided, and explore new worlds of his own. The loop class's loop method gets called once for each pixel. It is passed 12 numbers in 3 sets of 4 and an integer loop maximum. It must return an integer from 0 through the loop maximum. How it gets from the inputs to the outputs is limited only by one's imagination. No recompilation of JavaQuat is required to use new loop classes.


PSEUDO-CODE FOR DRAWING FRACTALS

Some people have sent me email asking for the basic idea of how the fractal images are drawn. I hope the following will help.

void draw-pixel(int horiz, int vert, int color)
{
  "This function draws one pixel and is language dependent."
  
}

int Mandel-loop (Complex z, int loop-max)
{
  "This defines the Mandelbrot Set.  Other formulas can be used to
   give different results.  Number systems other than complex numbers
   can be used with this formula to produce other fractals too.  Those
   number systems redefine the meaning of 'z**2', that is the squaring
   operaton."
  int count = 0;
  Complex original-z = z;
  while (count++ < loop-max AND (z**2) < 4) {
    z = (z**2) + original-z;
  }
  return z;
}


void scan (Complex center, float range, int square-size)
  // This draws a square section of the mandelbrot set.
  // Center is the center of the picture in the complex plane.
  // range is the size of the picture in the complex plane
{
  int loop-max = 500;
  int number-of-colors = 256;
  double left = center.real - (range / 2);
  double top = center.img - (range / 2);
  double inter-pixel-spacing = range / (square-size - 1);
  for(int pix-h = 0; pix-h < square-size; pix-h++) {
    for(int pix-v = 0; pix-v < square-size; pix-v++) {
      Complex z = new Complex(left + pix-h * inter-pixel-spacing,
                              top + pix-v * inter-pixel-spacing);
      int count = Mandel-loop(z, loop-max);
      int color = (int)(count * number-of-colors / (float)loop-max);
      draw-pixel(pix-h, pix-v, color);
    }
  }
}


MULTIPLICATION TABLES OF EXISTING JAVAQUAT LOOP CLASSES

  _____________________
  321*||  r |  i |  j |
  =====================
  | r ||  r |  i |  j |
  _____________________
  | i ||  i | -j | -r |
  _____________________
  | j ||  j | -r | -i |
  _____________________
  _____________________
  322*||  r |  i |  j |
  =====================
  | r ||  r |  i |  j |
  _____________________
  | i ||  i | -j |  r |
  _____________________
  | j ||  j | -r | -i |
  _____________________
  _____________________
  323*||  r |  i |  j |
  =====================
  | r || -j |  i |  j |
  _____________________
  | i ||  i | -r |  r |
  _____________________
  | j ||  j |  r | -i |
  _____________________
  _____________________
  324*||  r |  i |  j |
  =====================
  | r ||  r |  i |  j |
  _____________________
  | i ||  i |  j |  r |
  _____________________
  | j ||  j | -r | -i |
  _____________________
 322k*||   r  |   i  |   j  |
  ===========================
  | r ||   r  | Ki/2 | Kj/2 |
  ___________________________
  | i || Ki/2 |  -j  |   r  |
  ___________________________
  | j || Kj/2 |  -r  |  -i  |
  ___________________________
 where K is a constant entered
 as 2 + Center.k.  Center.k is
 a JavaQuat parameter.
  __________________________
  421*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  k | -i |
  __________________________
  | i ||  i | -r | -j |  r |
  __________________________
  | j ||  k | -i | -k |  j |
  __________________________
  | k || -j |  r |  j |  k | 
  __________________________
  __________________________
  422*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  j | -i |
  __________________________
  | i ||  i | -r | -k |  r |
  __________________________
  | j ||  j | -k | -j |  k |
  __________________________
  | k || -i |  r |  k |  j | 
  __________________________
  __________________________
  424*||  r |  i |  j |  k |
  ==========================
  | r || -r |  i |  j |  k |
  __________________________
  | i ||  i |  r | -k |  j |
  __________________________
  | j ||  k | -j |  i | -r |
  __________________________
  | k ||  j |  k | -r | -i | 
  __________________________
  __________________________
  425*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i | -j |  k |
  __________________________
  | i ||  i | -r |  r | -i |
  __________________________
  | j || -j |  k | -k |  j |
  __________________________
  | k ||  r | -i |  j |  k | 
  __________________________
  __________________________
  426*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  j |  k |
  __________________________
  | i ||  i | -r | -k |  j |
  __________________________
  | j ||  k | -j |  i | -r |
  __________________________
  | k ||  j |  k | -r | -i | 
  __________________________
  __________________________
  427*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  0 |  j |
  __________________________
  | i ||  i | -r | -i |  0 |
  __________________________
  | j ||  0 |  r |  j |  k |
  __________________________
  | k || -k |  0 |  k | -j | 
  __________________________
  __________________________
  428*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  j |  k |
  __________________________
  | i ||  i | -j |  k |  r |
  __________________________
  | j ||  j | -k | -r |  i |
  __________________________
  | k ||  k | -r | -i | -j | 
  __________________________
  Alias Tetra (i.e. LoopTetra)
  
  __________________________
  429*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i | -j |  k |
  __________________________
  | i ||  i |  j |  k |  r |
  __________________________
  | j || -j | -k | -r |  i |
  __________________________
  | k ||  k | -r | -i |  j | 
  __________________________
  Alias TetraN (i.e. LoopTetraN)
  __________________________
  42A*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i | -j |  k |
  __________________________
  | i ||  i |  j |  k |  r |
  __________________________
  | j || -j | -k |  r |  i |
  __________________________
  | k ||  k | -r | -i |  j | 
  __________________________
  Alias TetraRN (i.e. LoopTetraRN)
  __________________________
  42B*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  j |  k |
  __________________________
  | i ||  i | -j |  k |  r |
  __________________________
  | j ||  j | -k |  r |  i |
  __________________________
  | k ||  k | -r | -i | -j | 
  __________________________
  Alias TetraR (i.e. LoopTetraR)
  __________________________
  42C*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  0 |  j |
  __________________________
  | i ||  i | -j | -r |  0 |
  __________________________
  | j ||  0 |  r |  j |  k |
  __________________________
  | k ||  j |  0 |  k | -r | 
  __________________________
  __________________________
  HCx*||  r |  i |  j |  k |
  ==========================
  | r ||  r |  i |  j |  k |
  __________________________
  | i ||  i | -r |  k | -j |
  __________________________
  | j ||  j |  k | -r | -i |
  __________________________
  | k ||  k | -j | -i |  r | 
  __________________________
  This is commonly known as
  HyperComplex space.
   __________________________
TetraP*||  r |  i |  j |  k |
   ==========================
   | r ||  r |  i |  j |  k |
   __________________________
   | i ||  i |  j |  k |  r |
   __________________________
   | j ||  j | -k | -r |  i |
   __________________________
   | k ||  k | -r | -i | -j | 
   __________________________
     __________________________
 TetraRP*||  r |  i |  j |  k |
     ==========================
     | r ||  r |  i |  j |  k |
     __________________________
     | i ||  i |  j |  k |  r |
     __________________________
     | j ||  j | -k |  r |  i |
     __________________________
     | k ||  k | -r | -i | -j | 
     __________________________
     __________________________
TetraHCi*||  r |  i |  j |  k |
     ==========================
     | r ||  r |  i |  j |  k |
     __________________________
     | i ||  i | -j |  k |  r |
     __________________________
     | j ||  j | -k | -r | -i |
     __________________________
     | k ||  k | -r | -i | -j | 
     __________________________
       __________________________
TetraPiHCi*||  r |  i |  j |  k |
       ==========================
       | r ||  r |  i |  j |  k |
       __________________________
       | i ||  i |  j |  k |  r |
       __________________________
       | j ||  j | -k | -r | -i |
       __________________________
       | k ||  k | -r | -i | -j | 
       __________________________
       __________________________
TetraPkHCi*||  r |  i |  j |  k |
       ==========================
       | r ||  r |  i |  j |  k |
       __________________________
       | i ||  i | -j |  k |  r |
       __________________________
       | j ||  j | -k | -r | -i |
       __________________________
       | k ||  k | -r | -i |  j | 
       __________________________

To top