Quaternion Class

A 3D object for representing orientation or rotation within an RB3DSpace world.

Properties
W
X
Y
Z

Methods
Inverse
Invert
MultiplyBy
Normalize
SetBetween
SetRotateAboutAxis
Times
Transform

# Notes

A Quaternion is a compact, efficient way to represent orientation or rotation in three-dimensional space. They do the same job for orientation and rotation that vectors do for position and movement. Any possible rotation can be represented as an angle turned around a certain axis. A Quaternion is essentially an axis plus an angle, although the internal representation is slightly different from this for mathematical reasons.

Just as a vector can be used to represent either position or displacement, a Quaternion can be used to represent either orientation or rotation. To represent absolute orientation, we simply consider the quaternion as a rotation relative to a "null" or standard orientation.

The neat thing about quaternions is that they can be combined in a very straightforward manner. When you multiply quaternion A by quaternion B, the result is a quaternion which we'll call C. Rotation C puts the object in exactly the same orientation as you'd get by doing rotation A followed by rotation B. Multiplying quaternions is exactly the same as composing rotations.

To make a quaternion represent a particular rotation, use the SetRotateAboutAxis method, giving it the axis and the angle (in radians) you want to rotate. For example, to make a quaternion that rotates 90 degrees around the X axis, you'd use:

q.SetRotateAboutAxis 1,0,0, Pi/2

To rotate a vector, use the Transform method of a Quaternion. Give it a vector, and the result will be a new vector, rotated about the origin (0,0,0).

To interpolate between two Quaternions: this is used when you think of the quaternions as representing orientation. You have q1 representing the object in one orientation and q2 representing it in another. You want to animate the object smoothly rotating between q1 and q2. To do this, set the object's orientation to something in between q1 and q2 by using the SetBetween method. The final parameter is the position between these two, with 0.0 meaning q1 and 1.0 meaning q2. 0.5 would be a position exactly halfway in between.

One common application is to update an object's orientation by some rotation. For example, suppose Object3D didn't have a built-in Yaw method. You could do the same thing yourself as follows:

Dim yawQuat as Quaternion
yawQuat = New Quaternion
yawQuat.SetRotateAboutAxis 0,1,0, yawAngle // "yaw" -rotate about Y axis
obj.orientation = yawQuat.Times(obj.orientation)

Note that when multiplying quaternions, order does matter. A.Times(B) is not the same as B.Times(A); this is just the nature of rotations in 3D space.

Finally, note that quaternions also have a MultiplyBy function; Q1 = Q1.Times(Q2) can be written more efficiently as Q1.MultiplyBy Q2. But that doesn't help in the example above, because we need Q2 = Q1.Times(Q2) in order to get the correct ordering. We want to start with the current orientation of the object, so it must appear on the right.

## Interpolation

Use the SetBetween method, giving it the two quaternions you want to interpolate between, and the interpolation factor: 0.0 to exactly match the first quaternion, 1.0 to exactly match the second, and something else to assume some position in between:

Q.SetBetween Q1, Q2, 0.25 // set Q to 25% of Q1 plus 75% of Q2

This is an amazingly useful technique. It lets you produce smooth animation between the orientation that you have and an orientation you want to have. For example, if you have two "keyframe" (pre-defined or pre-computed) positions and orientations the object is supposed to interpolate between, in 11 steps, you could do it this way:

For i = 0 to 10
obj.position.x = position1.x * i/10 + position2.x * (1 - i/10)
obj.position.y = position1.y * i/10 + position2.y * (1 - i/10)
obj.position.z = position1.z * i/10 + position2.z * (1 - i/10)
obj.orientation.SetBetween orientation1, orientation2, i/10
Rb3DSpace1.Update
next

# See Also

Bounds3D, ColorList, Element3D, Group3D, Light3D, Material, Object3D, TriangleList, Trimesh, UVList, Vector3D, VectorList classes; RB3DSpace control.