Sie sind auf Seite 1von 10

10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.

net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 1/10
Sign In Create Account
Home Articles Technical Math and Physics Article: Quaternion Powers

Home
For Beginners
Top Members
Marketplace
Bring your ideas to life with a Gaming Degree from Full Sail University
Articles
Forums
Community
Classifieds
Watched Content New Content
1
Quaternion Powers
By Sobeit Void | Published Jul 06 2000 10:37 AM in Math and Physics
root version square missing thanks shi quaternion norm pointing
If you find this article contains errors or problems rendering it unreadable (missing images or files,
mangled code, improper text formatting, etc) please contact the editor so corrections can be made. Thank
you for helping us improve this resource
Download attached article resource
Version 1.2, February, 2003
Updates
1.2
A minor correction with the formula of converting from Quat to Axis. The scale is missing a square root.
Thanks to Shi for pointing that out.
From version 1.0 - 1.1
The norm of a quaternion should be the square root of the q.q. The mistake was brought to my attention by
several kind readers and upon checking the definition of the Euclidean properties for complex numbers, I
realize the norm property
|| u+v || <= || u || + || v ||
2
Likes
3
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 2/10
is violated for the previous definition of the magnitude.
The code in the samples are updated as well.
Foreword
To me, the term 'Quaternion' sounds out of this world, like some term from quantum theory about dark
matter, having dark secret powers. If you, too, are enthralled by this dark power, this article will bring
enlightenment (I hope). The article will show you how to do rotations using quaternions, and bring you
closer to understanding quaternions (and their powers). If you do spot a mistake please email me at
robin@cyberversion.com. Also if you intend to put this on your site, please send me a mail. I like to know
where this ends up.
Why use Quaternions?
To answer the question, let's first discuss some common orientation implementations.
Euler representation
This is by far the simplest method to implement orientation. For each axis, there is a value specifying the
rotation around the axis. Therefore, we have 3 variables
x, y, z <-- angle to rotate around global coordinate axis
that vary between 0 and 360 degrees (or 0 - 2pi). They are the roll, pitch, and yaw (or pitch, roll, and yaw -
whatever) representation. Orientation is obtained by multiplying the 3 rotation matrices generated from the
3 angles together (in a specific order that you define).
Note: The rotations are specified with respect to the global coordinate axis frame. This means the first
rotation does not change the axis of rotation for the second and third rotations. This causes a situation
known as gimbal lock, which I will discuss later.
Angle Axis representation
This implementation method is better than the Euler representation as it avoids the gimbal lock problem.
The representation consists of a unit vector representing an arbitrary axis of rotation, and another variable
(0 - 360) representing the rotation around the vector:
x, y, z <-- unit vector representing arbitrary axis
angle <-- angle to rotate around above axis
Why are these representations bad?
Gimbal Lock
As rotations in the Euler representation are done with respect to the global axis, a rotation in one axis
could 'override' a rotation in another, making you lose a degree of freedom. This is gimbal lock.
Say, if the rotation in the Y axis rotates a vector (parallel to the x axis) so that the vector is parallel to the z
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 3/10
axis. Then, any rotations in the z axis would have no effect on the vector.
Later, I will show you an example of gimbal lock and how you can use quaternions to overcome it.
Interpolation Problems
Though the angle axis representation does not suffer from gimbal lock, there are problems when you need
to interpolate between two rotations. The calculated interpolated orientations may not be smooth, so you
will get jerky rotation movements. Euler representation suffers from this problem as well.
Let's get started
Before we begin, let's establish some assumptions I'll be making. I hate the way many articles leave this
important section out, causing a great deal of confusion when it comes to the mathematics.
Coordinate System - This article assumes a right hand coordinate system, like OpenGL. If you are using
a left handed coordinate system like Direct3D, you may need to transpose the matrices. Note that the
Direct3D samples have a quaternion library already, though I recommend you check through their
implementation before using it.
Rotation Order - The sequence of rotations in the Euler representation is X, then Y, and then Z. In matrix
form:
RotX * RotY * RotZ <-- Very Important
Matrix - Matrices are in column major format, like they are in OpenGL.
Example [ 0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15 ]
Vectors and Points - Implemented as a 4x1 matrix so applying a transformation is of the order
Rotation Matrix* [ vx
vy
vz
1 ] <-- 4x1 vector
This does not imply that I prefer OpenGL over Direct3D. It just happened that I learned OpenGL first, and
so my quaternion knowledge was gained in OpenGL.
Note: If you specify rotations in another order, certain quaternion functions will be implemented differently,
especially those that deal with Euler representation.
What is a Quaternion?
A complex number is an imaginary number that is defined in terms of i, the imaginary number, which is
defined such that i * i = -1.
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 4/10
A quaternion is an extension of the complex number. Instead of just i, we have three numbers that are all
square roots of -1, denoted by i, j, and k. This means that
j * j = -1
k * k = -1
So a quaternion can be represented as
q = w + xi + yj + zk
where w is a real number, and x, y, and z are complex numbers.
Another common representation is
q=[ w,v ]
where v = (x, y, z) is called a "vector" and w is called a "scalar". Although the v is called a vector, don't
think of it as a typical 3 dimensional vector. It is a vector in 4D space, which is totally unintuitive to
visualize.
Identity Quaternions
Unlike vectors, there are two identity quaternions.
The multiplication identity quaternion is
q= [1,(0, 0, 0)]
So any quaternion multiplied with this identity quaternion will not be changed.
The addition identity quaternion (which we do not use) is
q= [0,(0, 0, 0)]
Using quaternions as orientations
The first thing I want to point out is that quaternions are not vectors, so please don't use your preconceived
vector mathematics on what I'm going to show.
This is going to get very mathematical, so please bear with me.
We need to first define the magnitude of a quaternion.
|| q ||= Norm(q) =sqrt(w
2
+ x
2
+ y
2
+ z
2
)
A unit quaternion has the following property
w
2
+ x
2
+ y
2
+ z
2
=1
So to normalize a quaternion q, we do
q = q / || q || = q / sqrt(w
2
+ x
2
+ y
2
+ z
2
)
What is so special about this unit quaternion is that it represents an orientation in 3D space. So you can
use a unit quaternion to represent an orientation instead of the two methods discussed previously. To use
them as orientations, you will need methods to convert them to other representations (e.g. matrices) and
back, which will be discussed soon.
Visualizing a unit quaternion
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 5/10
You can visualize unit quaternions as a rotation in 4D space where the (x,y,z) components form the
arbitrary axis and the w forms the angle of rotation. All the unit quaternions form a sphere of unit length in
the 4D space. Again, this is not very intuitive but what I'm getting at is that you can get a 180 degree
rotation of a quaternion by simply inverting the scalar (w) component.
Note: Only unit quaternions can be used for representing orientations. All discussions from here on will
assume unit quaternions.
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 = [ w
2
+ x
2
- y
2
- z
2
2xy - 2wz 2xz + 2wy
2xy + 2wz w
2
- x
2
+ y
2
- z
2
2yz - 2wx
2xz - 2wy 2yz + 2wx w
2
- x
2
- y
2
+ z
2
]
Using the property of unit quaternions that w
2
+ x
2
+ y
2
+ z
2
= 1, we can reduce the matrix to
Matrix = [ 1 - 2y
2
- 2z
2
2xy - 2wz 2xz + 2wy
2xy + 2wz 1 - 2x
2
- 2z
2
2yz - 2wx
2xz - 2wy 2yz + 2wx 1 - 2x
2
- 2y
2
]
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 (x
2
+ y
2
+ z
2
)
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.
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 6/10
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 component 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:
<table border="1" cellpadding="5" cellspacing="0"><tbody><tr bgcolor="#666699"><td width="50%"><font
color="white"><b>Euler</b></font></td><td width="50%"><font color="white"><b>Quaternion</b></font>
</td></tr><tr><td class="code">glRotatef( <i>angleX</i>, 1, 0, 0)<br>glRotatef(
<i>angleY</i>, 0, 1, 0)<br>glRotatef( <i>angleZ</i>, 0, 0, 1)<br>// translate</td><td
class="code">// convert Euler to quaternion<br>// convert quaternion to axis
angle<br>glRotate(theta, ax, ay, az)<br>// translate</td></tr></tbody></table>
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.
Multiplying Quaternions
Since a unit quaternion represents an orientation in 3D space, the multiplication of two unit quaternions will
result in another unit quaternion that represents the combined rotation. Amazing, but it's true.
Given two unit quaternions
Q1=(w1, x1, y1, z1);
Q2=(w2, x2, y2, z2);
A combined rotation of unit two quaternions is achieved by
Q1 * Q2 =( w1.w2 - v1.v2, w1.v2 + w2.v1 + v1*v2)
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 7/10
where
v1= (x1, y1, z1)
v2 = (x2, y2, z2)
and both . and * are the standard vector dot and cross product.
However an optimization can be made by rearranging the terms to produce
w=w1w2 - x1x2 - y1y2 - z1z2
x = w1x2 + x1w2 + y1z2 - z1y2
y = w1y2 + y1w2 + z1x2 - x1z2
z = w1z2 + z1w2 + x1y2 - y1x2
Of course, the resultant unit quaternion can be converted to other representations just like the two original
unit quaternions. This is the real beauty of quaternions - the multiplication of two unit quaternions in 4D
space solves gimbal lock because the unit quaternions lie on a sphere.
Be aware that the order of multiplication is important. Quaternion multiplication is not commutative,
meaning
q1 * q2 does not equal q2 * q1
Note: Both quaternions must refer to the same coordinate axis. I made the mistake of combining two
quaternions from different coordinate axes, and I had a very hard time wondering why the result
quaternion fails in certain angles only.
Conversion To Quaternions
Now we learn how to convert other representations to quaternions. Although I do not use all the
conversions in the sample program, there are times when you'll need them when you want to use
quaternion orientation for more advanced stuff like inverse kinematics.
Axis Angle to Quaternion
A rotation around an arbitrary axis in 3D space can be converted to a quaternion as follows
If the axis of rotation is (ax, ay, az)- must be a unit vector
and the angle is theta (radians)
w = cos(theta/2)
x = ax * sin(theta/2)
y = ay * sin(theta/2)
z = az * sin(theta/2)
The axis must first be normalized. If the axis is a zero vector (meaning there is no rotation), the quaternion
should be set to the rotation identity quaternion.
Euler to Quaternion
Converting from Euler angles to a quaternion is slightly more tricky, as the order of operations must be
correct. Since you can convert the Euler angles to three independent quaternions by setting the arbitrary
axis to the coordinate axes, you can then multiply the three quaternions together to obtain the final
quaternion.
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 8/10
So if you have three Euler angles (a, b, c), then you can form three independent quaternions
Qx = [ cos(a/2), (sin(a/2), 0, 0)]
Qy = [ cos(b/2), (0, sin(b/2), 0)]
Qz = [ cos(c/2), (0, 0, sin(c/2))]
And the final quaternion is obtained by Qx * Qy * Qz.
Demo - Avoiding Gimbal Lock
Finally, we've reached what you all been waiting for: "How can quaternions avoid gimbal lock.?"
The basic idea is
1. Use a quaternion to represent the rotation.
2. Generate a temporary quaternion for the change from the current orientation to the new orientation.
3. PostMultiply the temp quaternion with the original quaternion. This results in a new orientation that
combines both rotations.
4. Convert the quaternion to a matrix and use matrix multiplication as normal.
Firstly, I want to make a disclaimer regarding the sample code. The code is ugly and very poorly
organized. But do remember, this is just a cut down version of my program when I was testing
quaternions, and I'm not getting paid for this.
There are two executable samples that I have included. The first program, CameraEuler.exe, is an
example for camera implementation using Euler angles.
The main concern should be the Main_Loop function in main.cpp.
The main thing you should take note (in the while loop) is
1. There are 3 angles I keep track of for rotation in the X, Y, and Z axis.
2. With every key press, I adjust the corresponding rotation variable.
3. In the while loop, I translate and then just convert the 3 Euler angles to rotation matrices and
multiply them into the final transformation matrix.
Use the up/down keys to rotate around the X axis, left/right to rotate around the Y axis and Insert/PageUp
to rotate around the Z axis.
This program suffers from gimbal lock. If you want to see it in action, rotate the camera so that the yaw is
90 deg. Then try rotating in the X and Z direction. See what happens.
Now for the quaternion solution. The program is CameraQuat.exe and it is a slight modification of the
previous program.
The main point you should take note (in the while loop) is
1. The orientation of the camera is a quaternion.
2. There are 3 angles corresponding to the keypress. Note the angles are meant to be an on/off switch
(not accumulative). I reset them inside the while loop. Of course this is not the best way to do it but
as I said, it is a quick job.
3. I convert the 3 angles to a temporary quaternion.
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 9/10
4. I multiply the temporary quaternion to the camera quaternion to obtain the combined orientation.
Note the order of multiplication.
5. The camera rotation is then converted to the Axis Angle representation for transforming the final
matrix.
When a key is pressed, I generate a temporary quaternion corresponding to the key for a small rotation in
that particular axis. I then multiply the temporary quaternion into the camera quaternion. This
concatenation of rotations in 4D space will avoid gimbal lock. Try it and see for yourself.
The camera quaternion has to be changed into either a matrix form or equivalence form so that you can
concatenate it into a final transformation matrix. You have to do this for every quaternion you use, as 4D
space and 3D space just don't mix. In the case of OpenGL, I just changed the quaternion to an Axis Angle
representation and let the API do the rest.
Although I did not use the global Euler angles for rotations in the second program, I have left them there as
a guide for you to see the similar Euler rotations in the first program. Note the Euler angles will be incorrect
if you rotate more than 1 axis (because it counts the keypress rather than getting the Euler angles from the
camera quaternion). It is just a reference for you to see that when you rotate the yaw to 90 deg when the
program starts, the gimbal lock problem is no more.
Note: I don't recommend you use my math library as it is. Understand the quaternion and write your own.
For your information, I am going to throw all of that away and rewrite it too. It is just too messy and ugly for
my taste.
What I did not show
If you notice, I did not show how to convert from a Quaternion to the Euler angle. That's because I have
yet to find a conversion that works perfectly. The only way I know is to obtain a matrix from the quaternion
and try to extract the Euler angles from the matrix. However, as Euler to matrix conversions are a many-to-
one relationship (due to sin and cos), I do not know how to get the reverse even using atan2. If anyone
knows how to extract Euler angles from a matrix accurately, please do share with me.
The other thing I did not show is the conversion of a matrix to a quaternion. I didn't think I needed this
conversion as you can convert the Euler and Axis angle representation to quaternion straight without
needing to throw them to a matrix.
More you can do - SLERP
If you think you are a quaternion master, think again. There is still more to learn about them. Remember I
said something about why the Axis Angle representation is bad? Does the word 'interpolation' ring a bell?
I don't have the time to write about interpolations using quaternions. This article has taken much longer
than I had anticipated. I can give you the basic idea about SLERP (Spherical Linear Interpolation), which is
basically generating a series of quaternions between two quaternion orientations (which you specify). The
series of quaternions will result in smooth motion between the first and end quaternion (something which
both the Euler and Axis Angle representation cannot achieve consistently).
Final Words
I hope this article can clear up any mystery behind the quaternion theory. A final word of caution again:
10/5/2014 Quaternion Powers - Math and Physics - Articles - Articles - GameDev.net
http://www.gamedev.net/page/resources/_/technical/math-and-physics/quaternion-powers-r1095 10/10
Home Home Articles Technical Math and Physics Article: Quaternion Powers

Don't multiply two quaternions from different coordinate frames. Nothing but pain and hair loss will
result from it.
With your new found powers, I bid thee farewell. Take care, .. and watch your back.
Download attached article resource
Comments
Note: Please offer only positive, constructive comments - we are looking to promote a positive atmosphere
where collaboration is valued above all else.
23 Like
English (USA) Mark Community Read Help
Copyright 1999-2014 GameDev.Net LLC
GameDev.net, the GameDev.net logo, and
GDNet are trademarks of GameDev.net, LLC