Rediscovering Quaternions(jasonfantl.com) |
Rediscovering Quaternions(jasonfantl.com) |
3blue1brown and Ben Eater did a series of interactive videos on the subject that can be explored:
My favorite demo on this point is this one: https://eater.net/quaternions/video/rotation
Where they have a toggle to go between `a + bi + cj + dk` quaternion notation and an equivalent formulation in terms of 3d orientation vector plus rotation angle as `cos(θ) + sin(θ)*(ai + bj + ck)`
Something's missing. Orientation in 3D space is a two-dimensional quantity; you would never need three dimensions to express it. The third dimension has to be providing some additional information, like a magnitude.
Visualizing quaternions (2018) - https://news.ycombinator.com/item?id=38043644 - Oct 2023 (42 comments)
Visualizing quaternions: an explorable video series (2018) - https://news.ycombinator.com/item?id=31083042 - April 2022 (15 comments)
Visualizing quaternions: An explorable video series - https://news.ycombinator.com/item?id=18310788 - Oct 2018 (32 comments)
IMHO I think for me they're interesting because it felt like mathematically they straddle the line of being nearly impossible for me.
I could just barely do them and felt very accomplished when I could. Anything else was either impossible or easy by comparison.
assuming my maths skills are average here then most people have similar experiences with them.
Edit: just noticed we also have a thread on bifurcation, another big topic in Against the Day.
[Let's remove Quaternions from every 3D Engine] https://marctenbosch.com/quaternions/
(Open access pdf: https://par.nsf.gov/servlets/purl/10098941)
Can you give some pointers to other interesting applications?
This is a bit pedantic - and the blog post actually does clarify this - but the problem isn't that a 3D representation of representations has "discontinuities" as such, it's that it's not orientable in Euclidean 3D space. It is similar to the Klein bottle - the mathematical description is continuous, but any Klein bottle made of real-world glass has to intersect itself. Or likewise that a Mobius strip can be demonstrated in 3D but can't be built in Flatland without a 3D entity doing the copy-pasting. Reality just has the wrong topology to represent the full group of rotations. Hence the discussion about projective space later in the blog post.
So adding a fourth gimbal is really tantamount to a correctly-oriented embedding of 3D rotations onto a 4-torus (that is, [0,2pi]^4).
Gimbal lock also relates to another issue of continuity, related to the "plate dance."[1] Rotations themselves have a sense of continuity (infinitesimal differences in either the angle or axis of rotation, aka they are Lie groups), but Euler angles fail to respect the equivalent fundamental theorem of calculus: adding a bunch of infinitesimal changes might say you are at the identity rotation according to Euler angles, but in reality you have flipped the meaning of the right-hand rule and the overall state of the system is not at the identity. In a robotics context, the robot's hand might have done a complete rotation, but its arm is twisted without the robot "knowing." I believe robotic arms used to have a serious problem with this, either overrotating and breaking the arm, or swinging dangerously fast in the opposite direction. Using quaternions / a fourth gimbal / etc. there would be a measurable phase or pole indicating the true state of the system, and letting the robot know how to rotate its arm without malfunctioning. So, like the Apollo mission, the need for a fourth dimension to keep track of that stuff - and even the quaternion multiplication structure - comes about pretty naturally without ever thinking about abstract math.
I had a much simpler time just using rotation matrices for everything. They're not much more difficult to compose, they're trivial to apply to vectors, and they can be easily understood in terms of their row and column vectors. (For my project in particular, I really enjoyed the property of easily knowing which octants the basis vectors are mapped to.)
Where are the practical areas where quaternions shine? Are they just useful for the slerp operations that everyone points at, or are there other situations where they're better than rotation matrices?
A Quaternion from what I believe is just the same but instead of distance it just encodes the rotation around that direction as a fixed axis. (Instead the angle stored is half etc).
Feel free to correct me if I'm wrong, I'm not a math-heavy person.
The first part kinda makes sense, but I have no idea what the paranthetical is intended to mean.
They are mathematically equivalent, easier to explain, can generalize to higher dimensions, and aren't mocked in the Alice in the Wonderland[2] (famous tea part scene).
[1]https://archive.is/20240820193111/ (mirror of https://marctenbosch.com/quaternions/ )
[2]https://gaupdate.wordpress.com/2011/07/26/quaternions-part-o...
1. "any representation of 3D rotations using only three values"
That is not representation, that is parametrization. Euler-angle parametrization sometimes fails because it is not a correct parameterization of SO(3) in general by construction, this is why it sometimes fails (essentially, the three consecutive rotations can sometimes effectively collapse into two for certain set of angles, regardless of how you choose your 3 axes, in which case you can't relate 2 independent parameters back to the 3 independent axis-angle parameters). The correct parametrization of SO(3) is the axis-angle parametrization, which can be represented using quaternions or 3D reals matrices.
The "representation", on the other hand, would typically be unit quaternions or 3D orthogonal matrices.
2."it can be proven that any representation of 3D rotations using only three values must contain discontinuities." where is that proof and what discontinuity are you talking about? It sound like he misunderstood what "SO(3) is not simply connected" means. Lie groups are differentiable.
3 parameters are sufficient to represent any 3D rotation. The natural parametrization of all Lie groups, including SO(3), is the axis-angle parametrization, and their elements have the form exp(i θ n.J) where n is a unit vector defining the axis of rotation, θ determines the amount of rotation, and J is a vector of the generators of the corresponding Lie algebra. The "regular" 3D matrix representation in the axis-angle parameterization is obtained with so(3) generators L_x, L_y, L_z in their fundamental representation. Basis quaternions i, j, k (which can be represented by Pauli matrices) obey the same Lie algebra as L_x, L_y, L_z, but the group that it corresponds to (which is SU(2)) is a double cover of SO(3) (up to a sign), so they can still be used for implementing 3D rotations once you pick a sign.
Think of matrices as computational instructions, which are straightforward but lossy, while quaternions are the canonical "lossless representations".
The sweet spot for using quaternions is to use them as intermediate representations of rotation operations, then "compile" them down to a matrix once you are gonna apply it to a vector.
ijkl_as_matrix = {
(ll+ii)-(jj+kk), (ij+ji)-(lk+kl), (ki+ik)+(lj+jl),
(ij+ji)+(lk+kl), (ll+jj)-(kk+ii), (jk+kj)-(li+il),
(ki+ik)-(lj+jl), (jk+kj)+(li+il), (ll+kk)-(ii+jj),
};
(Keep in mind that unnormalized quaternion has uniform scaling, so if your quats are unnormalized then your matrix will also apply a scale factor of dot(q,q), so you should divide your final vertex coords by that factor.)---
[0] For an example, see https://old.reddit.com/gdd8op
(Luckily, for my project, I'm not particularly worried about error, since the only thing being rotated frequently is the camera, and microscopic scaling and shearing won't affect the result much. I measured the error in the basis vectors over time to make sure, and it just seems to be O(sqrt(t)) random-walk noise, not anything that compounds on itself.)
[0] https://www.tobynorris.com/work/prog/csharp/quatview/help/or...
A better word than lossless is perhaps ‘overspecified’ when referring to a 3x3 matrix being used to represent a rotation or orientation. A 3x3 matrix has redundant information in that case (however a matrix is more general and more powerful than a quat). But axis-angle is 4D like a quat too, and more intuitive than a quaternion. Actually normalized-axis-angle (with no scaling) can beat normalized quats, because axis-angle can be a 3D value and quats cannot. Same goes for Euler angles too. In general, if your quats are implemented with floats then applying quat transforms will introduce unwanted floating point scaling that may accumulate under repeated operations (and if you compile to a matrix first then you also have the matrix problem you mentioned).
If you’re interested in seeing their approach, here’s the repo:
It's mostly for the same reasons everyone else mentioned, simplifying interpolation and avoiding gimbal lock. I also found the actual operations much easier to implement. I never developed a good mental model of what they actually are, but tried not to let that bother me too much.
It can have other uses for things like inverse kinematics too.
At least for a simple camera I've done that with something that resembled a spherical coordinate system (although maybe not following the usual conventions) and it didn't experience gimbal lock. Effectively the axes rotate with you. It's also very intuitive to work with the code, although probably not very efficient compared to other approaches (but hey it's a camera it's not like there's 10k of them). Once you have the camera orientation you can derive a corresponding rotation matrix to apply to the scene geometry.
I guess what I'm trying to ask is if there's any reason other than efficiency not to do something like that when modeling craft and the like?
https://www.quantamagazine.org/the-octonion-math-that-could-...
Also see the work of John Baez:
html https://math.ucr.edu/home/baez/octonions/octonions.html
Drifts in quats results in a drifted value of rotation + uniform scaling, but will never introduce deformation.
Drifts in matrices may result in total mutilation of your coordinates.
The overdetermined nature of matrices with respect to orthogonal transforms means that you lose information about which values constitute the authoritative state, whereas it is by definition impossible for a quat not to be orthogonal even when perturbed with significant error.
As an analogy, think of matrices as retained-mode GUI while quats are immediate-mode.
2. Axis angle is just the logarithm of [unit]quats (non-unit quat adds an additional scalar to the axis-angle components).
If you want to compose rotations sequentially, you'll still need to take the exponential of axis-angle to turn it into quats.
You can author initial state in axis angles as an authoritative declaration of what you meant for the orientation to be, but composing them still invariably requires you to un-logarithm them back to quats, hence what I said about "intermediate representation"
3. I said compile to a matrix at the very end when transforming the final vertices, entirely sidestepping the problem of repeated operations since you're only "baking" it for the final transformation onto vertices.
EDIT: I guess if you use a shitty overzealously reduced version of the quaternion formula then you absolutely need to normalize it constantly, because the reduced formula assumed three degrees of freedom (completely defeating the purpose of using quats in the first place), normalization is then to solve a problem that you caused. But if you use a proper formula then my recommendation is actually that you never normalize your quats, instead only un-scale your vertex at the end.
q = cos(0) + sin(0)*(ai+bj+ck) = 1 + 0 = 1
That means applying the "rotation" to the vector gives v' = q * v * q^-1 = 1 * v * 1^-1 = v
So the output ("rotated") vector is the same as the input, as you would expect for a rotation by 0.> Only if you’re describing orientation as two orthogonal rotations.
No, the space has the dimensionality it has. You may choose to describe a 3D orientation with more than two numbers, but you won't stop it from being a two-dimensional quantity that way. If you use more than two numbers, those numbers will fail to be independent of each other.
Your comment is essentially correct if you replace the word "orientation" with "direction", though.
But I agree it is helpful to think of quaternions as direction and spin.
Future user control inputs (ie a 4th rotation step) happen in this rotated space, and then you normalize the result so you only ever need 3 instead of 4 rotations.
It's been several years since I did this so hopefully I didn't mess up the explanation. Again I realize it isn't computationally efficient but there's only the one camera and it let me have code that was minimal and easy to reason about. Presumably if I were simulating 10k airplanes or whatever this wouldn't be a good idea.
This was fine for some things. but if you wanted something to rotate but only in a certain way it was annoying as sometimes it would get from A to B, but go through Z during its rotation.
Getting the order or multiplications right too.
For levity, see Acts 12:4 And when he had apprehended him, he put him in prison, and delivered him to four quaternions of soldiers to keep him.