## Quaternions

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 + x**i** + y**j**
+ z**k**] 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.

### Adding and subtracting

Given two quaternions

q_{1 }= [s_{1}, v_{1}] = [s_{1} +
x_{1}**i** + y_{1}**j**
+ z_{1}**k**] and

q_{2 }= [s_{2}, v_{2}] = [s_{2} +
x_{2}**i** + y_{2}**j**
+ z_{2}**k**] they are added like
vectors i.e.

q = [(s_{1} + s_{2}) + (x_{1}** **
+** ** x_{2})** i** + (y_{1}** **
+ y_{2})**j**
+ (z_{1}** **+ z_{2})**k**]

Subtraction is done in a similar fashion.

### Multiplication

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.

i^{2} = j^{2} = k^{2} = ijk = -1

ij = k, jk = i, ki = j

ji = -k, kj = -i, ik = -j

So multiplying the quaternions above we get

q = q_{1}q_{2} = [(s_{1}s_{2} -
x_{1}x_{2} - y_{1}y_{2} -
z_{1}z_{2}) + (s_{1}x_{2} +
s_{2}x_{1} + y_{1}z_{2} -
y_{2}z_{1})**i**

+(s_{1}y_{2} + s_{2}y_{1} +
z_{1}x_{2} - z_{2}x_{1})**j** +
(s_{1}z_{2} + s_{2}z_{1} +
x_{1}y_{2} - x_{2}y_{1})**k**

### The inverse quaternion

For a given quaternion **q** = [s + x**i** + y**j**
+ z**k**]

the inverse quaternion q^{-1} is

q^{-1} = [s - x**i** - y**j** - z**k**] / |q|^{2}

whwre |q| is the magnitude of q and is given by the equation

|q| = √(s^{2} + x^{2} + y^{2} + z^{2})

The inverse quaternion fulfills the following

qq^{-1} = q^{-1}q = 1

### Quaternions in rotation

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 + x**i** + y**j** + z**k**]

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** = [x_{u}**i** + y_{u}**j** + z_{u}**k**]

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 + x**i** + y**j**
+ z**k**] the matrix is

1-2y^{2}-2z^{2} |
2xy-2sz | 2xz+2sy | 0 |

2xy+2sz | 1-2x^{2}-2z^{2} |
2yz-2sx | 0 |

2xz-2sy | 2yz+2sx | 1-2x^{2}-2y^{2} |
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.