248 CHAPTER 8: Putting It All Together^
What Are These Quaternion Things Anyway?
On October 16, 1843, in Dublin, Irish mathematician Sir William Hamilton was taking a
stroll by the Royal Canal when he had a sudden flash of mathematical inspiration. He’d
been working on ways to meaningfully multiply and divide two points in space and
suddenly saw the formula for quaternions in his mind: i^2 =j^2 =k^2 =ijk=− 1.
Impressive, huh?
He was so excited that he couldn’t resist the temptation to carve it into the stonework of
the Brougham Bridge he had just come to (no doubt nestled in between lesser graffiti
like ‘‘Eamon loves Fiona, 1839’’ or ‘‘Patrick O’Callahan rulz!’’). Radically new ways to
look at physics and geometry descended directly from this insight. For example, the
classic Maxwell’s equations in electromagnetic theory were described entirely through
the use of quaternions. As newer methods of dealing with similar situations came about,
quaternions were shunted aside until the late 20th century, when they found a significant
role in 3D computer graphics, in navigation of the Apollo spacecraft to the moon, and in
other areas that rely heavily on rotations in space. Because of their compact nature, they
could describe a direction vector, and hence a 3D rotation, more efficiently than the
standard 3x3 matrix. Not only that, but they provided much superior means of
concatenating a series of rotations on top of each other. So, what does this mean?
In Chapter 2, we covered the traditional 3D transformation math using matrices. If you
wanted to rotate an object 32° around the z-axis, you would instruct OpenGL ES to
perform a rotation via the command glRotation(32,0,0,1). Similar commands would be
executed for the x- and y-axes as well. But what if you wanted a funky sort of rotation
that an airplane might make when banking to the left? How would that be described in
the glRotatef() format? Using the more traditional way, you would generate separate
matrices for the three rotations and then multiply them in order of yaw (rotation around
the Y-axis), pitch (rotation around the X-axis), and roll around the Z-axis. That’s a lot of
math to aim toward one direction. But if this is for a flight simulator, your banking motion
will constantly update to new rolls and headings, incrementally. That would mean you’d
have to calculate the three matrices each time for the deltas of your trajectory since the
last frame and not absolute values from some starting point.
In the early days of computers, when floating-point calculations were expensive and
shortcuts were regularly invoked for performance reasons, round-off errors were
common and would likely build up over time, causing the current matrices to be ‘‘out of
square.’’ However, quaternions were brought to the rescue because they had a couple
of very compelling properties. The first is that a quaternion can represent a rotation of an
object in space roughly equivalent to how glRotatef() works but by using fractional axis
values. It’s not a direct one-to-one correlation, because you still need to go about some
of that math stuff to convert attitudes to and from a quaternion. The second and more
important property derives from the fact that an arc on a sphere can be described by
two quaternions, one at each endpoint. And any point between them on the arc can also
be described by a quaternion merely by interpolating the distance from one endpoint to
the other by using spherical geometry, as shown in Figure 8-2. That is, if you were going
through an arc of 60°, you could find an intermediate quaternion, say, 20° from the
starting point by tracing a third of the way along the arc. In the next frame, if you were to