Some website update is currently going on. Stay tuned :-)
Implementing coordinate frames.
or how to use quaternions easily.

incomplete, under construction

Seems that using quaternions to store and process orientation is kind of hot topic these days... There is some implementation tips that should help to stop worrying and learn to love the bom...errr, quaternions. In fact this text is not really so quaternion-related; it allows you to replace quaternions with whatever other thing you like, without changing any application code, by introducing some higher level of abstraction.
In this text, it is assumed that reader already know what the hell is quaternions, how to multiply them, and similar stuff. There, only usage of quaternions will be explained.

You probably noticed that in most cases in computer graphics where you use quaternion, or axis and angle, or 3x3 matrix, you actually want to deal with 3D rotations, and "implement" rotations as matrix or quaternion. In good design, implementation details should be keept away from main code.(of course everything is good only to some extent) It is quite reasonable to make all your classes that store rotation transform , be it 3x3 orthonormal matrix, quaternion, axis-angle, or euler angles, to have some common methods that beyongs not necessarily to underlying math construct but to rotations itself. So, you can easier interchange them. Let's define what operations we can do on _rotations_ : For example, rotations can be concatenated. That is, if you rotate by A and then by B, you can find C that rotation by C gives same effect. It is reasonable to define operator*(Rotation, Rotation) to concatenate rotations. So, (B*A) defines rotation by A followed by rotation by B (or, reference frame A as child of reference frame B. More on why this order is preferred below). There you can see that it's getting similar to multiplication of matrices or quaternions - you also have such multiplication that works in such way. So you can ask "what's the point in defining same thing again". What is very important to understand is that multiplication of matrices or quaternions do more than concatenation of rotations. For example, it can be used for scaling. Computational instability leads to de-orthonormalization of matrix, or to non-unit-length quaternions. You can add normalization (or fast normalization, more on it below) of quaternions into this operator*(Rotation, Rotation), for example, to ensure stability. Or you can add debugmode assertion of 1-epsilon>= |Q| <=1+epsilon, to simplify debugging of computational instability problems Also, you can even define this operator for axis and angle or Euler angles if you like, but it is IMHO pointless/inefficient.). Also, for every rotation there is inverse rotation. So, you can define Inverse() to return inverse rotation. There things gets more interesting. You can implement it as transpose of 3x3 matrix, or as negation of real part of quaternion (it's actually -conjugate(Q). Remeber that -Q stores same rotation as Q, so -conjugate(Q) and conjugate(Q) aswell). Now, while with matrices and quaternions your code would need to use different functions, transpose and conjugate, with Rotation code doesn't depend to implementation details(what it uses internally). Unlike those get_XXX and set_XXX methods(IMHO totally unuseful bloat), it really allows you to change internal representation, and you really might want to do that.

And of course rotation should be able to rotate point. It is also reasonable to define * to do that. Why: A*(vector1+vector2)=A*vector1+A*vector2 is true for rotations. In words: sum of rotated points is equal to rotated sum of points(sounds bit like tautology)

You also may need to transform rotations from one representation to other (you can transform axis and angle to orthonormal 3x3 matrix or to quaternion, for example) 3x3 and 4x4 matrices is somewhat special thing, them are practical for transforming several vectors, and 4x4 matrices is practical for general transformations(that's why OpenGL or DirectX uses them). So, conversion to 3x3 matrix is the most necessary conversion there. Another somewhat special thing is axis and angle, it is easier for human to specify rotation this way. So it is good to make conversion of axis and angle to quaternion and back, for human input. So rotation will definately be not harder to use than axis-angle

You can write your utility functions for your favorite API, e.g. for OpenGL, something like glmRotate(Rotation) that will convert rotation to 4x4 matrix and use glMultMatrix on it. (glm can mean GL math) It is reasonable to have glmRotate(Rotation) and glmRotateInv(Rotation) where RotateInv should rotate by inverse rotation.

incomplete, under construction

TODO:
fix Typos.
add sample implementation of rotation class (using quaternions). Also, I will add descriptions and implementation of Euclidean Transformation class (coordinate frame). It does rotation and translation (sample uses Rotation and Vector), and similarly have operator* not unlike 4x4 rotation-and-translation matrix.

show that such abstracted system is significantly easier to use than bare 4x4 matrix or axis and angle, and allows you to change internal representation/optimize something(store precalculated inverse, for example)/etc. if you like.



References:

MathWorld: Quaternion.
EuclideanSpace.com: Maths - Combined Rotation and Translation (great site, BTW.)
http://gandalf-library.sourceforge.net/ some library that includes Euclidean transformations as well.
Geometric Transformations


(C) 2004..2008 Dmytry Lavrov.
Want to say something or ask some question? Or have some (commercial) job you'd want me to do (CG animation, still images for website design, programming, things like that) ? Contact: .
_