Quaternion manipulation in the 1456 object code system.

William Overington

Copyright 2000 William Overington

Quaternions are an interesting part of mathematics that can be applied in the computation of rotations of three dimensional graphics. Accordingly, quaternion manipulation facilities are now included in the 1456 object code system. Here is a link to the Engine1456.class file. The version of the 1456 engine added to add quaternions into the system is added on 7 December 2000. As only one version of Engine1456.class in stored in the webspace, the links in previous documents are automatically updated to the latest version of the file.

In implementing the manipulation of quaternions in the 1456 object code system I have added a number of commands to the 1456 object code specification. Each of these commands is expressed using two characters, the first character of the pair being either a Q character or a u character. It would have been convenient to use Q and q, yet q is already in use for obtaining the square root of a double and I do not wish to change the already published specification, as I feel that it is important that readers may rely upon published commands not being changed. The use of Q and u is, however, hopefully not too inconvenient.

It is convenient to think of the processing of quaternions within the 1456 engine as if they are being carried out within a large translucently paneled volume, such as those found in the new large botanical gardens. With complex numbers the notion of a complex number courtyard was introduced. Yet quaternions are four dimensional and are applied in the 1456 system to manipulate three dimensional graphics, so a volume is imagined. My reason for introducing this concept of such a volume is that I feel that the mind can handle a certain amount of complexity. For me, the use of analogies of this kind reduces the amount of complexity involved in understanding the basics of the system and so the amount of complexity handling capability left over may be used to understand more advanced aspects, rather than using it all up on understanding the basics. So, I think in terms of objects floating in the air within such a botanical dome. Commands beginning with Q involve moving data in and out of the dome and commands beginning with u involve manipulating quaternions within the dome.

The quaternion dome interfaces with the rest of the 1456 engine using the ad1456 and bd1456 registers. The bi1456 register is also used to provide addressing data for u> and u< commands. Please note that although bi1456 is not within the quaternion dome a u character is used for u> and u< because the data being manipulated is a quaternion.

The 1456 engine is regarded as having aq1456 and bq1456 registers and mq1456 storage from mq1456[0] to mq1456[99] inclusive. In fact, in the underlying Java coding four doubles are used for each quaternion. As far as possible it is nice, mathematically elegant, to think of aq1456, bq1456 and mq1456 as being quaternions. However, in order to get data in and out of the dome, one needs to think of aq1456 and bq1456 as being composed of eight doubles, namely aqr1456, aqi1456, aqj1456, aqk1456, bqr1456, bqi1456, bqj1456 and bqk1456, where the r, i, j and k in the register names represent the one real and three imaginary parts respectively. Let us begin by looking at those Q commands used in copying data into the quaternion registers. Each of QP, QU, QV, QW, QQ, QX, QY, QZ, Qp, Qu, Qv, Qw, Qq, Qx, Qy, Qz copy one double into part of a quaternion register. These commands are summarized in the table below. Please note that, for these sixteen instructions, those eight with the second letter being a capital letter take the data from ad1456, whereas those eight with the second letter being a lowercase letter take the data from bd1456. Regarding the letters, P, Q; U, X; V, Y; W, Z as being pairs, those commands having as its second letter the earlier letter within a pair have a register within aq1456 as the destination, whereas those commands having as its second letter the later letter within a pair have a register within bq1456 as the destination.

QP | aqr1456 takes the value in ad1456 |

QU | aqi1456 takes the value in ad1456 |

QV | aqj1456 takes the value in ad1456 |

QW | aqk1456 takes the value in ad1456 |

bqr1456 takes the value in ad1456 | |

QX | bqi1456 takes the value in ad1456 |

QY | bqj1456 takes the value in ad1456 |

QZ | bqk1456 takes the value in ad1456 |

Qp | aqr1456 takes the value in bd1456 |

Qu | aqi1456 takes the value in bd1456 |

Qv | aqj1456 takes the value in bd1456 |

Qw | aqk1456 takes the value in bd1456 |

bqr1456 takes the value in bd1456 | |

Qx | bqi1456 takes the value in bd1456 |

Qy | bqj1456 takes the value in bd1456 |

Qz | bqk1456 takes the value in bd1456 |

Let us continue by looking at those Q commands used in sending data into the quaternion registers, which also perform some calculation. These are Q* and Q/. These two instructions are provided so that a real number in bd1456 may be used to scale the data in aq1456. In addition, Q! may be used to set aq1456 to zero. This is particularly useful where it is desired to set aq1456 to the value of a quaternion where only one or two of the individual registers used to represent the quaternion are non-zero. In this case the use of the Q! command immediately before setting those individual registers that are non-zero avoids the need to set individually those individual registers that need to contain a zero value.

