4 ms·
Similarly, slerp is also not a property of quaternions [1], contrary to the claim in the article, and is usually not implemented inside quaternion libraries usi
by dahart 5y ago
Similarly, slerp is also not a property of quaternions [1], contrary to the claim in the article, and is usually not implemented inside quaternion libraries using quaternion exponentiation like the article does, but by computing angles explicitly [2], for robustness I believe, and also because slerp is designed for normalized quats, not for general quats with non-unit magnitude.
With these two things combined - the two most commonly cited reasons about why to use quaternions (using slerp and avoiding gimbal lock) - what are other reasons to use quaternions? I’m aware that there are moderate compute savings in some cases (a matrix obviously has more degrees of freedom than a rigid orientation). Are there other good reasons to deal in quaternions? There are some reasonable ideas about why not to use them. [3]
[1] https://en.wikipedia.org/wiki/Slerp#Geometric_Slerp https://en.wikipedia.org/wiki/Slerp#Geometric_Slerp
[2] https://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/index.htm https://www.euclideanspace.com/maths/algebra/realNormedAlgeb...
[3] http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/ http://number-none.com/product/Understanding%20Slerp,%20Then...
- jackling 5y agoI believe that even though slerp isn't a property of quaterions and can be retrieve without them, having your orientation represented as a vector is a clean way for the developer to hold the state of an orientation and interpolate it. What's happening under the hood shouldn't matter much, the abstraction in the code using quaterions makes it easier for the developer to interpolate orientations without the worry of gibal locking.
- dllthomas 5y agoOne reason to accumulate into quaternions vs a matrix is that compounded errors can add scaling and shear to a rotation matrix, whereas unit quaternions remain pure rotation (and non-unit quaternions can be trivially normalized).
- dahart 5y agoThat's reasonable, but compound matrix ops can also re-normalized and re-orthogonalized as they go, right? It's easier with a quat, for sure, but does it make up for the general complications with using quats?
- user-the-name 5y agoI have not seen any complications of using quaternions that would be anywhere near as big as the complications of using any other approach.
- dahart 5y agoThat's why I posted an article that describes what the complications are, reference number [3] above. It's mainly a game-centric and people-centric view of problems with quaternions, not a list of technical problems with the representation. In short, many programmers don't understand quaternions, so using them puts an education burden on the team, a burden that is most frequently un-met. Quats can be less efficient, if you're not paying attention to what you're doing.
- jacobolus 5y agoThe part that is less efficient is applying a rotation to a vector (you need to "sandwich multiply" by your quaternion which involves 3×4 + 4×4 = 28 multiplications, whereas with a matrix you only need 3x3 = 9 multiplications). But composing, interpolating, exponentiating, etc. is a lot nicer with quaternions. (Easier to reason about, numerically better behaved, computationally cheaper.) If you need to apply the same rotation to a large number of separate vectors, keep your rotation representation as a quaternion internally and convert to a matrix just before vector rotation.
- user-the-name 5y agoMany programmers don't understand matrices either. If you're going to be working with 3D engines, some of this stuff you'll just have to sit down and learn.
- user-the-name 5y agoIt is easier to deal with accumulating floating point when using quaternions than when using matrices. Various other operations are also quite easy to express in terms of quaternions, such as swing/twist decomposition.
- klodolph 5y ago> ...not implemented inside quaternion libraries using quaternion exponentiation like the article does, but by computing angles explicitly... How else would you compute quaternion exponentiation? I don't think there's really a dichotomy here. When you compute quaternion exponentiation, one natural way to do it (as with complex numbers) is to think of the quaternions as a real magnitude multiplied by a phase. For complex numbers, the magnitude grows according to exp(x) and the phase evolves according to cos(x)+isin(x). This just falls out of Euler's formula. If you know that the magnitude is 1, you take the exp(x) term out, and you end up with a point that moves in a circle. The same thing applies to quaternions. I'm aware that there are other ways to compute quaternion exponentiation, but this is just a natural way to do it, especially for people who aren't experts in numeric programming.
- dahart 5y agoThe article's quat_pow is implemented using 'quat_exp(quat_scale(quat_log(q), n));' where the code example I posted computes the half-angle of the rotation. If you stand back, I'd agree with you that there's an equivalence here, and it could be argued that Euclideanspace's code example is a kind of simplification and flattening of using an exponentiation function. Still, there are real differences between these two implementations, and the article's here looks conceptually simple, while the one people use in practice looks more complicated, and requires knowing how quaternions works. It's natural if you're fluent in quats, but not necessarily intuitive otherwise.
- klodolph 5y ago> If you stand back, I'd agree with you that there's an equivalence here, and it could be argued that Euclideanspace's code example is a kind of simplification and flattening of using an exponentiation function. You don't have to stand back that far! They're really quite similar pieces of code. quat_log() is basically a conversion to axis-angle. quat_exp() is basically a conversion from axis-angle back to quaternions. So, the quat_exp(t quat_log(x)) formula, with different names for the functions, is described as: 1. Figure out the angle between the starting and ending position, and the axis of rotation. 2. Vary the angle of rotation smoothly from t=0..1. 3. Convert back from axis-angle to an orientation. The only funny thing here is that the axis-angle encoding of quaternions uses a magnitude which a factor of two away from the angle in radians, so you'll see the sample code you linked to (with SLERP) use variables like "halfTheta" and "cosHalfTheta", where the quat_exp() and quat_log() formulas simply won't name them that way. In the end I think the point of learning more math is so you can see past the differences in naming and recognize when two seemingly different approaches to the same problem are really just two different sets of terminology and names for the same approach.