3
votes

(perhaps this is better for a math Stack Exchange?)

I have a chain composed of bones. Each bone has a with a tip and tail. The following code computes where its tip will be, given a rotation, and sets the next link in the chain's position appropriately:

    // Quaternion is a hand-rolled class that works correctly (as far as I can tell.)
    Quaternion quat = new Quaternion(getRotationAngleDegrees(), getRotation());

    // figure out where the tip will be after applying the rotation
    Vector3f rotatedTip = quat.applyRotationTo(tip);

    // set the next bone's tail to be at this one's tip
    updateNextPosFrom(rotatedTip);

This works if the rotation is supposed to occur around the origin of the object's coordinate system. But what if I want the rotation to occur around some other arbitrary point in the object? I'm not sure how to translate the quaternion. What is the best way to do it?

(I'm using JOGL / OpenGL.)

5

5 Answers

5
votes

Dual quaternions are useful for expressing rigid spatial transformations (combined rotations and translations.)

Based on dual numbers (one of the Clifford algebras, d = a + e b where a, b are real and e is unequal to zero but e^2 = 0), dual quaternions, U + e V, can represent lines in space with U the unit direction quaternion and V the moment about a reference point. In this way, dual quaternion lines are very much like Pluecker lines.

While the quaternion transform Q V Q* (Q* is the quaternion conjugate of Q) is used to rotate a unit vector quaternion V about a point, a similar dual quaternion form can be used to apply to line a screw transform (the rigid rotation about an axis combined with a translation along the axis.)

Just as any rigid 2D transform can be resolved to a rotation about a point, any rigid 3D transform can be resolved to a screw.

For such power and expressiveness, dual quaternion references are thin, and the Wikipedia article is as good a place as any to start.

4
votes

A quaternion is used specifically to handle a rotation factor, but does not include a translation at all.

Typically, in this situation, you'll want to apply a rotation to a point based on the "bone's" length, but centered at the origin. You can then translate post-rotation to the proper location in space.

4
votes

Quaternions are generally used to represent rotations only; they cannot represent translations as well.

You need to convert your quaternion into a rotation matrix, insert it into the appropriate part of your standard OpenGL 4x4 matrix, and combine it with a translation in order to rotate about an arbitrary point.

4x4 rotation matrix:
  [ r r r 0 ]
  [ r r r 0 ]  <- the r's are the 3x3 rotation matrix from the wiki article
  [ r r r 0 ]
  [ 0 0 0 1 ]
0
votes

Edit : This answer is wrong. It argues on 4x4 transformation matrices properties, which are not quaternions...

I might have got it wrong but to me (unlike some answers) a quaternion is indeed a tool to handle rotations and translations (and more). It is a 4x4 matrix where the last column represents the translation. Using matrix algebra, replace the 3-vector (x, y, z) by the 4-vector (x, y, z, 1) and compute the transformed vector by the matrix. You will find that values of the last column of the matrix will be added to the coordinates x, y, z of the original vector, as in a translation.

A 3x3 matrix for a 3D space represents a linear transformation (like rotation around the origin). You cannot use a 3x3 matrix for an affine transformation like a translation. So I understand simply the quaternions as a little "trick" to represent more kinds of transformations using matrix algebra. The trick is to add a fourth coordinate equal to 1 and to use 4x4 matrices. Because matrix algebra remains valid, you can combine space transformations by multiplying the matrices, which is indeed powerful.