Version 4 (modified by martin, 8 years ago) |
---|

# Quaternion Maths

## TracNav

**About****Screenshots****News****Developer Blog****Mailing Lists****Forum****Documentation**- Getting Started
- Platform Specifics
- Tutorials
- Examples
- User Guides
- Programming Guides
- Reference Guides
- LatestDevelopments
- Porting
- CMake
- CDash
- CPack
- FAQ
- Tips And Tricks
- Maths
- Knowledge Base
- Trac Usage Examples
- TracGuide Documentation
- Software Patents
- Software Patents Europe
**Downloads****Community****Links**

Quaternions describe rotation transformations (at least as far as a SceneGraph is concerned).

A quaternion (invented by W R Hamilton http://mathworld.wolfram.com/Quaternion.html) is a number system like complex numbers but with 3 imaginary values and one real. The real term can be thought of as a rotation angle (actually COS(angle/2)) and the imaginary terms as a direction vector, the quaternion is a rotation about the vector. The imaginary terms are commonly written as [i,j,k] (a notation which has remained in use in vector notations). the products of ijk are: i*i=j*j=k*k=-1 and i*j*k=-1 too. Hence j*k = i, i*j=k and k*i=j - the order of multiplication is important, and the products can be considered as the cross product of the vectors, hence their usefulness in rotating frames where gyroscopic precession obeys similar cross product laws.

It is not obvious that any possible orientation of one coordinate system to another can be represented by a Quaternion, but it is so. {For hand waving purposes, there are 3 axes of space, so 3 parameters are required - such as EulerAngles - and the unit quaternion has 3 independent parameters so that is just enough adjustables). The length preserving unitary transformations required by most applications of a SceneGraph are unit quaternions - that is the sum of squares of the 4 components add up to 1.

The OpenSceneGraph provides many utilities to convert Quaternions to Matrices. Quaternions do not suffer from local infinities when a scene is being rotated, unlike an EulerAngle. For example imagine flying an aeroplane due North and pull back the stick until you are nearly flying vertically - you are still flying North, just slowly. Continue pulling back the stick and suddenly (instantly) you are flying South, the EulerAngle for heading has reversed. The quaternion representation of your flight changes smoothly through any orientation change. Quaternions are preferred when integrating up velocity & rotation rate to find a new position.

I have just returned from Dublin where I saw the bridge where WR Hamilton scratched his equation (not that this is important to the maths). When implemented as a quaternion, the rotation matrix about X for an angle A is
`q = [cos(A/2), sin(A/2), 0, 0] {written as qw,qx,qy,qz}`

The euler angles are [A,0,0] BUT the matrices are:

(Quaternion form):

1 0 0 0 0 (1-2*qx^2) - 2*qx*qw 0 0 2*qx*qw (1-2*qx^2) 0 0 0 0 1

and in Euler form:

1 0 0 0 0 cos(A) -sin(A) 0 0 sin(A) cos(A) 0 0 0 0 1

Strangely(!) the same result of course, but the Euler form requires evaluating cos and sin 4 times, quaternion at most twice (if you have been integrating the velocity and rotation rate then the quaternion requires NO sin and cos evaluations). This make quaternions much more numerically efficient. Obviously care is needed to be sure that the quaternion axes are consistent with the rotation axes, but we wouldn't be here otherwise.(GWM)

**Fast normalisation of quaternions**. If the quaternion deviates from a unit length then it represents a distortion of space (generally undesirable in Visual Simulation). If a quaternion is being integrated to get the orientation of a vehicle, then rounding errors are likely to make the quaternion slightly longer or shorter than unit. You can normalise in a 'brute force' manner by dividing by square root of length - but square roots are relatively slow, and the error should be very small. So write the square of the actual length as:

qw^2 + qx^2 + qy^2 + qz^2 = 1+alpha

then normalising the quaternion requires (qw,qx,qy,qz) to be divided by sqrt(1+alpha). Assuming alpha is small, this is equivalent to multiplying by (1-0.5*alpha)- since no square root is involved the correction can be made very efficiently. (GWM).