4.4. Quaternions 173

Likewise, the composite rotation quaternion qnet can be found and applied to

vector v (in its quaternion form, v) as follows:

Notice how the quaternion product must be performed in an order opposite

to that in which the rotations are applied (q 3 q 2 q 1 ). This is because quaternion

rotations always multiply on both sides of the vector, with the uninverted

quaternions on the left and the inverted quaternions on the right. As we saw

in Equation (4.3), the inverse of a quaternion product is the reverse product of

the individual inverses, so the uninverted quaternions read right-to-left while

the inverted quaternions read left -to-right.

4.4.4. Quaternion-Matrix Equivalence

We can convert any 3D rotation freely between a 3 × 3 matrix representation

R and a quaternion representation q. If we let q = [ qV qS ] = [ qVx qVy qVz qS ] =

[ x y z w ], then we can fi nd R as follows:

Likewise, given R we can fi nd q as follows (where q[0] = qVx , q[1] = qVy ,

q[2] = qVz , and q[3] = qS). This code assumes that we are using row vectors

in C/C++ (i.e., that the rows of matrix R[row][col] correspond to the rows

of the matrix R shown above). The code was adapted from a Gamasutra article

by Nick Bobic, published on July 5, 1998, which is available here: htt p://www.

gamasutra.com/view/feature/3278/rotating_objects_using_quaternions.php.

For a discussion of some even faster methods for converting a matrix to a

quaternion, leveraging various assumptions about the nature of the matrix,

see htt p://www.euclideanspace.com/maths/geometry/rotations/conversions/

matrixToQuaternion/index.htm.

`void matrixToQuaternion(`

const float R[3][3],

float q[/*4*/])

{

float trace = R[0][0] + R[1][1] + R[2][2];

`net 1 2 3`

`1 2 3 net`

#### ;

#### .

#### =

#### ′==

#### R RRR

`v vR R R vR`

`net 3 2 1`

`3 2 1 11112 3 net net^1`

`q qqq;`

`v q q q vq q q−−−q vq−.`

#### =

#### ′==

`22`

22

22

#### 12 2 2 2 2 2

#### 2 2 12 2 2 2.

#### 2 2 2 2 12 2

`y z xy zw xz yw`

xy zw x z yz xw

xz yw yz xw x y