[HN Gopher] Rotations with quaternions
___________________________________________________________________
Rotations with quaternions
Author : imadr
Score : 159 points
Date : 2021-06-01 12:03 UTC (10 hours ago)
(HTM) web link (imadr.github.io)
(TXT) w3m dump (imadr.github.io)
| greggman3 wrote:
| Be aware, quaternions are not always the right solution. There's
| a reason Unity, Unreal, 3DSMax, Maya, Blender, etc all support
| Euler interpolation in animation. A simple example is an artist
| might want to show a clock hand spinning fast to show the
| progress of time. To do that they set a start angle of 0 and an
| end angle of say 20000. Sure, there may be ways to represent that
| with specialized quaternions but in general the 3D tools all
| seems to default to using Eulers.
|
| This is an issue with the GLTF format. They chose quaternions to
| represent rotations in animation and as such can't easily
| represent what the artist's intent was.
|
| You might claim you can sample the Euler animation and split it
| into multiple quaternion slerps but that brings up another issue
| which is you need support for discontinuous animations in order
| to handle other situations (another thing the GLTF format
| apparently didn't consider).
| klodolph wrote:
| Quaternions _usually_ match artist 's intent, and Euler angles
| usually don't. glTF isn't alone in using quaternions. I did a
| bunch of FBX imports a while back all the orientation channels
| are just quaternions. It makes sense, because it's _one natural
| way_ to interpolate rotation data, just based on the
| orientations of bones during the keyframes. The kind of stuff
| that you interpolate using Euler angles is going to be stuff
| that is naturally on gimbals, like cameras, tanks, robots,
| turrets, and stuff like that. You can do that easily enough by
| adding another node to your transform hierarchy with
| quaternions, but if you started off with Euler angles, you don
| 't really have a way to back out.
|
| Quaternions are not always right, but they are the right
| default. If you want Euler angles, you can always translate to-
| from quaternions. Quaternions are independent of the way you
| set up the coordinate system and each axis is equal.
|
| Unity, for example, uses quaternions internally. It exposes
| getters and setters for Euler angles that do the conversion
| to/from quaternions as a convenience. The editor edits Euler
| angles but they disappear as soon as you are in-game, and if
| you open up your scene file in a text editor, you'll see
| m_LocalRotation with the x/y/z/w of a quaternion. I believe
| Unreal is the same way.
|
| Honestly, that just makes too much sense. Trying to do a
| physics simulation with Euler angles is just adding extra
| steps, because Euler angles are not easily composable. If you
| want to compose two Euler angles to get a third, the easy way
| to do it is to convert to quaternions, multiply, and then
| convert back to euler angles. You can see Euler angles in the
| editor when you are animating a model, but most of the time you
| are just dragging stuff around on screen or matching mocap data
| and quaternions make 100x more sense than Euler angles for
| representing that stuff.
|
| My sense is that any code which does a lot of trig, when
| there's an obvious way to write the code that does no trig,
| should probably be rewritten to eliminate the trig. A little
| bit of sin/cos/tan is fine but as soon as you are doing round
| trips with acos/asin/atan, you have to start considering where
| the branch cuts are.
| greggman3 wrote:
| Unity uses quaternions in the rotation but the actual
| animation curves are still interpolating Euler angles. Same
| with Unreal, Maya, 3DSMax, Blender etc... GLTF requires you
| to convert the animation curves to quaternions. That's a
| lossy operation
| jonas21 wrote:
| Yeah, I think any time you need to interface with a human,
| Euler angles are better because they're more intuitive. There's
| a good reason aircraft instruments display things in Euler
| angles, for example.
| sillysaurusx wrote:
| "Why not both?"
| mottosso wrote:
| Yes, exactly. The article even points this out:
|
| > However writing a rotation directly in quaternion form
| isn't really intuitive, what we do instead is convert an
| Euler angle to a quaternion then use it for rotating.
| Animats wrote:
| For a simpler discussion, see [1].
|
| [1] http://wiki.secondlife.com/wiki/Rotation
| FabHK wrote:
| A few remarks:
|
| 0) Very nice practical introduction to quaternions and their
| application to rotation.
|
| 1) Neat didactic "textbook" implementation, but note that it is
| not production quality (eg potential overflow in the norm
| function unnecessarily). That was not the aim, either, but just
| something to bear in mind.
|
| 2) As a supplement, a useful practical reference for rotations in
| 3D (with good clarifications and basically all formulae you'll
| ever need, but no implementation) is
|
| _Representing Attitude: Euler Angles, Unit Quaternions, and
| Rotation Vectors_ by James Diebel
|
| https://www.astro.rug.nl/software/kapteyn-beta/_downloads/at...
| tbabb wrote:
| What would you do differently with the norm function?
| hanche wrote:
| To compute a norm without overflow (unless it is totally
| unavoidable), let m be the maximum of the absolute values of
| the components. Divide each component by m, compute the
| square root of the sum of squares, and multiply by m. Only
| the last step might overflow, and if it does, it could not be
| avoided in any case. Incidentally, this normalization
| procedure also avoids underflow problems.
| tbabb wrote:
| I see. I'd say it depends what the application is, then,
| because in graphics correctly handling (unlikely) extreme
| values would be quite secondary to performance, especially
| for an inner loop function like norm. See fastinvsqrt,
| e.g., which is extremely imprecise!
| FabHK wrote:
| Absolutely, I should've been more precise: it's perfectly
| fine for most applications, but not for a library, or,
| say, manned aviation. So, yeah, when optimising for
| accuracy, range, or speed you might implement it
| differently, respectively.
|
| I mean, papers have been written about sqrt(a^2+b^2)
| alone... :-)
|
| https://arxiv.org/abs/1904.09481
| hanche wrote:
| In many applications there is definitely no reason to
| worry about overflow when computing norms. That is more
| of an issue if you are writing library code for general
| use, which should be as robust as you can make it.
| xscott wrote:
| The hypot() function avoids many overflow and underflow
| cases: return hypot(hypot(q.w, q.x),
| hypot(q.y, q.z));
| tbabb wrote:
| Interestingly, with clang and -O3 I get identical assembly
| for hypot() and the "naive" implementation.
| [deleted]
| captainmuon wrote:
| > A quaternion is basically a 4 dimensional vector, so it has a
| magnitude (or norm, or length)
|
| Is it really a _vector_ in the physical sense? People often say
| vector when they mean N-tuple -- for example we learned in high
| school that vectors are just N numbers taken together.
|
| For physicists, a vector must satisfy certain transformation laws
| - it must transform in the correct way if a rotation is applied,
| and the scalar product must be invariant of the coordinate
| system, IIRC. I don't have enough intuition of quaternions to say
| how they behave under transformations, though. I would be
| surprized if you could have "proper" vectors with four components
| in three-dimensional space.
| littlestymaar wrote:
| A vector is a member of a vector space. A vector space is a set
| _V_ + a Field _F_ , where for all _x_ , _y_ in _V_ and _a_ in
| _F_ , _x + ay_ is also in V. That 's it.
| marosgrego wrote:
| It's a vector in the mathematical sense.
| foo92691 wrote:
| Well, quaternions form a vector space over quaternion
| addition. This part is not very interesting. Vector spaces do
| not describe multiplication of vectors by each other. So,
| quaternions are _not_ (only) vectors "in the mathematical
| sense" when it comes to their more interesting properties.
| marosgrego wrote:
| What do you mean? They also form an algebra (a vector space
| where a "multiplication" is defined).
| vladTheInhaler wrote:
| For anyone who is interested in an accessible introduction to
| representing rotations, I highly recommend this site:
| https://rotations.berkeley.edu. One of my professors provided it
| for one of his courses, and it's been a really helpful reference
| several times since then.
| iab wrote:
| That's a great resource, thank you
| gspr wrote:
| The reason this works is often skipped in computationally
| oriented writeups:
|
| Rotations of 3-dimensional real space form the topological group
| SO(3). Naive parameterizations of that group do not form a cover
| [1], but the group of norm-1 quaterinons, Spin(3), does.
|
| The failure of naive parameterizations, like the Euler angles, to
| be a cover manifests itself as gimbal lock.
|
| [1] https://en.wikipedia.org/wiki/Covering_space
| rnhmjoj wrote:
| Technically the unit quaterions are not Spin(3), but only
| isomorphic to it, they are properly Sp(1) = GL(1, H). It's all
| fuzzy because the low dimensional classical groups are all
| isomorphic to each other: SU(2) ~ Sp(1) ~ Spin(3).
| tobinfricke wrote:
| > Technically X is not Y, but only isomorphic to it
|
| Not sure this is a useful argument. If two structures are
| isomorphic, there is no way to tell them apart. If you can't
| tell them apart - maybe they are the same thing.
| gspr wrote:
| Indeed.
| jacobolus wrote:
| This seems extraordinarily nitpicky. Like saying that unit
| complex numbers are technically not the group of plane
| rotations about a fixed point, but only isomorphic to it. Or
| for that matter like saying that the "real number line" is
| technically not a line, but only isomorphic to one.
| rnhmjoj wrote:
| Well yeah, it is. The point I wanted to make is that these
| isomorphism are "exceptional"[1] and only hold for the
| lower dimensional groups. The general Spin group and
| quaterions are very different objects.
|
| [1]: https://en.wikipedia.org/wiki/Exceptional_isomorphism
| joppy wrote:
| That really depends on how you define Spin(3), for example
| some would define it as the compact simply-connected Lie
| group of a certain type, at which point the unit quaternions
| model of Spin(3) is as good as any other.
| GolDDranks wrote:
| Here's a similar argument from my naive, intuition-based
| perspective:
|
| It's important to remember that the the group of rotations in
| 3d space is represented by _unit_ quaternions. This is a subset
| of the full 4d quaternion space: a spherical shell around the
| origin, like the skin of a 3d ball but in 4d.
|
| A 3d ball has a 2d, "flat" skin that is "spherically"
| symmetric.
|
| A 4d ball has a 3d, "volumetric" skin that is, similarly,
| "spherically" symmetric.
|
| If we are stuck to that 3d skin, it makes perfect sense that it
| manages to represent rotations in 3d, which have 3 degrees of
| freedom and spherical symmetry.
|
| The space of rotations that is formed by this "skin" has two
| special points: the point where all the imaginary coordinates
| are zero and the real coordinate is one, and it's dual, the
| negative one, precisely because we are talking about _unit_
| quaternions. (Similarly as there is only two "purely x" points
| in a unit circle: (1, 0) and (-1, 0)).
|
| These points represent the identity rotation, i.e. "don't
| rotate at all". This makes sense, if you think how complex
| numbers work: the effect of multiplying "one" is that it keeps
| everything as-is, whereas every other "unit" complex number has
| a rotating effect.
|
| Then as you think the three imaginary dimensions as degrees of
| freedoms you can start traveling into, from this neutral point,
| you get all kinds of rotations. The geometry of the "round",
| "skin-shaped" space ensures that the rotations wrap around the
| correct way, "spherically". Especially that after you have
| travelled "tau" (2 times pi) units, you are again in purely
| "real", "not rotated" state. And the spherical symmetry means
| that this works similarly in _any_ direction you can travel to.
|
| The only gotcha is that the unit quaternion space contains
| doubly the space of minimal 3d rotations, because of the
| negative number symmetry. There's some good arguments why this
| is especially beautiful and true, but they are a bit beyond me.
| hanche wrote:
| There is a nice experiment you can do, illustrating this:
| Hold a glass of water in the palm of your hand. Not too full,
| especially not until you get the hang of the following move:
| Assuming you use your right hand, rotate your hand
| counterclockwise. At first, your hand goes under your arm,
| until it has rotated about 270 degrees or so. You can now
| continue that rotation, but you have to lift your hand up, so
| it is now above the arm. Keep going, and you end up where you
| started, but the glass has done two full revolutions.
| Hopefully without spilling an water (takes practice). The fun
| thing is, after just one revolution, your arm is twisted into
| a really uncomfortable configuration.
|
| The mathematical explanation is that SO(3) is doubly
| connected, whereas the unit quaternions, like any sphere, is
| simply connected. At any time, each part of your arm has
| undergone some rotation from the orientation at rest. Halfway
| through the move, as you travel from the shoulder down to the
| hand, this rotation starts at the identity, and changes
| continuously through one rotation, back to the identity once
| more. But in the unit quaternions, that path takes you from
| one pole to the opposite pole. This explains why you can't
| untwist your arm.
|
| Sorry if that made no sense.
|
| Edit: Have a look at "Your palm is a spinor" [1], and then at
| this Phillipine* tradtional dance [2] about 40 seconds in. I
| knew I had written about this before [3].
|
| [1] https://www.youtube.com/watch?v=fTlbVLGBm3Q
|
| [2] https://www.youtube.com/watch?v=mOO_IQznZCQ
|
| [3] https://math.stackexchange.com/a/383549
|
| * I wrote Thai originally.
| hanche wrote:
| I know what you mean, but I would hesitate to call Euler angles
| naive. ;-)
| an1sotropy wrote:
| Speaking of gimbal lock - it was a real (as opposed to only
| theoretical/mathematical) concern for navigation during the
| Apollo 11 moon landing [1].
|
| Euler angles are fugly and annoying. Quarternions are clean and
| refreshing.
|
| [1] https://apollo11space.com/apollo-and-gimbal-lock/
| imadr wrote:
| How far into algebra do you need to get to understand
| "Rotations of 3-dimensional real space form the topological
| group SO(3)"? I kinda understand that norm-1 quaternions map to
| rotations in 3D space somehow but I can't prove it myself. What
| kind of curriculum do I need to follow to really grasp this?
| gspr wrote:
| To understand the definitions and apply them in practice, a
| first course in group theory + a basic understanding of
| vector calculus suffices. To add the adjective "topology",
| the first parts of a general topology course is enough.
|
| To truly appreciate groups like SO(3), a course in
| differential geometry and differential topology is useful.
|
| Edit: This is all assuming you have no background in
| mathematics (or, alternatively, physics) at all. If you do, a
| targeted text can teach you these concepts in a few pages.
| billfruit wrote:
| The thing is group theory is taught in an incredibly
| abstract manner, its hard to find any motivating
| application for it, or any problems it helps us solve.
|
| Also terminology/definitions are vague too, whether a
| vector has an endpoint or it something unachored in space
| is itself not clear from many treatments.
| swiley wrote:
| That's an odd complaint to hear on a technology centered
| forum.
|
| The most obvious application for algebra should be
| thinking about data structures with their operations. If
| you can't be sure about a method on a class being valid
| in terms of the contracts for that class (IE being a
| closed operation) then the method can't be public
| (usually an idea taught in "intro to OOP" style classes
| although with other words unless you're reading something
| like SICP.)
| klodolph wrote:
| Some of the motivating examples are hard to understand,
| unfortunately. You can't do quantum mechanics without
| group theory, and if you can't do quantum mechanics, it
| will be much harder to understand how half the
| instrumentation in your chemistry lab works.
| gspr wrote:
| > The thing is group theory is taught in an incredibly
| abstract manner, its hard to find any motivating
| application for it, or any problems it helps us solve.
|
| Mathematics is abstractly defined. But for basic group
| theory there's a plentitude of very concrete examples to
| rely on.
|
| > Also terminology/definitions are vague too,
|
| Absolutely not. There is no vagueness at all! Everything
| is completely well-defined in most introductory
| textbooks/courses (or you can even read the precise
| definitions on Wikipedia, which is often not the case).
|
| > whether a vector has an endpoint or it something
| unachored in space is itself not clear from many
| treatments.
|
| Vectors do not have endpoints. Vectors are not anchored.
| Vectors are elements of vector spaces. Vector spaces are
| completely clearly defined.
| jcora wrote:
| Sounds snarky but completely correct. Parent should look
| for a more diverse set of examples for vector spaces. In
| fact sounds like a good linear algebra course would be a
| priority over group theory
| immmmmm wrote:
| it's actually more group representation theory you'll
| need: the rotation group has an infinite number of
| representations acting on different vectors spaces,
| rotation of an electron in 3d is SU(2) which maps to
| SO(3), the rotation of vectors.
| meiji163 wrote:
| You can get a very good intuition with 3B1B's video (
| https://www.youtube.com/watch?v=zjMuIxRvygQ )
| rikroots wrote:
| I failed advanced math (UK A level) and dumped advanced
| physics before reaching the point of taking the exams. I've
| managed to implement a quaternion system in my canvas
| library[1] - with nagging doubts that it's not entirely right
| - mainly by staring at lots of (poorly explained) examples
| online and hoping that things would click 'by osmosis'. So, I
| reckon you can go a long way without understanding the
| concepts behind quaternions, but you'll need to do a lot of
| geometry and physics study if you ever want to feel
| comfortable with any quaternion code you write.
|
| The only reason I went through all that pain was because I
| kept on coming across articles saying that "quaternions fix
| the gimbal lock issue you encounter with Euler angles" - now
| I see people saying in this thread that the assertion is
| false. I no longer know what to believe, but I do know I
| never want to go crawling down the Euler/quaternion rabbit
| hole again!
|
| [1] - https://scrawl-v8.rikweb.org.uk/docs/source/factory/qua
| terni... - just looking at that code makes me wince!
| jacobolus wrote:
| Start by reading
| http://geocalc.clas.asu.edu/pdf/OerstedMedalLecture.pdf
| gspr wrote:
| It's a good text, but the parent poster may wish to be made
| aware that it's very physics-centric. If they do not come
| at this from an interest in physics or a physics mindset,
| it may be counterproductive.
| blovescoffee wrote:
| This is really interesting. Why does the failure of naive
| parameterizations to form a cover imply a group with gimbal
| lock? I'm unclear on how a cover is linked to gimbal lock.
|
| I've taken undergrad topology and algebra if you could explain
| in those terms (I understand what a covering is).
| quietbritishjim wrote:
| You're definitely right to bring up Gimbal lock [1]
|
| One of the benefits of knowing about it is to know when it
| _doesn 't_ matter to you. In that case, you can just use Euler
| angles, as you say. If you just need to express a rotation in
| terms of three angles, or convert back from three angles (e.g.
| yaw/pitch/roll [2]) to a rotation matrix, then you don't need
| to know about quartertonians at all.
|
| [1] https://en.wikipedia.org/wiki/Gimbal_lock
|
| [2] https://en.wikipedia.org/wiki/Aircraft_principal_axes
| gspr wrote:
| Even in this case you need to take care of the action of
| rotations on points near the poles, don't you? (I don't
| remember, it's been a long time since I did such
| calculations).
|
| But yes, otherwise I agree with you.
| gilbetron wrote:
| If you are going to apply 3 angles directly, then you run
| into problems (specifically, if you pitch +/- 90 degrees,
| then roll and yaw become the same thing, aka gimbal lock).
| If you take those 3 angles and convert them to a matrix,
| and use that matrix to apply the angles, you're all good.
| You can then even take the new matrix and pull 3 angles out
| of that.
| toxik wrote:
| ... and those three angles will be discontinuous at the
| poles.
| Jyaif wrote:
| Most of the time you don't want to use his SLERP function. You
| can even see what is wrong in his illustration video: the cube
| does 3/4s of a full rotation, while only 1/4 of a full rotation
| would have been sufficient. In other words, it's not always
| taking the shortest path between 2 rotations.
|
| If you are not careful, this is what you may end up with:
| https://www.reddit.com/r/FIFA/comments/9gms3n/most_realistic...
| imadr wrote:
| What would be the alternative to slerp that takes the shortest
| path?
| edflsafoiewq wrote:
| Just replace q2 with -q2 if q1 and q2 are in opposite
| hemispheres, then slerp.
| imadr wrote:
| If I'm not wrong you check if q1 and q2 are in opposite
| hemispheres with the sign of their dot product?
| edflsafoiewq wrote:
| Yes.
| Scene_Cast2 wrote:
| As a much more intuitive version of quaternions, there's
| Geometric Algebra (aka Clifford Algebra). In 4D, the calculations
| end up being the same, but there's much more intuition and
| generalizability behind the Geometric version.
| OmarShehata wrote:
| This article incorrectly states that gimbal lock is a property of
| Euler angles, and that using quaternions prevents it.
|
| This is a common misconception.
|
| Euler angles can be used to rotate an object exactly the same way
| as quaternions do with no gimbal lock. Similarly, you can apply
| quaternions in such a way that gimbal lock will happen (if you
| wanted to represent a physical system of gimbals with
| quaternions, where that is a physical property).
|
| I wrote a short article demonstrating and clarifying this, hope
| it helps: https://omar-shehata.medium.com/how-to-fix-gimbal-lock-
| in-n-...
| DecoPerson wrote:
| I was hoping your article would example how gimbal lock can
| occur with quaternions, but from a quick skim I can't see any
| such paragraph.
|
| Would you mind elaborating?
| OmarShehata wrote:
| It's at the bottom of the "What causes gimbal lock?" section,
| the final code snippet:
|
| ``` rotationAroundX = Quaternion.fromAxisAngle(angle1,
| Xaxis); rotationAroundY = Quaternion.fromAxisAngle(angle2,
| Yaxis); rotationAroundZ = Quaternion.fromAxisAngle(angle3,
| Zaxis);
|
| cubeRotation = rotationAroundX * rotationAroundY *
| rotationAroundZ; ```
|
| Basically, you store 3 quaternions, representing 3 angles,
| and combine them to get the final rotation.
|
| You might say "This is just quaternions emulating Euler
| angles!" and my answer is, sure. You can say the same about
| rotation matrices. There's nothing inherent about rotation
| matrices that makes them susceptible to gimbal lock. You can
| implement them as representing 3 fixed angles, thus gimbal
| lock, or you can implement them as accumulating rotations,
| thus no gimbal lock. Same is true of quaternions.
|
| The fact that you can get gimbal lock with quaternions is a
| feature, not a bug. Quaternions are just one way to describe
| rotations. Gimbal lock is a natural phenomenon of certain
| physical rotation systems, and can be described whether you
| use quaternions, or matrices etc.
| imadr wrote:
| Thanks for the heads up, I'm going to rephrase the statement
| about gimbal lock and link you article.
|
| And just to be 100% sure, is the approach I'm using the right
| one: storing a quaternion instead of 3 angles, multiplying,
| overwriting the rotation value?
| greggman3 wrote:
| Something else to be aware of
|
| http://number-
| none.com/product/Understanding%20Slerp,%20Then...
| OmarShehata wrote:
| Yes, exactly!
|
| And the idea is, _that's_ how you avoid gimbal lock. It's
| that implementation of multiplying, and overwriting, which
| can be done with any system that describes and applies
| rotation, including Euler angles, rotation matrices, etc.
| dahart wrote:
| 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
|
| [2]
| https://www.euclideanspace.com/maths/algebra/realNormedAlgeb...
|
| [3] http://number-
| none.com/product/Understanding%20Slerp,%20Then...
| user-the-name wrote:
| It 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.
| dllthomas wrote:
| One 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 wrote:
| That'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 wrote:
| I have not seen any complications of using quaternions
| that would be anywhere near as big as the complications
| of using any other approach.
| dahart wrote:
| That'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 wrote:
| The part that is less efficient is applying a rotation to
| a vector (you need to "sandwich multiply" by your
| quaternion which involves 3x4 + 4x4 = 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.
| jackling wrote:
| I 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.
| klodolph wrote:
| > ...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 wrote:
| The 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 wrote:
| > 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.
| dahart wrote:
| You're right and it's a great point!
| Ono-Sendai wrote:
| If you want to represent different rotations as differential
| Euler angles, then I think you can say it's a property of Euler
| angles, or at least linked to them.
| jayd16 wrote:
| Are you simply saying that quaternions can be used to perform
| the same rotation as the Euler method or are you saying that
| the rotation information along the Euler axes can also be lost
| even when using the quaternion method?
|
| Said another way, are you conflating gimbal lock the physical
| property, with gimbal lock the common bug of creating
| irreversible rotations or is the bug still possible?
| hanche wrote:
| Here's an abstract view regarding the inevitability of gimbal
| lock: The state of a single gimbal is described by an angle.
| Since angles are mod 360deg, that is topologically a circle.
| The state of three gimbals are then given by three angles. One
| point on each of three circles is a point on a three-
| dimensional torus T^3. With no gimbal lock, you get a map from
| T^3 to SO(3), which is locally a diffeomorphism at every point.
| For topological reasons, no such map exists: Due to
| compactness, it would be a cover, but the only covers of SO(3)
| are SO(3) itself (a single cover) and the three-sphere (unit
| quaternions, a double cover). And T^3 is distinct from either
| of these two. Hence gimbal lock is unavoidable with three
| gimbals. (Four gimbals is a different story, but then you have
| a redundant dimension to play with.)
| anon_tor_12345 wrote:
| lol i'm a dummy for never realizing that SO(3) isn't
| homeomorphic (the diffeo part isn't necessary to prove
| this...) to T^3 (which i naively thought because s in SO(3)
| seemingly has 3 free parameters). surprise surprise SO(3) is
| actually homeomorphic to P^3 lol.
| hanche wrote:
| You can drop "seemingly": SO(3) is indeed tree-dimensional.
| And SO(3) a.k.a. P^3 has fundamental group Z_2 a.k.a.
| GF(2), whereas T^3 has fundamental group Z^3, so they are
| quite different beasts indeed.
| benrbray wrote:
| Howdy 4ur :) Nice article, I'm pretty sure I got dinged once
| for making this point in a job interview, so good to see you
| spreading the word.
| OmarShehata wrote:
| Oh hey!! Always a pleasure running into familiar faces from
| NG out in the wild :)
|
| And that's funny...I had the exact same experience in a job
| interview...which gave me the extra motivation I needed to
| finally write that up!
| IshKebab wrote:
| Great article. Presumably the reason this confusing exists
| exists is that people don't want to store full rotation
| matrices, so their choices are Euler angles or quaternions, and
| Euler angles _guarantee_ gimbal lock by quaternions allow you
| to avoid it. Is that right?
| zemnmez wrote:
| I'm so confused. The article you wrote says that you fix gimbal
| lock by using quaternion rotation, quote:
|
| >To fix gimbal lock, we must avoid modelling this physical
| gimbal system.
|
| > In 3D, instead of using 3 fixed angles that we multiply
| together to get the final rotation, we will:
|
| > 1. Construct a quaternion that describes a rotation around
| whatever axis we want, and the angle to rotate by.
| rthomas6 wrote:
| As a non-math person, I've thought a lot about quaternions and
| why they need 4 dimensions, and why there aren't 3d complex
| numbers. It's because if you think about it, on the complex
| plane, the imaginary number i just represents a rotation of 90
| degrees. Now if you think about a 3d space, i represents a
| rotation across one dimension, and j represents a rotation across
| another dimension. But how do you rotate from i to j? You can't
| without another number k.
| hanche wrote:
| Hamilton famously had the same problem before he came up with
| the quaternions.
| [deleted]
| imadr wrote:
| I made this guide on how to implement quaternions yourself and
| use them to rotate objects in a 3D engine. The implementation is
| probably not the most efficient, but I tried to make it simple
| enough to understand how quaternions work.
| KboPAacDA3 wrote:
| Thank you for making this and getting straight to the useful
| code. Too often, guides on quaternions stray into proofs and
| waste time for a programmer who just wants to apply the
| quaternion concept.
| darkstarsys wrote:
| This is good, thanks. But a much more interesting problem I
| haven't seen a good writeup for is how to interpolate smoothly
| between quaternions at different times. Quaternion slerp has
| jerks (C_0 but not C_1 or C_2) at the keyframes.
| dahart wrote:
| Ken Shoemake's 1985 Siggraph paper "Animation Rotation with
| Quaternion Curves", that brought quaternions to computer
| graphics, covered this. The idea is to use quaternions as
| control points in a spline the same way you would use 3d points
| in a spline. You could have a series of quaternion
| orientations, and connect them with C_2 continuity by using a
| connected series of piecewise cubic Bezier splines.
|
| The abstract mentions it: "This paper gives one answer by
| presenting a new kind of spline curve, created on a sphere,
| suitable for smoothly in-hetweening (i.e. interpolating)
| sequences of arbitrary rotations." And the final punch line is
| section 4.3, then you can work through the details in the
| earlier sections.
|
| https://www.cs.cmu.edu/~kiranb/animation/p245-shoemake.pdf
| gilbetron wrote:
| It's been a while for me, but iirc, there's two ways you can
| slerp between two quaternions, and by using the shortest path,
| you can avoid the jerk.
| chombier wrote:
| I've used "A General Construction Scheme for Unit Quaternion
| Curveswith Simple High Order Derivatives" in the past, and
| while not perfect it was generally good enough and fairly easy
| to implement.
|
| Basically it extends Hermite splines to Quaternion splines
| using the Lie group operations.
| aardvark179 wrote:
| Since this will get posted here anyway I'll just get it done now.
| https://marctenbosch.com/quaternions/
|
| I don't entirely agree with the article's viewpoint that people
| do not perfectly understand quaternions and therefore they should
| not be used, as I get the feeling there are many parts of 3D
| graphics that are not perfectly understood by developers, and
| that's okay.
| marosgrego wrote:
| The Geometric Algebra viewpoint is much nicer, more natural and
| encompasses more.
| ww520 wrote:
| Quaternion is great for dealing with 3D rotation. Another great
| approach is using the rotor in geometric algebra. It's pretty
| simple and it works on rotation in dimensions higher than 3D as
| well.
| sojuz151 wrote:
| Small trivia: Existence of two unit quaternions corresponding to
| the same rotation is the same thing as the fact that an electron
| must be fully rotated twice before it has the same configuration
| as when it started.
| marosgrego wrote:
| How?
| unholiness wrote:
| If you want to intuitively understand _why_ this particular 4D
| construction is the right representation of a 3D rotation, then I
| highly recommend 3blue1brown 's explorable interactive video
| series on the topic:
|
| https://eater.net/quaternions
|
| The interactive videos alone are quite the technical feat, but
| after going through it, it's honestly hard to imagine fully
| understanding this topic with less technology (or with a less
| incredible teacher!)
| nighthawk454 wrote:
| In particular, that toggle switch to show it in terms of an
| angle makes it super clear.
|
| The 4 components can be re-written in terms of 3 variables for
| an orientation vector and 1 variable for rotation about that
| axis. Basically "point this way and rotate this much". The 4
| variables are expressed as two complex numbers.
|
| That helped me understand what the quaternions are actually
| describing. Incidentally, it also kind of explains why 3
| variables isn't enough, and so the regular rotation thing must
| not be sufficient.
| dnautics wrote:
| am I wrong that this use of a union is UB in C?
| imadr wrote:
| I'm absolutely not a pro in C, so if it is undefined behaviour
| I'd be glad to know and fix it, I just found out about the
| notation and it looks handy
| dnautics wrote:
| checked myself. My cursory, poor search suggests it's UB in
| C++, but not in C?
| steerablesafe wrote:
| It is definitely UB in C++ and probably implementation
| defined in C (and this use is fine all implementations,
| AFAIK). Some C++ implementations allow this as a conforming
| language extension.
| dnautics wrote:
| thanks for clarifying!
| rdevsrex wrote:
| There was a post about Geometric Algebra, a while back. Is that
| more in use these days?
| Jenz wrote:
| Was hoping to see some discussion on this too.
| Syzygies wrote:
| In "Further Reading" the article links to [Let's remove
| Quaternions from every 3D
| Engine](https://marctenbosch.com/quaternions/) which is about
| Geometric Algebra.
|
| Many chefs are brilliant, but only Jeremiah Tower's book covers
| will tell you he's brilliant. Many branches of mathematics are
| of great utility. Geometric Algebra will breathlessly tell you
| this. I know few fields quite so evangelical.
|
| If you don't know better, you should use quaternions rather
| than matrices. If you don't know better, stick with quaternions
| and avoid the generalization presented by Geometric Algebra
| until the benefit is clear.
|
| This tension is probably why the field is so evangelical.
|
| Quaternions are inevitable. In ten thousand runs of the
| simulation, sentient beings would come up with quaternions
| every time. Geometric Algebra is not so inevitable. An
| aesthetic awareness of the centrality of ideas guides some but
| not all mathematicians. Like that famous quote about taking an
| instant dislike to Ted Cruz, it saves time.
| frankus wrote:
| Sort of unrelated but I wonder if this could make certain kinds
| of latitude/longitude calculations easier.
| jacobolus wrote:
| If you are dealing with a sphere, is much easier to work with
| pure vector methods than with classical spherical trigonometry.
|
| If you are dealing with an ellipsoid of revolution, then vector
| methods can also get tricky.
| neonological wrote:
| Guys I work at a company that uses Quaternions for rotations of
| physical objects. PTUs we call them (Pan Tilt Units).
|
| I am telling you Quaternions have HUGE issues. These issues
| become much more apparent when you deal with physical objects.
|
| Here's the thing Quaternions don't exist in reality. It
| represents an orientation of rotation but it completely masks the
| path took to achieve that orientation.
|
| For every gimbal in reality there is an actual YawPitchRoll (YPR)
| that was executed to achieve that orientation. AS soon as you
| convert that real YPR into a Quaternion you lose the YPR that was
| needed to achieve that orienation.
|
| So let's say I need to have one gimbal imitate the position of
| another gimbal. I take the YPR given to me by gimbal "A" convert
| the YPR to a Quat, send that Quat over the wire to Gimbal "B" and
| convert that Quat back to YPR to feed to the gimbal so it can
| rotate itself to imitate the orientation of gimbal A.
|
| The quat is a higher entropy form of information. Now when
| converting back to YPR there are MULTIPLE YPRs that yield the
| same orientation. You can derive a YPR that is out of bounds of
| the physical gimbal.
|
| Literally you can get a YPR that tells your gimbal to Yaw 190 and
| pitch all the way back past 90 to 170 degrees and roll 180
| degrees until it's right side up. This YPR is identical to a yaw
| of 10, a pitch of 20 and 0 roll. Quaternions hide the original
| YPR, you lose information so when you receive a Quaternion it's
| hard to translate it into a physical realization of the
| orientation.
|
| The company I work for doesn't realize this. They used
| Quaternions from day one and we have all kinds of headaches like
| this when we try to extract the YPR and use these orientations in
| the real world. Actually I should say only I have these
| headaches. A lot of people haven't figured out this problem yet.
|
| The only time you should use Quats are if you need to transform
| an orientation or you're dealing with virtual objects that have
| no rotational limits. Everybody thinks quats are magic and
| better. They are not. They have huge downsides. Huge.
| edflsafoiewq wrote:
| Interesting to read about experience with a physical gimble,
| thanks. In this case the "problems" of Euler angles are
| actually an accurate model of the problem space.
| dakr wrote:
| This real hardware handles quaternions just fine:
| https://en.wikipedia.org/wiki/Stratospheric_Observatory_for_...
| neonological wrote:
| I'm sure it does, I'll give you the benefit of the doubt even
| though the article makes no mention of Quaternions. My point
| is, using Quaternions for physical devices is using a hammer
| on a screw. Huge mistake, but it can be done by people who
| don't know any better. I'm guessing you worked on this and
| bought in to the whole Quaternion BS?
|
| I'm in the defense industry as well and guess what? Basically
| most people don't know any better.
| phkahler wrote:
| >> For every gimbal in reality there is an actual YawPitchRoll
| (YPR) that was executed to achieve that orientation. AS soon as
| you convert that real YPR into a Quaternion you lose the YPR
| that was needed to achieve that orienation.
|
| I would say you obscure it. You can certainly calculate it from
| the 4 quaternion parameters.
|
| SolveSpace (Free CAD software) can be used to design assemblies
| and mechanisms from a set of parts with constraints. You can
| certainly build a gimbal with it by constraining the pieces. If
| you do it correctly, it will be possible to re-orient the final
| 3DoF part and the constraint solver will solve for the angles
| (assuming you built it that way).
|
| Internally we treat all object orientations as quaternions, so
| this would just be using the algebraic constraint solver to
| find the angles. In practice there will be closed form
| solutions - with problems at gimbal lock.
| neonological wrote:
| >I would say you obscure it. You can certainly calculate it
| from the 4 quaternion parameters.
|
| No it is an actual information loss.
|
| There are multiple valid YPR solutions like my example
| illustrated.
|
| There is NO way to determine which YPR out of the multiple
| possibilities was the original solution.
|
| Something like solve space can only determine the original
| YPR with additional assumptions or the original YPR still
| referenced in memory.
| marcodiego wrote:
| tldr: Simply explained without demonstrations: Quaternions are
| hypercomplex numbers of the form
|
| w + x _i + y_ j + z _k
|
| Where w, x, y, and z are real and i^2 = j^2 = k^2 = -1 and i_j =
| k, j _i = -k, j_ k = i, k _j = -i, k_ i = j, i _k = -j.
|
| Being u = (x, y, z) = x_i + y _j + z_ k a unitary vector parallel
| to a rotation axis, it is possible rotate any vector q with a
| theta arc around u by doing:
|
| p _q_ p'
|
| where p = cos(theta/2) + sin(theta/2) _u and p ' = cos(theta/2) -
| sin(theta/2)_u .
___________________________________________________________________
(page generated 2021-06-01 23:01 UTC)