Q* | aq1456 is multiplied by the value in bd1456 |

Q/ | aq1456 is divided by the value in bd1456 |

Q! | The value in aq1456 is set to zero. |

Let us complete the Q commands by looking at those Q commands used in sending data from the quaternion register aq1456 to ad1456, one of which, Qr, also performs some calculation. These commands are QR, QI, QJ, QK, and Qr.

QR | ad1456 takes the real part of aq1456 |

QI | ad1456 takes the i imaginary part of aq1456 |

QJ | ad1456 takes the j imaginary part of aq1456 |

QK | ad1456 takes the k imaginary part of aq1456 |

Qr | ad1456 takes the modulus of aq1456 |

We may now look at the u commands, where the data are entirely quaternions. These work in a similar manner to the way in which the commands for integers and doubles work. There are, however, certain differences. There are uw, u+, u-, u*, u/, u|, u= each of which alter aq1456 depending what is in bq1456. In addition the u! command sets aq1456 to zero. These are summarized in the table.

uw | aq1456 takes the value of bq1456 |

u+ | aq1456 takes the value of aq1456 + bq1456 |

u- | aq1456 takes the value of aq1456 - bq1456 |

u* | aq1456 takes the value of aq1456 * bq1456 |

u/ | aq1456 takes the value of aq1456 / bq1456 with the conjugate / conjugate multiplication term placed on the right hand side. |

u| | aq1456 takes the value of aq1456 / bq1456 with the conjugate / conjugate multiplication term placed on the left hand side. |

u= | The values in aq1456 and bq1456 are swapped. |

u! | The value in aq1456 is set to zero. |

The commands u> and u< are used for storing and retrieving quaternions to and from the mq1456 memory locations.

u> | aq1456 is copied into mq1456[bi1456] |

u< | mq1456[bi1456] is copied into bq1456 |

At this stage, the only function of a quaternion being included is the quaternion conjugate. The command uh is being used for the quaternion conjugate. My thinking is as follows. The command zj is used for the complex conjugate and it might seem reasonable to have uj as the quaternion conjugate. However, i, j and k are used as unit vectors with quaternions and there is perhaps a possibility that at some stage as this research proceeds that it might seem desirable to use ui, uj and uk as three commands in some way related to those unit vectors. Using uh for the quaternion conjugate keeps that possibility open.

uh | aq1456 takes the value of the quaternion conjugate of aq1456 |

Please know that the commands Q! and u! are identical in effect. The inclusion of both is for aesthetic considerations. The intention is that Q! be used when setting up data in the quaternion dome and that u! be used if one wishes to clear the aq1456 register in the midst of a manipulation of quaternions within the quaternion dome.

In order to use the quaternions for rotations a little about quaternions need to be understood. There are a number of useful items on the internet. I entered the word quaternion at the http://www.ask.co.uk web site. I have decided not to seek to describe the essentials of quaternions in this document, as there are other documents available on the web. A key point though that needs specific mention here is that in multiplying two quaternions together, the order is important. If q1 and q2 are two quaternions, generally q1*q2 is not the same as q2*q1.

The next topic is rotations and it is often the case that rotations are expressed using Greek letters. In this document three Greek letters are used. These are all lowercase and are as follows. The letter theta, represented by the θ character. The letter phi, represented by the φ character. The letter psi, represented by the ψ character.

The technique for computing rotations is to have the following.

- A quaternion representing the rotation operation about a given axis.
- A quaternion representing the point in three dimensional space that it is desired to rotate about that axis.
- The quaternion conjugate of the quaternion that represents the said rotation operation.

Suppose that the desire is to rotate the point given by (x=1, y=2, z=3) about the x axis by θ radians. The quaternion representing the rotation operation is given by the following.

cos(θ/2) + sin(θ/2)**i** + 0**j** + 0**k**

The quaternion representing the point is given by the following.

0 + 1**i** + 2**j** + 3**k**

The quaternion conjugate of the rotation operation is given by the following.

cos(θ/2) - sin(θ/2)**i** + 0**j** + 0**k**

(For the avoidance of doubt, the quaternion conjugate of a quaternion

4 + 5**i** + 6**j** + 7**k**

is

4 - 5**i** - 6**j** - 7**k**

and the + 0 in the quaternion conjugate further up the page is simply because - 0 is conventionally represented as + 0 rather than - 0.)

Above it was mentioned that the quaternion representing a rotation by θ radians about the x axis is given by the following.

cos(θ/2) + sin(θ/2)**i** + 0**j** + 0**k**

The quaternion representing a rotation by φ radians about the y axis is given by the following.

