Probably the most important result on this page is the formula for representing rotations in 3 dimensions using quaternions (although we will also discuss how to use quaternions for other transforms on this page). This formula for 3D rotations is:
Pout = q * Pin * conj(q)
where:
- Pout and Pin are vectors represented by the i, j and k parts of a quaternion (real part =0)
- conj() is a conjugate function explained on this page.
- q is a quaternion which represents the rotation, if you prefer to think in terms of the angle and axis of the rotation then q is:
q = cos(a/2) + i ( x * sin(a/2)) + j (y * sin(a/2)) + k ( z * sin(a/2))
where:
- a = rotation angle
- x,y,z = rotation axis
So why is the rotation represented by this strange formula where the vector to be transformed is 'sandwiched' between two slightly different variants of 'q'? It is quite hard to get an intuitive grasp of this, although its easy to use it if you don't worry too much about how it works. If, like me, you like to know why things work then the rest of this page gives different ways to think about it.
Options for Transform Equation
When we discussed complex numbers we saw that we could rotate by 90° by multiplying by 'i', this also works for quaternions but, as we shall show here, it does not work if we represent the rotation by a linear combination of 'i', 'j' and 'k'. So we need to find another way.
Imagine that we (incorrectly) represented a rotation by:
Pout = Pin * q
Where q is a quaternion representing the 3D rotation by a linear combination of 'i', 'j' and 'k'.
As discussed on the arithmetic page this can be represented by a multiplication table, which represents the equivalent matrix representation of the transform:
| Pout.w |
| Pout.x |
| Pout.y |
| Pout.z |
|
= |
| q.w |
q.x |
q.y |
q.z |
| q.x |
-q.w |
-q.z |
q.y |
| q.y |
q.z |
-q.w |
-q.x |
| q.z |
-q.y |
q.x |
-q.w |
|
|
We can compare this with the matrix representation of a 3D rotation and we can see that, although it works for pure values of 'i', 'j' and 'k' representing a rotation of 90 around each of the three planes, it does not work for a linear combination of them.
Order of multiplication is important for quaternions so instead of Pout = Pin * q lets try: Pout = q * Pin
| Pout.w |
| Pout.x |
| Pout.y |
| Pout.z |
|
= |
| q.w |
q.x |
q.y |
q.z |
| q.x |
-q.w |
q.z |
-q.y |
| q.y |
-q.z |
-q.w |
q.x |
| q.z |
q.y |
-q.x |
-q.w |
|
|
This does not work either so lets try both pre and post multiplying by the conjugate to give:
Pout = q * Pin * conj(q)
This matches the matrix representation of a 3D rotation so we use this 'sandwich' form: Pout = q * Pin * conj(q) to use a quaternion to apply a 3D rotation.
Note that because of this double multiplication 'i' now represents a 90° for each multiplication, that is, 90°+90°=180° and similarly for 'j' and 'k'.
Note also that the q.w²+q.x²+q.y²+q.z² in the top left element represents the scaling factor, if we want pure rotation without any scaling then, we normalise the quaternion that is:
q.w²+q.x²+q.y²+q.z² = 1
The Sandwich Product
One way to look at the product:
q * Pin * conj(q)
Is that it is equal to:
Pout * q * conj(q)
Which is just 'Pout' (the result we want) because a quaternion times its conjugate is unity (q * conj(q) = 1) assuming q is normalised.
So by just reversing the order of the multiplication we change Pin into Pout. Now if q and Pin have no common factors, for instance if,
q = i
Pin = k
then reversing the order will change the sign, so,
Pout = -k
But for common terms (and real terms), for instance if,
q = i
Pin = i
then reversing the order will not effect the sign, so,
Pout = i
In this case 'i' is the axis of rotation so its not effected by the rotation. For other values of q we can start to see that the component along the axis of rotation will not be effected by the transform but the component in the plane of rotation will be rotated.
Why we use quaternions
Quaternions are very useful for calculating the results of rotations. On this page we discuss how a given quaternion can be used to rotate points in 3 dimensional space.
Although rotations in 3 dimensions have three degrees of freedom they are not a 3D vector space (we can't combine them using vector addition). Representations of 3D rotations using 3 scalar values are very messy, they are non linear, they have singularities and they are difficult to combine, see euler angle page for more details. To get round these problems we don't model the physical 3D space directly, instead we imbed it into a higher dimensional space, in this case the 4D quaternion space.
| concept |
3D space |
4D space |
| position |
x,y,z |
p = 0 + i x + j y + k z |
| orientation |
heading
attitude
bank |
q = cos(a/2) + (i x + j y + k z)sin(a/2) |
| rotation |
heading
attitude
bank |
q = cos(a/2) + (i x + j y + k z)sin(a/2) |
| rotate a point |
difficult to do |
q * p * conj(q) |
| combine rotations |
difficult to do |
q1 * q2 |
Rotations are the most useful application of quaternions although we also discuss how to use them for other transforms associated with 2 dimensional planes in 3 dimensional space:
| Type of transform |
Formula to use |
| Rotation (around the origin) |
Pout = q * Pin * conj(q) |
| Reflection in plane (through the origin): |
Pout = -q * Pin * q |
| Parallel component of plane: |
Pout = ½ (Pin + q * Pin * q) |
| Perpendicular component of plane: |
Pout = ½ (Pin - q * Pin * q) |
| Scaling: |
Pout = scalar * Pin --- or combine with rotation or reflection |
| Translation: |
Pout = q + Pin |
Where:
- q = quaternion representing transform
- Pin = vector representing point before being transformed.
- Pout = vector representing point after being transformed.
- conj() = conjugate function.
Compound Operations
So it is possible to perform various types of transform using quaternions but can we combine them into a single operation?
Because the above formulas contain both multiplication and addition then when we combine them (set Pin of one transform to Pout of the previous transform) then we can end up with very complex expressions.
This means that we cant necessarily derive a single quaternion that can represent a combination of the above transforms. This is obvious since a quaternion contains 4 scalar values so there is no way it can represent say the 6 degrees of freedom of a solid object.
If we want a single algebraic entity which can represent any combination of the above transforms then we would need to consider other algebras:
If we want to rotate, reflect or scale around a point other than the origin, this is the same as doing the operation around the origin combined with a translation.
Converting the 3D vector into a quaternion
First we convert the 3D vector into a quaternion, to do this we set the imaginary parts of the quaternion to the x,y and z values of the vector, the real part of the quaternion is set to zero. This quaternion is therefore not normalised like the quaternion representing the rotation.
So we take the vector: (x,y,z)
And represent it by the quaternion: 0 + i x + j y + k z
Now we need to combine this quaternion, representing a point, with a quaternion 'q' representing the transform, this is calculated as follows:
| Type of transform |
Value of 'q' |
| Rotation: |
q = cos(a/2) + i ( x * sin(a/2)) + j (y * sin(a/2)) + k ( z * sin(a/2))
where:
- a = rotation angle
- x,y,z = rotation axis
|
| Reflection in plane: |
q = i*x + j*y + k*z
where:
|
| Parallel component of plane: |
| Perpendicular component of plane: |
| Scaling: |
q = scalar |
We then apply the appropriate formula from the following table to generate the output vector:
| Type of transform |
Formula to use |
| Rotation: |
Pout = q * Pin * conj(q) |
| Reflection in plane: |
Pout = -q * Pin * q |
| Parallel component of plane: |
Pout = ½ (Pin + q * Pin * q) |
| Perpendicular component of plane: |
Pout = ½ (Pin - q * Pin * q) |
| Scaling: |
Pout = scalar * Pin --- or combine with rotation or reflection |
where:
- Pout = output point expressed as a quaternion
- q = quaternion representing the transform
- Pin = input point expressed as a quaternion
- conj() = conjugate function
If we apply this to every point in the 3D space we can think of the matrix as transforming the whole vector field.
If you just want to know how to use quaternions to do rotations in 3D space, that is all you need to know, you might like to look at some examples here. If you would like to know the theory behind it read on.
Examples
Here are some very simple examples, just to check that we are getting the expected results and we have not reversed a sign or anything like that.
To keep things very simple we will work with a plane represented by:
0 + 0 i + 0 j + 1 k
This represents the x-y plane in 3 dimensional space.
We can check what effect the different transforms have on a given point, say 0 + 2 i + 3 j + 4 k
Parallel component of plane
In this case we use the formula:
Pout = ½ (Pin + q * Pin * q)
Which gives:
Pout = ½ ((2 i + 3 j + 4 k) + k * (2 i + 3 j + 4 k) * k )
Pout = ½ ((2 i + 3 j + 4 k) + k * (-2 j + 3 i - 4 ))
Pout = ½ ((2 i + 3 j + 4 k) + 2 i + 3 j - 4 k
Pout = ½ (4 i + 6 j + 0 k)
Pout = 2 i + 3 j + 0 k
This is what we would expect when projecting onto the x-y plane, the x and y components stay the same and the z component is zero.
Perpendicular component of plane
In this case we use the formula:
Pout = ½ (Pin - q * Pin * q)
Which gives:
Pout = ½ ((2 i + 3 j + 4 k) - k * (2 i + 3 j + 4 k) * k )
Pout = ½ ((2 i + 3 j + 4 k) - k * (-2 j + 3 i - 4 ))
Pout = ½ ((2 i + 3 j + 4 k) - 2 i + 3 j - 4 k)
Pout = ½ (0 i + 0 j + 8 k)
Pout = 0 i + 0 j + 4 k
This is what we would expect when taking the parallel component to the x-y plane, the x and y components are set to zero and the z component is unchanged.
Reflection in plane
In this case we use the formula:
Pout = -q * Pin * q
Pout = - (k * (2 i + 3 j + 4 k) * k )
Pout = - (k * (-2 j + 3 i - 4 ))
Pout = - (- 2 i + 3 j - 4 k)
Pout = 2 i + 3 j - 4 k
This is what we want, the z plane is inverted, the other planes remain the same.
Mapping 3D coordinates to 2D coordinates in the plane.
It would be useful to be able to map between the 3D coordinates of points on a plane (using a quaternion) in 3D space and the corresponding 2D coordinates (using a complex number) within the plane.
We can do this using a 2×3 matrix (as described here), for example, but if we happen to be working with quaternions its a shame to have to switch to matricies.
An application of this would be projecting a 3D model onto a 2D computer screen or represinting a 2D image in a 3D model.
I'm not sure if quaternions can do this? can anyone help?
Derivation of rotation formula.
I would like to derive the rotation formula from the formula for projecting onto planes, is this possible?
Equation for transforming a point
To calculate the resulting point (P2) when we translate the point (P1) using quaternions then we use one of the following equations:
For Reflection & scaling: P2=q * P1 * q

For Rotation & scaling: P2=q * P1 * q'

Where:
- P1 = original position of point in the following format 0 + i x + j y +
k z
- P2 = resulting position of point after transform in the following format
0 + i x + j y + k z
- q = rotation quaternion = qw + i qx + j qy + k qz
- q' = conjugate of q = qw - i qx - j qy - k qz
In other words the elements are denoted by x, y and z for the position and
qw, qx, qy and qz for the quaternion representing the transform.
So why do these constructs work? Why does sandwiching a vector between two versions of the quaternion, that is transforming it, produce another vector which has been transformed in this way? I find it quite hard to get an intuitive interpretation of this, I can think of 3 approaches to this:
- We need this double multiplication to do the rotation in two halves that cancels out the real part, enabling it to be converted back to a vector at the end, this is explained in more detail here.
- The brute force method, we can show the above equations are correct by multiplying out all the terms and showing that they represent the same transforms as the matrix equivalents. The rotation case is proved below and the reflection case is proved on this page.
- By deriving the rotation result by combining two reflections, see this page.
Combining Transforms
Combining Rotations
First combining two rotations 'a' and 'b', applying 'a' gives:
P2=a * P1 * a'
Then we apply 'b' to the result
P2=b * a * P1 * a' * b'
we can rearrange this by using (b*a)' = a' * b' which gives:
P2= (b*a) * P1 * (b*a)'
which is equivalent to a single rotation of (b*a). So a rotation of b*a is equivalent to rotating by a and then by b.
Combining Reflections
Combining two reflections should, in general, give a rotation. But can we multiply the quaternions representing these reflections to get the resulting rotation?
First combining two reflections 'c' and 'd', applying 'c' gives:
P2=c * P1 * c
Then we apply 'd' to the result
P2=d * c * P1 * c * d
Can we get the second part into the same form as the first? Well we could use (d*c)' = c' * d' which gives:
P2= (d*c) * P1 * (d'*c')'
Since c and d are reflections then the real part is zero so,
c' = -c
in other words, in the conjugate function we invert the imaginary part. So applying this gives:
P2= (d*c) * P1 * (d*c)'
so if we let q=d*c we have
P2= q * P1 * q'
note that, unlike c and d alone, q does have a real and imaginary part.
As explained on this page, the result of two reflections is a rotation. Its angle is twice the angle between the normals of the reflection planes. So the required rotation is twice:
q.x = (v1 x v2).x
q.y = (v1 x v2).y
q.z = (v1 x v2).z
q.w = | v1 | | v2 | + v1 • v2
Quaternions can represent rotations, also non-normalised quaternions can represent
scaling by an equal amount in all dimensions (see discussion
with minorlogic
in the second part of this thread).
Unlike matrices, quaternions cannot represent translation or scaling by different
amounts in different dimensions.
A quaternion can be used to represent a rotation in 3 dimensions. If we are
rotating through t radians about a unit vector (x1,y1,z1) then the rotation
can be represented by multiplying by the following quaternion:
x1,y1,z1 represent a unit vector, about which we are rotating.
t is the angle we are rotating in radians.
We can use this rotation quaternion to calculate the rotated point from the
original position of the point, this allows us to translate points without using
matrices. The majority of applications involve pure rotations, for this we restrict
the quaternions to those with unit magnitude and we use only multiplications
and not addition to represent a combination of different rotations. When quaternions
are normalised in this way, together with the multiplication operation to combine
rotations, form a mathematical group,
in this case SU(2).