Tell me if I am wrong.
I'm starting using quaternions. Using a rotation matrix 4 x 4 (as used in OpenGL), I can compute model view matrix multiplying the current model view with a rotation matrix. The rotation matrix is derived from the quaternion.
The quaternion is a direction vector (even not normalized) and a rotation angle. Resulted rotation is dependent on the direction vector module and the w quaternion component.
But why I should use quaternions instead of Euler axis/angle notation? The latter is simpler to visualize and to manage...
All information that I found could be synthetized with this beatifull article:
http://en.wikipedia.org/wiki/Rotation_representation
Why it is better to use quaternions is explained in the article.
More compact than the DCM representation and less susceptible to round-off errors
The quaternion elements vary continuously over the unit sphere in R4, (denoted by S3) as the orientation changes, avoiding discontinuous jumps (inherent to three-dimensional parameterizations), this is often referred to as gimbal lock.
Expression of the DCM in terms of quaternion parameters involves no trigonometric functions
It is simple to combine two individual rotations represented as quaternions using a quaternion product
Unlike Euler angles, quaternions don't suffer from gimbal lock.
I disagree that quaternions are easier to visualize, but the main reason for using them is that it's easy to concatenate rotations without "matrix creep".
Quaternions are generally used for calculative simplicity - it's a lot easier (and faster) to do things like composing transformations when using quaternions. To quote the Wikipedia page you linked,
Combining two successive rotations,
each represented by an Euler axis and
angle, is not straightforward, and in
fact does not satisfy the law of
vector addition, which shows that
finite rotations are not really
vectors at all. It is best to employ
the direction cosine matrix (DCM), or
tensor, or quaternion notation,
calculate the product, and then
convert back to Euler axis and angle.
They also do not suffer from a problem common to axis/angle form, gimbal lock.
Quaternions are easier to visualize, manage and create in scenarios where you want to rotate about a particular axis that can be easily calculated. Determining a single rotation angle is much easier than decomposing a rotation into multiple angles.
Corrections to the OP: the vector represents the axis of rotation, not a direction, and the rotation component is the cosine of the half-angle, not the angle itself.
As mentioned, quaternions don't suffer from gimble lock.
For a given rotation, there is exactly one normalized quaternion representation.
There can be several seemingly unrelated axis/angle values that result in the same rotation.
Quaternion rotations can be easily combined.
It is extraordinarily complex to calculate an axis/angle notation that is the cumulation of two other axis/angle rotations.
Floating point numbers have a higher degree of accuracy when representing values between 0.0 and 1.0.
The short answer is that axis/angle notation can initially seem like the most reasonable representation, but in practice quaternions alleviate many problems that axis/angle notation presents.
Related
I was transforming an object with a matrix A using Object3D.applyMatrix4 and I found that at one point it didn't preserve an eigen vector's direction.
So I tried animating interpolation between Identity Matrix I and A and I found this:
How could the transformation be not continuous?
Linear interpolation of rotation matrices isn't mathematically sound. The vectors composing a rotation matrix need to be unit length.. or at least stay a consistent length.
Imagine a clock with a hand at 12, and a hand at 6.
If you Linearly interpolate the point at the tip of the 12 oclock hand, to the tip of the 6oclock hand, the point travels in a straight line from top of the clock to the bottom.
To interpolate the rotation represented by a 4x4 matrix, you can convert the rotations of the matrices, to quaternions, and .slerp (spherical linear interpolate) between those quaternions, then convert back to a matrix.
And then linearly interpolate the object.position. (although again.. this assumes linear motion between keyframes).
Now in the case that the rotation is small, you can get away with linearly interpolating the matrix, but you will need to orthonormalize it at each step, to reshape the mesh into one that has consistent length vectors that are orthogonal to each other. That isn't that hard.. you use a combination of dot products, multiplies and adds of the vectors forming the matrix rows (or columns, i forget) to orthonormalize the matrix. But its more of a pain, and less accurate than just using quaternions and .slerp.
#manthrax 's answer pointed out the fundamental problem of interpolating a matrix linearly which I wasn't aware of at the time and he was right about that. But the real problem was that Object3D.applyMatrix4 wasn't the right function for explicitly defining local matrix. I tried setting Object3D.matrix property directly and it worked. And the linear interpolation (although I shouldn't do that) became continuous.
Why would be difficult to use quaternions for the LBS(Linear Blend Skinning) formula?:
See picture:
Linear Blend Skinning Formula
P': Point transformed
P: Point
wi: matrix of weights
wi(P): weight of point P in entry i
Ti: Transform at i
I couldn't really find an answer, I thought that maybe because a transform matrix can store 4x4 values rather than quaternions which can only represent a rotation in 4 values then we wouldn't have a way to represent both a translation and rotation for any bone using a quaternion but I'm not too sure.
You are absolutely right. The fact that quaternions can only represent rotations (and scalings) makes them unusable for this task. There are extensions to quaternions (dual quaternions) that circumvent this restriction. And then, blending linearly works pretty well.
Also, keep in mind how to transform a point with a quaternion - you have two multiplications instead of one. Therefore, you would usually first blend the quaternions and then transform the point. Although blending the transformed points can be done as well, this makes little sense as it is computational heavier and has the same problems as simple LBS.
Whether or not the question aims at something more is still open.
In most graphics libraries I've seen, there's some function that returns the determinant from 3x3 and 4x4 matrices, but I have no idea when you'd actually need to use the determinant in 3D computer graphics.
What are some examples of using a determinant in 3D graphics programming?
Off the top of my head...
If the determinant is 0 then the matrix cannot be inverted, which can be useful to know.
If the determinant is negative, then objects transformed by the matrix will reversed as if in a mirror (left handedness becomes right handedness and vice-versa)
For 3x3 matrices, the volume of an object will be multiplied by the determinant when it is transformed by the matrix. Knowing this could be useful for determining, for example, the level of detail / number of polygons to use when rendering an object.
In 3D vector graphics
there are used 4x4 homogenuous transform matrices and we need booth direct and inverse matrices which can be computed by (sub)determinants. But for orthogonal matrices there are faster and more accurate methods like
full pseudo inverse matrix.
Many intersection tests use determinants (or can be converted to use them) especially for quadratic equations (ellipsoids,...) for example:
ray and ellipsoid intersection accuracy improvement
as Matt Timmermans suggested you can decide if your matrix is invertible or left/right handed which is useful to detect errors in matrices (accuracy degradation) or porting skeletons in between formats or engines etc.
And I am sure there area lot of other uses for it in vector math (IIRC IGES use them for rotational surfaces, cross product is determinant,...)
The incircle test is a key primitive for computing Voronoi diagrams and Delaunay triangulations. It is given by the sign of a 4x4 determinant.
(picture from https://www.cs.cmu.edu/~quake/robust.html)
I'm wondering if it's possible to define an object's rotation not around itself but around an arbitrary origin, effectively removing the need to pass XYZ position vectors to the GPU. So instead of having XYZ position + XYZW quaternion, we could pre-compute a quaternion that would solely define the object's position and rotation all by itself?
It is not possible with a pure quaternion. A quaternion has only four degrees of freedom. If you use it for transformation, these will be three degrees for rotation and one degree for scaling. There is just nothing more a quaternion can offer.
Dual Quaternions, however, can represent translations (and thus also rotations about arbitrary axes). This comes with the cost of four more numbers to store and usually it is not worth the trouble. The advantage of dual quaternions is that rigid body transforms can be expressed in a consolidated way with a nice algebraic background. It is usually used for animation to interpolate between multiple transforms in a consistent way.
In most cases, the advantages of dual quaternions do not outweigh their complexity. Hence, using a simple offset vector is more reasonable most of the time.
Givens
1- X,y,and Z the world co-ordinate system
2-i,j,k another co-ordinate system.
3-the cosines in which each of i,j, and k make with the X,Y,Z.
problem
how to rotate the i,j,k system about i or j or k??
If you have the cosines of the angles formed by pairing each of i,j,k with each of xhat, yhat, and zhat (nine angles altogether), you have the makings for the direction cosine matrix. For example, see http://www.ae.illinois.edu/~tbretl/ae403/handouts/06-dcm.pdf (or just google direction cosine matrix). The direction cosine matrix is just another name for a transformation or rotation matrix.
Be careful, though!
There is no single standard scheme. You need to know that this is the case and read the literature carefully.
Are you rotating the object or transforming coordinates? Rotation and transformation are conjugate operations. Some people (many people!) use the term 'rotation matrix' when they mean 'transformation matrix', and vice versa.
Do you represent vectors as column vectors or row vectors? Here there is a lot more consistency; most people use column vectors rather than row vectors for things like positions, velocities, etc. BUT there are very good reasons to use row vectors (or column vectors if you are one of those contrarians) for things that properly belong in the dual space.
Quaternions have even more ambiguity of representation than matrices. There's nothing wrong with that (I use quaternions all the time), but you do have to beware of these ambiguities when you read a paper or book, look at someone else's code, or exchange data.
Finally, matrices and quaternions are only two of many charts on SO(3). There are lots of ways to represent rotations in 3-space.
You can first create either a rotation matrix or a quaternion. Then you use that to transform your vectors.
You can find the code to create a rotation matrix or a quaternion in pretty much any 3d maths library.
If I recall correctly you calculated the rotation quaternion as(assuming normalized axis):
q.x=axis.x*sin(alpha)
q.y=axis.y*sin(alpha)
q.y=axis.z*sin(alpha)
q.w=cos(alpha)