Ok now, we are in the three dimensional space. Shouldn't we move around a little bit? If so the camera (our eyes to the world) should move along and more important it should change its orientation to represent the direction we are looking at and the orientation of our head. The image we see is different when our head is inclined than when it is straight up. The example of the camera orientation is only the top of the iceberg. It is more important to know the orientation of our objects since this is what we actually need in our calculations.
Orientation can be represented in several ways. The first one is the matrix form. This is the one used by graphics libraries like OpenGL. It simplifies projection calculations but it is hard to maintain and update as the objects move in the virtual world. Another proposal was made by Euler and is called Euler angles. In this the orientation is expressed by three angles, one for the rotation about each axis. This method is more natural for humans and is very memory efficient. BUT, it has some important problems. Rotations are not completely of one another since the second and the third occur in the resultant coordinate system. When pitch is ±90° we have the effect called Gimbal lock where heading and banking both rotate about the vertical axis.
Well this was the case until 1843. That year the Irish mathematician Sir William Rowan Hamilton published his work on Quaternions. Quaternions is the result of his long search for a way to generalize complex numbers so that they would be applicable to three dimensional space. What he came up with is the idea of a three-part imaginary system. This leads to a 4D notation which gives the name 'quaternion'.
A quaternion is a quadruple of real numbers q = [s, v] where 's' is a scalar and v a 3D vector. Expressing the vector in terms of its components we have q = [s + xi + yj + zk] where s, x, y, z are real numbers.
Mathematicians have shown over the years that quaternions can be used to rotate points about an arbitrary axis. This can be applied to objects and the virtual camera. Before we examine how they can be applied to rotation it is a good idea to get a closer look to their mathematical behavior and how we can deal with them. We should get to know them a little better.
Given two quaternions
q1 = [s1, v1] = [s1 +
x1i + y1j
+ z1k] and
q2 = [s2, v2] = [s2 +
x2i + y2j
+ z2k] they are added like
vectors i.e.
q = [(s1 + s2) + (x1 + x2) i + (y1 + y2)j + (z1 + z2)k]
Subtraction is done in a similar fashion.
Before we continue with multiplication we must bear in mind the meaning of the i, j, k elements and their behavior. There are some special rules in the multiplication of quaternions.
i2 = j2 = k2 = ijk = -1
ij = k, jk = i, ki = j
ji = -k, kj = -i, ik = -j
So multiplying the quaternions above we get
q = q1q2 = [(s1s2 -
x1x2 - y1y2 -
z1z2) + (s1x2 +
s2x1 + y1z2 -
y2z1)i
+(s1y2 + s2y1 +
z1x2 - z2x1)j +
(s1z2 + s2z1 +
x1y2 - x2y1)k
For a given quaternion q = [s + xi + yj + zk]
the inverse quaternion q-1 is
q-1 = [s - xi - yj - zk] / |q|2
whwre |q| is the magnitude of q and is given by the equation
|q| = √(s2 + x2 + y2 + z2)
The inverse quaternion fulfills the following
qq-1 = q-1q = 1
Consider a point P(x,y,z) in the three dimensional space. It can be assigned a position vector with its tail at the origin point. This can be converted to a quaternion with 0 as scalar term like this
p = [0 + xi + yj + zk]
This quaternion can be transformed into another position vector with a simple multiplication. It was mathematically proved that for a position vector p the rotated vector p' coordinates are given by
p' = qpq-1
where the unit quaternion q holds the axis and angle of rotation. Here is how we encode the rotation in the q quaternion. First we define the axis of rotation as a unit vector u
u = [xui + yuj + zuk]
and thus the transformation quaternion is
q = [cos(θ/2), sin(θ/2)u]
whose inverse quaternion is
q-1 = [cos(θ/2), -sin(θ/2)u]
and finally the rotated vector is
p' = qpq-1 → p' = [0 + x' i + y' j + z' k]
from where we can get the final x', y', z' coordinates
Now that we have calculated the final position of our object and we have its orientation quaternion we need to draw it. The obstacle is the quaternion itself. No graphics library that I know of (neither OpenGL not DirectX) accepts quaternions. They require the transformation matrix instead. The conversion from quaternion to matrix is very simple. For the quaternion q = [s + xi + yj + zk] the matrix is
1-2y2-2z2 | 2xy-2sz | 2xz+2sy | 0 |
2xy+2sz | 1-2x2-2z2 | 2yz-2sx | 0 |
2xz-2sy | 2yz+2sx | 1-2x2-2y2 | 0 |
0 | 0 | 0 | 1 |
This simplicity in handling and formulation of calculations is what makes quaternions the first choice of game programmers to hold and calculate rotation in 3D space. Once you get past the first shock and start understanding the idea behind them you will see their beauty too.