Você está na página 1de 23

Quaternions and Rotations

Advanced Games Programming Christopher Peters

But first

Hierarchical Transformations

Back to Quaternions and Rotations


Basis
Showing consecutive related static images one after another produces the perception of a moving image

Traditional Animation
Master artists draw certain important keyframes in the animation Apprentices draw the multitude of frames inbetween these key-frames Called tweens

In Practice
On Computers:
Object has an initial configuration and a final configuration (often specified by the artist) Computer must figure out the intermediate configurations: interpolation

Orientation Interpolation:
Given two key-frame orientations, figure out an intermediate orientation at a certain point between them

Possible Solutions
Potential Solution #1:
Use Euler angles Interpolate between individual angles

Potential Solution #2:


Interpolate between two rotation matrices

Neither of these is a good idea


Lets see why

#1: Euler Angles


An Euler angle is a rotation around a single axis Any orientation can be specified by composing three rotations
Each rotation is around one of the principle axes i.e. (x, y, z) first rotate around x, then y, then z Think of roll, pitch and yaw of a flight simulator

When rotating about a single axis, is possible to interpolate a single value


However, for more than one axis, interpolating individual angles will not work well Unpredictable intermediate rotations

Euler Angle Problems


Gimbal lock:
Rotation around two or more axes results in a loss of rotational degrees of freedom Imagine an aircraft pitches up 90 degrees: its roll axes become parallel to the yaw axis Changes about yaw can not be compensated for Can be overcome by adding a fourth gimbal

#2: Rotation Matrices


Interpolating between two rotation matrices does not give a rotation matrix
Does not preserve rigidity of angles and lengths This result of an interpolation of 0.5 between the identity matrix and 90 degrees around the x-axis does not produce a valid rotation matrix:

Solution
Use quaternion interpolation Quaternions dont suffer from Gimbal lock Can be represented as 4 numbers instead of 9 of a 3x3 matrix Trivial conversion between angle/axis representation Easy interpolation between two quaternions is easy

Representation
Defined like complex numbers but with 4 coordinates
q[w,(x,y,z)] also written q[w,v] where v = (x,y,z) q = w + xi + yj + zk Here, w is real part, and (x,y,z) are imaginary parts Think of w as angle in an angle-axis representation Think of (x,y,z) as axis in an axis-angle representation

Baed on three different roots of -1:


i2 = j2 = k2 = -1

Quaternions are unit vectors on a 3-sphere in 4 dimensional space

Representation
For a right-hand rotation of radians about unit vector v, quaternion is: q = (cos(/2); v sin(/2))
Note how the 3 imaginary coordinates are noted as a vector Only unit quaternions represent rotations
Such a quaternion describes a point on the 4D unit hypersphere

Important note: q and q represent the exact same orientation

Quaternion Toolbox
Addition
q1 + q2 = [w1 + w2, v1 + v2]

Multiplication Magnitude

q1q2 = [w1w2 v1.v2, v1 x v2 + w1v2 + w2v1] (note: q1q2 != q2q1)


| q | = sqrt(w2 + x2 + y2 + z2)

Normalisation
N(q) = q / | q |

Conjugate
q* = [w , -v]

Inverse
q-1 = q* / | q | 2

Unit quternion
q is unit if | q | = 1 and q-1 = q*

Identity
qIdentity = [1,(0,0,0)] for multiplication, qIdentity = [0,(0,0,0)] for addition

Transforming a Point or Vector


To transform a vector P by the rotation specified by the quaternion q:
Two options: 1. Multiply conj(q) by (0,Px,Py,Pz)
(see next page)

or 2. Convert q to matrix and use matrix transformation

First Method
Rotate vector P angle around the unit axis R:
1. Form the quaternion representing the vector P q1 = (0,Px,Py,Pz) 1. Form the rotation quaternion from the axis R and angle q2 = (cos(/2),Rx sin(/2),Ry sin(/2),Rz sin(/2)) 3. The rotated vector is given by v entry of the quaternion: q3 = q2 q1 q2* q2 must be of unit magnitude for this to work properly

Quaternion and Axis-Angle


From axis-angle to quaternion:
q = (cos(/2); v sin(/2)) Here:
v is the axis

is the angle

From quaternion to axis-angle: Axis v = (x,y,z) / sqrt(x2 + y2 + z2) Angle = acos(w) * 2

Quaternion to Matrix
From quaternion to a 3x3 rotation matrix:

See: http://www.gamasutra.com/features/19980703/quaternions_01.htm P.s. This may not work for you if not, have a look on the web for other examples

Euler Angles to Quaternion


From Euler angles (pitch, yaw, roll) Create three quaternions
One for each of pitch, roll, yaw Then multiply them together Here, P = pitch/2, Y = yaw/2, R = roll/2
w = cos(R)*cos(P)*cos(Y) + sin(R)*sin(P)*sin(Y) x = sin(R)*cos(P)*cos(Y) cos(R)*sin(P)*sin(Y) y = cos(R)*sin(P)*cos(Y) + sin(R)*cos(P)*sin(Y) z = cos(R)*cos(P)*sin(Y) sin(R)*sin(P)*cos(Y)

Quaternion Lerp
Lerp: Linear intERPolation:
LERP(Q0,Q1,t) = Q0 + t(Q1-Q0)

Interpolate each of the four components individually Not good at all:


The intermediate quaternions dont represent rotations! They arent normalised and therefore dont fall on our unit hypersphere

Normalised Lerp
This time, do same as above but normalise the quaternion after the LERP:
Normalise(LERP(Q0,Q1,t))

Better, but not perfect The rate of interpolation is not constant


Practically, this gives the unwanted side-effect of the object rotation speeding up and slowing down between interpolated points

Enter: Slerp
Spherical Linear intERPolation Dont interpolate along a straight line between Q0 and Q1 Instead, interpolate along the surface of the unit hyper-sphere

Trace the arc between each quaternion

Slerp
Need to know , the shortest angle between the two quaternions Provides a smooth interpolation with a constant rate of change Can also do a spline interpolation along a sequence of quaternions for a smooth path of rotations

Usage
Not always the best choice
Quaternions are (as you will have noticed) hard to visualise If another method will do and is simpler, it will be a more appropriate choice

But
Extremely useful in many situations where other representations are awkward Easy to use in your own programs once you have a quaternion class

Be wary!
1. Recall, each 3D rotation has two quaternion representations: q and -q 2. As you do calculations on quaternions (as is the case with matrices) rounding errors build up
A resulting quaternion that looks on paper like it should be unit may not actually be unit at all Make sure to normalise quaternions to prevent problems Analogous to the way one can orthogonalise a matrix to prevent the same problems, but easier to do with quaternions

Você também pode gostar