Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
89 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

  Contents

 Introduction
 Let's Get Started
 Quaternions
 Converting from
 Quaternions

 Multiplying
 Quaternions

 Conversion to
 Quaternions

 Demo
 Conclusion

 Printable version

 


Conversion from Quaternions

To be able to use quaternions effectively, you will eventually need to convert them to some other representation. You cannot interpret keyboard presses as quaternions, can you? Well, not yet.


Quaternion to Matrix

Since OpenGL and Direct3D allow rotations to be specified as matrices, this is probably the most important conversion function, since homogenous matrices are the standard 3D representations.

The equivalent rotation matrix representing a quaternion is


Matrix = [ w2+x2-y2-z2     2xy - 2wz     2xz + 2wy
            2xy + 2wz    w2-x2+y2-z2     2yz - 2wx
            2xz - 2wy     2yz + 2wx    w2-x2-y2+z2 ]

Using the property of unit quaternions that w2 + x2 + y2 + z2 = 1, we can reduce the matrix to

Matrix = [ 1 - 2y2 - 2z2    2xy - 2wz      2xz + 2wy
             2xy + 2wz    1 - 2x2 - 2z2    2yz - 2wx
             2xz - 2wy      2yz + 2wx    1 - 2x2 - 2y2 ]

Quaternion to Axis Angle

To change a quaternion to a rotation around an arbitrary axis in 3D space, we do the following:

If the axis of rotation is         (ax, ay, az)
and the angle is                   theta (radians)
then the                           angle= 2 * acos(w)

           ax= x / scale
           ay= y / scale
           az= z / scale

where scale = sqrt (x2 + y2 + z2)

Another variation I have seen is that the scale = sin(acos(w)). They may be equivalent, though I didn't try to find the mathematical relationship behind them.

Anyway if the scale is 0, it means there is no rotation so unless you do something, the axis will be infinite. So whenever the scale is 0, just set the rotation axis to any unit vector with a rotation angle of 0.

A Simple Example

In case you are getting confused with what I'm getting at, I will show you a simple example here.

Say the camera orientation is represented as Euler angles. Then, in the rendering loop, we position the camera using

RotateX * RotateY * RotateZ * Translate

where each compmenent is a 4x4 matrix.

So if we are using a unit quaternion to represent the camera orientation, we have to convert the quaternion to a matrix first

Rotate (from Quaternion) * Translate

A more specific example in OpenGL:

Euler Quaternion
glRotatef( angleX, 1, 0, 0)
glRotatef( angleY, 0, 1, 0)
glRotatef( angleZ, 0, 0, 1)
// translate
// convert Euler to quaternion
// convert quaternion to axis angle
glRotate(theta, ax, ay, az)
// translate

The above implementations are equivalent. The point I'm trying to get across is that using quaternions for orientation is the same as using Euler or Axis angle representation and that they can be interchanged through the conversion functions I've described.

Note that the above quaternion representation will also incur gimbal lock like the Euler method.

Of course, you do not know how to make the rotation to be a quaternion in the first place but we will get to that shortly.

Note: If you are using Direct3D or OpenGL, you may not have to deal with matrices directly, but matrix concatenation is something that the API does, so it's worth learning about them.




Next : Multiplying Quaternions