cos(φ/2) + 0**i** + sin(φ/2)**j** + 0**k**

The quaternion representing a rotation by ψ radians about the z axis is given by the following.

cos(ψ/2) + 0**i** + 0**j** + sin(ψ/2)**k**

There are now three demonstration programs. In each of these please imagine that the screen of the computer has X and Y coordinates, with X horizontal from left to right and Y vertical from top to bottom in the standard manner for Java graphics and with X and Y as capital letters as in the $X and $Y commands. Please imagine that you are sat observing from an observation gallery at the top of an observation tower that is within the quaternion dome. The ground is quite a way below you and the translucent roof is quite a way above you. Please imagine the space within the quaternion dome as having x, y and z coordinates with x horizontally from your left to your right, y horizontally from where you are sat and heading directly away from you into the distance and z vertically from the ground to the roof. You are sat at a point which, for the particular experimental three dimensional drawings that are to be observed, at x=0, a very negative value of y and z=0. That is, the floor of the dome is at z is very negative and the roof of the dome is at z very positive, so that neither the floor nor the roof of the dome is present in the drawings. Also, the far wall of the dome is so far away that you can disregard it!

In displaying a two dimensional representation of the three dimensional object in the quaternion dome on the two dimensional screen of the computer the following transformations are used, in this experiment.

X | 350 + x |

Y | 200 - z |

No account is taken of perspective. It may well be that in some future use of the 1456 system for displaying views of objects within the quaternion dome that perspective will be used, yet in order to convey the essentials of the system, perspective is not used here.

It is hoped that readers will wish to look at the following demonstrations and will like to study the source code of each. The methods of approach differ amongst the programs. One uses XOR mode graphics, the others do not. One computes the rotation of each point by explicit software for each point, the others use software in a loop. However, each of the demonstrations contains the same basic parts.

- Set up the colour toolbar and the font.
- Label the colour toolbar.
- Set up the points as quaternions in the correct order to draw them with lines connecting between them, using various Q commands and u> commands.
- Set up the rotation quaternions, using various Q commands and u> and uh commands.
- Extract data from the quaternions and display the picture, using u<, uw and various Q commands.
- Rotate the points about the axes in response to clicks on the panels of the colour toolbar using various u commands.

In this demonstration a 1, 2, root 3 triangle is rotated about three axes by clicking on the panels of the colour toolbar. The rotation angles θ, φ and ψ are each 0.2 radians for each step.

In this demonstration a wire frame cube is rotated about three axes by clicking on the panels of the colour toolbar. The rotation angles θ, φ and ψ are each 0.2 radians for each step. The cube has an extra piece fitted across one corner to assist in following the rotations.

This demonstration is simply a variation on demo13.htm so that the rotation is about the centre point of a somewhat larger cube. The rotation angles θ, φ and ψ are each 0.1 radians for each step. The cube has an extra piece fitted across one corner to assist in following the rotations. In addition an extra rotation is included so that the cube starts off in a rotated position. This new rotation is coded as five φ rotations followed by two θ rotations. The cyan area on the colour toolbar will reverse this rotation. Given that the quaternion representing the θ rotation is stored in mq1456[31] and that the quaternion representing the φ rotation is stored in mq1456[32], the coding for the extra rotation is as follows.

31u<uw 31u<u* 32u<u* 32u<u* 32u<u* 32u<u* 32u<u* 39u> uh49u>

This compound rotation is stored in mq1456[39] and its quaternion conjugate in mq1456[49].

This order is important, as the order in which the rotations of the cube take place affects the final orientation of the cube. If you would like to observe this effect, please try the following experiment. Run demo14.htm and click on -phi five times, then click on -theta twice. Please observe that the drawing is not a perfect horizontal and vertical square. Now, please run demo14.htm again, by refreshing the page, and then click on -theta twice and then click on -phi five times. This time a perfect horizontal and vertical square should be produced.

This demonstration shows two interlocking, yet not touching, triangles being rotated. Each triangle is in a vertical plane, though they are not in the same vertical plane. One of the triangles has a tag at one vertex so as to help viewers follow the motion of the two triangles in this demonstration.

In preparing those demonstrations that manipulate a three dimensional object I have been careful to keep all of the lines to be drawn in the same colour so that no issues arise of a line of one colour wrongly being in front or behind a line of another colour. Suppose that the two triangles of demo15.htm had been one red and one green. There would have been places where the view would have been drawn obviously wrongly.

I am hoping that the availibility of quaternions directly in 1456 object code will encourage their use for the producing of animated illustrations for use in free to the end user distance education both on the internet and in telesoftware broadcasts on television channels.

1456 object code

Copyright 2000 William Overington