Ben Burns wrote:
I suspect that a Quaternoin library might be what your after here,
assuming I’ve got the right end of the stick. Gamasutra have an
article on it, somewhere
Quaternions are really strange mathematical objects, just like complex
numbers except that instead of just a real and imaginary part, you have
three imaginary components, so every quaternion is of the form a + bi +
cj + dk, where i, j, and k when squared equal -1. The odd thing about
these numbers is that they don’t obey the commutative law of
multiplication pq != qp if p and q are quaternions. They’re multiplied
by the distributive law, and by the rules: i^2 = j^2 = k^2 = -1, ij = k
= -ji, jk = i = -kj, and ki = j = -ik. For rotations in graphics,
you’re going to be interested in the unit quaternions, quaternions for
which sqrt(a^2 + b^2 + c^2 + d^2) = 1, as in this form:
cos(phi/2) + b*sin(phi/2)i + csin(phi/2)j + dsin(phi/2)*k
This corresponds to a rotation of an angle phi about the axis [ b c d ]
(which is a unit vector, of course). A unit quaternion can also be
thought of as a point on the surface of a four-dimensional hypersphere,
so if you try to interpolate between two unit quaternions, you can get
an intermediate rotation. Gamasutra describes Shoemake’s spherical
linear interpolation method, but I think getting the logarithm of the
quaternions and performing linear interpolation is easier. The
logarithm of a quaternion is given by
ln(a + bi + cj + dk) = log(sqrt(a^2 + b^2 + c^2 + d^2))
- ibarctan(r/a)/r
- jcarctan(r/a)/r
- kdarctan(r/a)/r
where r = sqrt(b^2 + c^2 + d^2)
Note that the first component will always be zero for unit quaternions.
Linearly interpolate each of the components of the logarithm of both
quaternions then perform the quaternion exponential on the result, given
by
exp(a + bi + cj + dk) = exp(a)cos® +
iexp(a)bsin®/r +
jexp(a)csin®/r +
kexp(a)dsin®/r
where r is the same factor as above. This finds an intermediate
rotation. Now, to actually use the quaternion rotation q on a point
p=[x y z], you compute the quaternion product s’ = qsq^-1 where q is the
unit quaternion a + bi + cj + dk for the rotation you want, q^-1 is a -
bi - cj - dk, and s = xi + yj + zk. s’ will be of the form x’i + y’j +
z’k, so the rotated point is p’=[x’ y’ z’]. The quaternion triple
product above is equivalent to a rotation matrix, as a lot of tedious
algebra can show. The proof is left as an exercise for the reader :-).
For more information, you can check the Gamasutra article referred to
above, and Section 21.1 and Exercise 21.7 in Foley, et. al.'s “Computer
Graphics: Principles and Practice”. I had to implement a lot of this
for my software renderer library…–
| Rafael R. Sevilla @Rafael_R_Sevilla |
| Instrumentation, Robotics, and Control Laboratory |
College of Engineering, University of the Philippines, Diliman |
---|