Hacker News new | past | comments | ask | show | jobs | submit login
Quaternions (liorsinai.github.io)
377 points by the_origami_fox on Dec 10, 2021 | hide | past | favorite | 112 comments



I first encountered quaternions in the concept of abstract algebra. It's interesting to think of it as part of a spectrum starting with reals and continuing to octonions (and beyond). Interestingly with each extension we lose something:

Complex numbers (2-dimensional): No more ordering

Quaternions (4-dimensional): No more commutative multiplication

Octonions (8-dimensional): No more associative multiplication

Sedenions (16-dimensional): We lose the alternative property, i.e., with octonions its still true that x(xy) = (xx)y but with sedenions it is not.

We can continue this process indefinitely, although I know nothing of the characteristics of trigintaduonions or what comes later. I suspect that it might be the loss of the flexible identity next, a(ba) = (ab)a but I don't know for sure.


Here's a short article that gave me some insight into the matter:

https://nautil.us/blog/the-strange-numbers-that-birthed-mode...

"Place your phone face-up on a flat surface, for example. Spin it 90 degrees to the left, and then flip it away from you. Note which way the camera points.

Returning to the original position, flip it away from you first and then turn it to the left second. See how the camera points to the right instead?

This initially alarming property, known as non-commutativity, turns out to be a feature the quaternions share with reality "


It's worth noting that one of the early finite groups that is taught in abstract algebra are the dihedral groups which model exactly this sort of behavior (For your phone example this would be D₄. Knowing that mattress flipping is modeled with D₂ makes it trivial to prove that that there is no combination of flip and rotate that will allow you to always do the same move to your mattress to get it into the four possible positions for optimal wear.


Interesting Applied Mathematics


Interestingly, if we go in the opposite direction we also loose something:

Real numbers (1-dimensional): No more algebraic closure [1]

though as you suggest we do gain a nice ordering where "nice" means "compatible with operations". BTW, you can always impose some ordering on all of these sets. It is the orderings' compatibility with arithmetic that we lose going from real numbers to complex numbers.

This can be generalized a little. Real numbers fail to be algebraically closed because some real polynomials lack real solutions, e.g. xx=-2. Complex numbers "fix" this problem since there every n degree polynomial has exactly n roots (counting multiplicity). In a sense, quaternions overdo this, e.g. xx=-2 has an infinite number of solutions (exercise for the reader). However, since quaternion multiplication is not commutative, polynomials as traditionally understood are ill-defined. For example, axx, xax and xxa are different degree two quaternion "polynomials". Ugh.

[1]: https://en.wikipedia.org/wiki/Algebraically_closed_field


I used to teach the expansion of the concept of numbers from ℕ to ℂ via a fictionalized history of the numbers (most notably, expanding ℕ to ℤ before introducing ℚ, but historically, rational and even irrational numbers preceded zero and negative numbers in mathematical understanding. It also elides over the various subdivisions of all the different kinds of irrational numbers that exist in ℝ\ℚ which could be a whole class in itself, but this was a math for liberal arts majors class and I had to make sure not to have their eyes glaze over too much.


One neat characteristic is that the derivations of these higher Cayley-Dickinson algebras stabilize!

[1] https://projecteuclid.org/journals/pacific-journal-of-mathem...


First 4 (reals, complex, quaternions, octonions) are normed division algebras.

Normed means that each number has associated nonnegative real number that describes the "size" of the number, also |xy| <= |x||y|. Number having a size (a norm) is very useful concept.

Sedions and the rest are less useful because they are not normed algebras.


I don't think it makes sense to say you "lose" something. Yes, the properties of different spaces _are_ different, but these differences are intentional so that they can be used to study something useful. For instance, complex analytic functions have a number of properties that don't hold for real analytic functions, so you actually "gain" something. An example is the residue theorem. One interesting thing about the residue theorem is that you can use it to calculate the integral of a real-valued function that wouldn't be calculable using conventional calculus techniques. So not only do complex functions have a number of interesting properties on their own, they can also be used to expand what's possible in real functions.


Another interesting property from which I learnt about quaternions is that all the proper subgroups of the quaternion group are normal and commutative, but the quaternion group itself is non commutative. [0]

[0] https://www.cs.cas.cz/portal/AlgoMath/AlgebraicStructures/St...


Why do you think the dimensions are in powers of two?


Because the construction generating this sequence of algebras doubles the dimension every time.

https://en.m.wikipedia.org/wiki/Cayley%E2%80%93Dickson_const...


W.R Hamilton's discovery of the Quaternions is semi-famous itself, with the story being that after the critical flash of insight he carved the equation describing quaternion multiplication into a bridge in Ireland with a penknife.

A interesting read is this letter [0] written the following day, where he explains his ideas in his own words. It's a great (and accessible!) look into his thought process.

[0] https://www.maths.tcd.ie/pub/HistMath/People/Hamilton/QLette...


The story goes that he was with his wife going to a dinner. On the way he got the flash of insight after years of working on the problem but he had no paper to write it down. When passing a bridge, he carved the equation on the side of the bridge to remind himself on the way back after the dinner.


always have a bridge nearby whenever you're trying to enter history


Ah that explains my failed attempts. It was always too far.


A bridge too far?


One interesting thing about quaternions that’s almost never mentioned anywhere on the internets, there’re two conventions for them.

The convention in that article is known as “Hamilton's quaternions”. There’s another incompatible one usually called “JPL quaternions”, for some American Jet Propulsion Laboratory.

Authors of 99% articles about the quaternions, and software libraries implementing quaternions, are assuming exactly one of these conventions, and almost never mention which one that is.

More info there: https://fzheng.me/2017/11/12/quaternion_conventions_en/


There are actually even more. You can actually have 12 different variations depending on certain choices. Though the other sources of differences are minor.

https://arxiv.org/abs/1711.02508

This is actually a great source of frustration in the robotics state estimation community, as you have the influential University of Minnesota using JPL, and most other universities using Hamiltonian.


I remember reading some library quaternion code (sorry can't remember which library) that started out with a lovely quote from Hamilton on how the idea burst into his mind in a flash as he walked with his wife near the river Liffey I think it was in Dublin. So I guess they mentioned it, at least indirectly.


you also see the variations from the group structure;

https://en.wikipedia.org/wiki/Quaternion_group


In my opinion, Geometric Algebra and bivectors (https://bivector.net) in particular is a much better (both practically and pedagogically) approach compared to quaternions and significantly more elegant. It's a real shame that people continue to focus so much on quaternions in this day and age.


Quaternions are the even part of the Clifford (aka Geometric) algebra associated to a three-dimensional space, so the connection is quite close. This case is also quite special because the quaternions form a division algebra over the real numbers, meaning that each nonzero quaternion has an inverse. Finite-dimensional real division algebras are quite rare: indeed the only ones up to isomorphism are the real numbers, complex numbers, and quaternions.

Geometric algebra is great if you want to extend things to higher dimensions, or spaces with different metric signatures (the 4-dimensional spacetime for example). But quaternions should not be discounted just because they fit into a generalisation - they have many quite special properties all of their own.


To be pedantic, "each nonzero quaternion has a multiplicative inverse"


Came here to say this!

I always felt like quaternions weren't a perfect fit for 3d rotation, and when I finally learned about bivectors my faith in the elegance of mathematics was restored :D

I liked this article: https://marctenbosch.com/quaternions/


> Why does i2=j2=k2=−1 and ij=k? Why do we take a vector and upgrade it to an "imaginary" vector in order to transform it, like q(xi+yj+zk)q∗? Who cares as long as it rotates vectors the right way, right?

Yikes! This is the sort of thing that scares people away from complex numbers from a young age.


Aren't you doing a bit of an injustice to that article by cherry-picking that line? It's obviously written humorously; the very next words are:

> Personally, I have always found it important to actually understand the things I am using. I remember learning about Cross Products and Quaternions and being confused about why they worked this way, but nobody talked about it. Later on I learned about Geometric Algebra and suddenly I could see that the questions I had were legitimate, and everything became so much clearer.

Clearly, "who cares as long as" is not the true belief of the author, but rather a mocking call-out of teachers who do think that way.


> It's a real shame that people continue to focus so much on quaternions in this day and age.

No really, unit quaternions are nice because it's pretty clear they belong to a sphere, therefore you can fairly easily extend geometric methods on the usual sphere to perform filtering, averaging, interpolation etc on rotations.

With GA it's not so obvious.


Specifically, GA allows you to invent complex numbers, quaternions, etc. very easily instead of it taking hundreds of years.

I've read linear and geometric algebra and it's amazing for linear operations. Unfortunately it gets more complex when you want to use it for nonlinear operations (such as translation) - now you need to use CGA or PGA or something. Still, seems like it would be amazing for computer graphics, physical simulation, etc. especially if someone can figure out a good strategy for efficient compilation (e.g. representing a multivector with exactly the minimal number of non-zero entries, with non-zero basis elements tracked at compile time).


GA is much slower in practice and takes more to store. In places speed and cache are important, quaternions are much better.

Game engines don't need much if anything from GA (and I've written about using GA decades ago for software, and did it for some time, before realizing that trading that elegance for worse performance was not worth it).

Here's [1] one example from the godfather of GA demonstrating how poorly GA performs

[1] https://webspace.science.uu.nl/~kreve101/asci/GAraytracer.pd...


I have done some experiments with type-directed static optimization of geometric algebra, but I didn’t get far enough to find out if it would scale up to real applications. The idea was to represent in the type system which components are known to be zero, so that (for instance) the GA representation of a vector or a rotation is the same size as it would be as a traditional matrix-based linear algebra. And the type system can check that the resulting of an operation is what you expect, eg, two planes intersect in a line. So, similar optimizations to gaigen, but (I hoped) more automatic and less runtime machinery. But as I said, I didn’t get it to work.


>the same size as it would be as a traditional matrix-based linear algebra

You can get it that small, it's all been done, but that's far larger than a quat, which can be stored in 3 components when normalized, and in 4 for quick and easy computation.

For large models and more importantly scarce GPU memory, increasing model size results in less complex models and slower computation.

There really is no benefit for 3D engines I can tell (and I was early on the GA bandwagon 20ish years ago... It just has not and I suspect will never pan out due to the inefficiencies not being worth it).


i've played with some libraries recently in julia that followed this strategy; https://discourse.julialang.org/t/ann-cliffordalgebras-jl/71...

and I was surprised at how high dimensionality you could go. I'd like to see a c++20 version.


Something like that exists in C++ and Rust:

* https://www.jeremyong.com/klein/ * https://github.com/wrnrlr/g3


From the paper:

> The main cause for the lower performance of GA is the Gaigen’s soft typing of the geometric algebra objects at compile-time: all types of objects (scalars, vectors, bivectors, trivectors, rotors and so on) are represented by a single data type in Gaigen. When a product or operation has to be computed, Gaigen first checks the grade usage of the argument(s) and then acts accordingly. This conditional step between function call and actual computation is largely responsible for the drop in performance.

So, I blame the library. Writing out the 3-4 datatypes for 3D GA by hand as real types costs some development effort but should give equivalent performance.


It's been tried, over and over. It doesn't work simply because GA representations are larger.

There's a reason that after decades GA hasn't replaced quaternions, and it's not because people don't know how to optimize code by hand.


Exactly, in fact I'm always surprised so many people still claim GA is better for practical implementations after all these years.

My impression is that if you want something compact that you'll need to either give up on performance (type erasure) or separate compilation (track every type).

GA is great for pen and paper proofs though.


Exactly - GA is nice for proofs, bad for code. I wrote an article in Games Programming Gems V back around 2004, showing many proofs of things one wants to do in computer graphics all derived simply using GA.


These don't look like they'd be all that different in perf

https://marctenbosch.com/quaternions/code.htm


GA strikes me as the monad's of physics


"Geometric Algebra is just a Clifford algebra over an Euclidean space, what's the problem?"


Quanternions' ubiquity is relatively recent. Rotation matrices ruled supreme in games and graphics and it was only after concerted effort to abolish R's were Q's made ubiquitous.

Two heartbeats later, we're bearish on Q's.


Rotation matrices are still ubiquitous even in systems which use quaternions: if you want to apply a dense linear transformation to a vector (be it a rotation or otherwise), pretty much nothing will beat (in terms of speed) a matrix-vector multiplication. For instance even if you work out the rotation matrices using quaternions, an engine will end up shipping a rotation matrix to a graphics card to actually transform the bulk of vertices in a scene.


I remember the first time I encountered quaternions, and it was in a similar context. I was using PiQT 3d to move models in a simulation.

At first it really bothered me that quaternions were a black box to me, yet so easy to use in so many contexts. What kind of magic was happening? I had to know.

My math is terrible. I spent actual days revisiting YouTube videos explaining quaternions but my limited brain cells were failing to properly grasp it. I had to know though, I’d go crazy writing so much code that depends on something I couldn’t understand.

It took a long time. This would have been very helpful. Quaternions are very cool, and well worth reading about if you do anything in the digital 3d world.

I think I can still hear my brain sizzling as I tried to absorb this stuff.


Try reading it up again. My experience is that with age theory gets easier.


3B1B is also informative, especially in explaining why C was not extended using triplets but 4-tuples were needed: https://youtu.be/d4EgbgTm0Bg.

Here’s a Math SE answer on why: https://math.stackexchange.com/questions/1784166/why-are-the..., here’s a more ELI5 discussion: https://www.reddit.com/r/math/comments/9urjyx/why_there_is_n.... I especially like this very intuitive comment in that thread : https://www.reddit.com/r/math/comments/9urjyx/comment/e96j4l...

Left as an exercise to reader: prove that no such n-tuples exist for n>4.


This comment is about ℂ the set of complex numbers, not the progamming language. It left me confused for a moment.


> prove that no such n-tuples exist for n>4.

It depends on how you define "such" n-tuples. The octonions (n = 8) aren't associative, but they have all the other relevant properties.


You’re absolutely right, forgot to mention associativity: https://en.m.wikipedia.org/wiki/Frobenius_theorem_(real_divi...


Interesting thing to remember: quaternions are a special application of rotors, a concept which may be easier to understand as a base:

https://marctenbosch.com/quaternions/


David Eberly has written a huge amount of great and free intro mathematical papers. The "Mathematics/Algebra" section of [1] has a few things on quaternions, including a nice self-contained linear algebra-based derivation of why it makes sense to represent a rotation with four numbers, which ends up being a sneaky introduction to quaternions [2]

[1] https://www.geometrictools.com/Documentation/Documentation.h...

[2] https://www.geometrictools.com/Documentation/LinearAlgebraic...


Smallest of small notes: in TeX, "cos" is rendered as a product of 3 italicised variables c, o and s, whereas the escaped literal "\cos" is rendered as the cosine function.


Author here: thanks for the tip. Definitely think this looks better


Great, it certainly does look better :) Note that this also applies to log, exp and other functions. Also, some images seem to be missing in part 2.

Anyway it's a great writeup, even though I know the material it was a good read.


> although a lecturer once eluded to them during a class in my masters

Would be more amusing if "they eluded a lecturer" or "a lecturer once elided them".

("alluded to them").


also: gimbol -> gimbal


I came here to report the same two typos. Thanks.


yeah that one drove me nuts for some reason.


Author here: these typos totally eluded me. Will fix them.


tpyos elide us all


You should check out the bivector community dedicated to geometric algebra https://bivector.net/.

Check out a demo https://observablehq.com/@enkimute/animated-orbits

Join the discord https://discord.gg/vGY6pPk.

Enki (the guy behind bivector) also gave a talk on GA at SIGGRAPH 2019 https://www.youtube.com/watch?v=tX4H_ctggYo


> I did not encounter quaternions in all my years of engineering, although a lecturer once alluded to them during a class in my masters.

I know that I am not coming in with same perspective as a lot of the other software engineers/graphics developers, but I started learning about quaternions freshman year of college. For aerospace engineering quaternions are used almost exclusively for spacecraft attitude determination and control. For a very dynamic system they are very useful.

There are some limitations that I have seen, and I have seen Rodrigues parameters (or modified Rodrigues parameters) used instead which are mentioned near the end of the article.


I've been teaching myself geometric algebra which is apparently isomorphic to quaternion algebra. Some people prefer GA for 3D modeling work.


Computing in higher dimensions is nice, although pretty difficult to implement efficiently. Hence, Quaternions are mostly used nowadays, I think.


I've been out of the games sphere for a long time, but is slerp() really the default idiomatic interpolation approach in modern games nowadays?

There are a vanishingly small number of scenarios where lerp() + normalize() doesn't work perfectly well enough and it is drastically faster and SIMD-friendly. That used to be the case at least.


You can see what's wrong with that approach by considering the difference between traveling at constant speed along the arc of a circle versus traveling at constant speed along a chord, and projecting the point (out from the center) onto the arc.

It works great if the chord is far away from the center (and also the angle is less than a half turn). If the chord goes through the center, it doesn't work at all.


10-12 years ago, the consensus used to be that this singularity simply does not show up in the wild in the vast majority of scenarios, and the performance hit of using `slerp()` is just not worth it unless truly needed.

It was essentially the same reasoning as for using `-ffast-math`. Yeah it's not "correct", but users can't tell the difference and it has a measurable performance benefit.

To be clear, I'm not questioning using slerp() at all, it definitely has a role to play. I'm just wondering about using it by default as implied by the post.


Yeah, I understand. I just wanted to show that one can understand the exact nature of the approximation in 2D geometry.

I think it's useful to think of it as a separate category of "wrong" than -ffast-math, which is "wrong" because two expressions that are mathematically equivalent over real numbers, like a + (b + c) and (a + b) + c, are not equivalent over floating-point numbers.

Using lerp in place of slerp is like using x in place of sin(x). (The small-angle approximation) They're not equivalent over the real numbers.


My apologies. I thought you were providing an explanation as to why slerp() is preferred in general. The circle example is a really good way to frame the distinction.


I don’t think the scenarios where uniform steps of angle is vanishingly small. There are plenty of cases where it matters to animators, on character rigs, on cameras

The amount that it matters depends on the angle between keys. Suggesting it rarely matters means you’re claiming nobody ever animates large angles, which I can confidently say I’ve seen plenty of counter-examples in game development.

I also wouldn’t be so sure that lerp+normalize is that much faster on today’s GPUs. Normalize takes a sqrt and reciprocal or divide, while slerp takes a few sin evaluations and a recip or divide. These special functions these days execute in a separate pipeline from linear (FMA) type instructions, and can be had for “free” as long as you can mix enough independent linear math in between the special functions. It used to be that sin() was very slow, but these days you can often mix a couple calls in without affecting your perf at all.


as for why lerp+normalize isn't enough: it all depends on the distance between things being blended, no? With far away end points, the apparent speed of the rotation would be fast, slow, fast, at the beginning, middle, end, which could be a bummer.


The two aspects that slerp() addresses over lerp() + normalize() are 1) it can deal with pole-to-pole interpolation 2) It always takes the shortest path.

In practice, the former is often provably never going to happen, and the later doesn't actually matter from a qualitative standpoint: Quaternion interpolation will always look a bit weird over large angles, especially if there's a roll component to one of the orientations.

As far as having a constant interpolation speed: again, this is rarely perceptible, and truly linear transitions from one orientation to another looks janky so some amount of filtering happens anyways (an ease-in-ease-out for example).

But yeah, for very large interpolations, it can create a slight authoring/runtime skew. My rule of thumb used to be: use slerp() when the orientations can be at least 120 degrees apart, or when lerp() yields weird results. However, it's really rare to be interpolating over such a large orientation change, you almost always have a few keyframes or dead-reckoning syncs in between.

Again: This might be an outdated perspective though.


Ask HN: Do quaternions have any interesting properties, akin to those of complex numbers, when calculus is applied? The only application I've ever seen is for doing rotations in computer graphics.


per wikipedia (hence the interest in twistors, spin spaces and clifford algebras in physics):

Quaternions also capture the spinorial character of rotations in three dimensions. For a three-dimensional object connected to its (fixed) surroundings by slack strings or bands, the strings or bands can be untangled after two complete turns about some fixed axis from an initial untangled state. Algebraically, the quaternion describing such a rotation changes from a scalar +1 (initially), through (scalar + pseudovector) values to scalar −1 (at one full turn), through (scalar + pseudovector) values back to scalar +1 (at two full turns). This cycle repeats every 2 turns. After 2n turns (integer n > 0), without any intermediate untangling attempts, the strings/bands can be partially untangled back to the 2(n − 1) turns state with each application of the same procedure used in untangling from 2 turns to 0 turns. Applying the same procedure n times will take a 2n-tangled object back to the untangled or 0 turn state. The untangling process also removes any rotation-generated twisting about the strings/bands themselves. Simple 3D mechanical models can be used to demonstrate these facts.


Still mostly relevant to their use as encoding for transformations, but the fact that a unit quaternion's conjugate is also its inverse is extremely useful from a computational performance point of view.


If I understand correctly, yes, calculus on quaternions is a useful thing. I'm not sure whether or not you have an equivalent of the residue theorem from the calculus of complex variables, but I'm pretty sure that you can do path integrals and stuff...


John Baez was tweeting about this recently:

https://twitter.com/johncarlosbaez/status/146720413326244659...


This page is a little more information dense, but it's what I learned quaternions from (after bashing my head against it for a couple of weeks) and it's good as a refresher because it is so dense.

http://www.tutis.ca/Rotate/7quaternions.htm

One thing I didn't see in the OP's linked article is how to transform a quaternion into a different coordinate system defined by another quaternion. For example, suppose you have a spaceship in a game at an arbitrary orientation defined by Q1 which is a rotation away from a conventional "unrotated" orientation, and you want to input say 5 degrees of yaw to the right. Well, you just construct a quaternion Q2 that is 5 degrees yaw to the right from this conventional unrotated orientation, and you can use quaternion conjugation to transform Q2 into the orientation of Q1 where it can then be applied to the spaceship's orientation. OP's link mentioned quaternion conjugation, but didn't really mention what it was good for. It is described in section IV of the 7quaternions link.


The absolute best instruction on quaternions I've seen is the 3Blue1Brown series on your tube and their incredible live quaternion viewer: https://www.youtube.com/watch?v=zjMuIxRvygQ&t=24s

I was able to learn enough from this to then use quaternion matrix transformations extensively in my startup to incredible effect.


Very nice thats a reference to keep and come back to thanks.


I've seen dozen of tutorials trying to explain quaternions in multiple analogies and methods. But finally after this tutorial I can finally conclude that I'm dumb.


I remember "quarternions" from my math-heavy computer graphics class.

Today, I have zero recollection of what they were or why it was in my graphics class. Heck I barely remember anything from that class today, which is ironical considering it was a required class for me to graduate that semester.

I wish my job had atleast a little more to do withwhat I learnt in college.

(I'm a web developer, and I'd like to get closer to the machine.)


Quaternion trivia.

There was at one point a debate in physics about whether it was better to use quaternions or linear algebra for physics. With i, j, and k being the unit vectors, and the real numbers representing time. In the end, of course, linear algebra won. But we still use i, j, and k as the unit vectors. And in electrical engineering where i wound up hijacked for current, they use j as the square root of -1.


About rotation and interpolation, I once had a bug in animated CSS transforms of all things, in which IE decided to rotate the element around another axis but still end up at the correct position. That one made me raise my eyebrows. No idea if IE actually was in the wrong, though, but in my head interpolating the xyz value I'm changing feels like the correct way to do it.


tldr: Simply explained without demonstrations: Quaternions are hypercomplex numbers of the form

w + xi + yj + zk

Where w, x, y, and z are real and i^2 = j^2 = k^2 = -1 and ij = k, ji = -k, jk = i, kj = -i, ki = j, ik = -j.

Being u = (x, y, z) = xi + yj + zk a unitary vector, it is possible rotate any vector q by an angle theta around u by doing:

pqp'

where p = cos(theta/2) + sin(theta/2)u and p' = cos(theta/2) - sin(theta/2)u .


> Quaternions are hypercomplex numbers of the form

I'm gonna guess "hypercomplex" means "involves imaginary numbers" due to the rest of this.

> Where w, x, y, and z are real and i^2 = j^2 = k^2 = -1 and ij = k, ji = -k, jk = i, kj = -i, ki = j, ik = -j.

Why even use different letters for i, j, and k, if they're all the same thing? Which thing appears to be i, as in, the square root of -1, that is to say, the most well-known and basic imaginary number, if I'm reading this right. As for the second part, I can't even begin to unravel the significance. I know it must not be, but it just seems like arbitrary rules added for... some unknown reason.

> Being u = (x, y, z) = xi + yj + zk a unitary vector, it is possible rotate any vector q by an angle theta around u by doing:

> pqp'

> where p = cos(theta/2) + sin(theta/2)u and p' = cos(theta/2) - sin(theta/2)u .

Oooooh kay... 1) Where'd w go? Is this one of those things where there's a (situationally-defined) constant in the formula but we just pretend it doesn't exist most of the time (until it comes time to actually use the math to, like, do anything real)? Would we need to bring it back in to apply the rest of this? 2) "u =" is just defining something, fine, but (x, y, z) doesn't seem to equal the thing after it at all—I suppose this is a shorthand function notation, though it seems really weird to me to use equality to relate that. Am I right, or is this something else?, 3) A quaternion is... a point, then? Since we're rotating around it? 4) I've got a feeling that theta needs a direction in this hypercomplex space but don't see where it's coming from. Somewhere "off screen", in this explanation? Or is it there but I'm not seeing it?


It seems to me that i, j, and k are three things that have the same property, not three identical things.


TIL that not every imaginary number is just "i" with optional scaling applied. Was taught "the square root of negative one is i".


That's a heck of a great observation.

In the complex numbers, every imaginary number is, indeed, just "i" scaled. But the quaternions are like three copies of the complex numbers glued together; you have multiple kinds of "imaginary", each with their own unit -- like "i", but now also copies of it, "j" and "k".

To bring this somewhere more familiar, you can probably imagine the real number line as a physical line stretching off to infinity. This line has a point called "1". Now if we take two more copies of this line, they each have their own point called "1" -- a different one for each line. And if you stick all three of these lines together as a three-dimensional set of axes, you get a world in which you have three 1s coexisting. We just say "in the X direction" to be clear about which we're talking about, or group them together in (x, y, z) triples -- in which case X's 1 is called (1, 0, 0).

The situation is the same for quaternions -- we glue one real line together with three copies of the imaginary line. So we get three different i's, and we give them different names to distinguish them.


Unfortunately that's not even correct for complex numbers: i is a square root of -1, and -i is the other. Complex numbers are really nice in that every non-zero complex number has two square roots, three cube roots, four fourth roots, etc.

A better definitional statement is the other way around: i has the property that i^2 = -1.


i wish i was taught in terms of euler' formula, which is probably the most useful: https://en.wikipedia.org/wiki/Euler%27s_formula


No, i, j, and k are not the same thing. They are the three distinct square roots of -1. You thus wind up with a space with one real axis and three orthogonal imaginary axes.

Why should -1 have three distinct imaginary roots? Well, why should it have one? Essentially, we just made up i, and we found out that the complex numbers had some really useful algebraic properties. The same is true of the quaternions.

But why not two imaginary roots, or four, or 17? Those turn out not to have nice algebraic properties. The only other thing out there are the octonions, with 7 imaginary roots.


And like that I’ve given up hope of ever having a good understanding of any mathematical field.


Try this version, which is expanded somewhat. I found it clearer:

https://news.ycombinator.com/item?id=29516191


Sounds a lot like the first time I tried to understand quaternions. The explanation in geometric algebra as a scalar and bivector gives it an intuitive geometric sense that words like words like "hypercomplex" fail to. Others here have linked to that material.


>> Quaternions are hypercomplex numbers of the form

>

>I'm gonna guess "hypercomplex" means "involves imaginary numbers" due to the rest of this.

Think it is right.

>>

>> Where w, x, y, and z are real and i^2 = j^2 = k^2 = -1 and ij = k, ji = -k, jk = i, kj = -i, ki = j, ik = -j.

>

>Why even use different letters for i, j, and k, if they're all the same thing? Which thing appears to be i, as in, the square root of -1, that is to say, the most well-known and basic imaginary number, if I'm reading this right.

They are not the same thing. All of these are equal to -1 when squared, but they are different when multiplied by any other of this set and multiplication between them is anti-commutative.

>As for the second part, I can't even begin to unravel the significance. I know it must not be, but it just seems like arbitrary rules added for... some unknown reason.

>

These are not added for unknown reasons. They specify rotations of unitary vectors of a canonical base around one another.

>> Being u = (x, y, z) = xi + yj + zk a unitary vector, it is possible rotate any vector q by an angle theta around u by doing:

>>

>> pqp'

>>

>> where p = cos(theta/2) + sin(theta/2)u and p' = cos(theta/2) - sin(theta/2)u .

>>

>Oooooh kay... 1) Where'd w go?

The coordinate 'w' is the real part. For the vector 'u', such coordinate is 0. For 'p' and 'p'', it is cos(theta/2).

>Is this one of those things where there's a (situationally-defined) constant in the formula but we just pretend it doesn't exist most of the time (until it comes time to actually use the math to, like, do anything real)?

No.

>Would we need to bring it back in to apply the rest of this?

No. Just follow the rules to multiply hypercomplex numbers and the rotation will occur.

>2) "u =" is just defining something, fine, but (x, y, z) doesn't seem to equal the thing after it at all—I suppose this is a shorthand function notation, though it seems really weird to me to use equality to relate that. Am I right, or is this something else?,

The notation '(x, y, z)' is just a shorter notation for "xi + yj + zk". For this problem, the vector 'u' defines the axis of rotation.

>3) A quaternion is... a point, then? Since we're rotating around it?

You can see a quaternion as a point in R^4 since it has 4 coordinates. Actually it describes an axis of rotation, by its imaginary part, and the angle of rotation.

>4) I've got a feeling that theta needs a direction in this hypercomplex space but don't see where it's coming from. Somewhere "off screen", in this explanation? Or is it there but I'm not seeing it?

>

The axis of rotation is actually the vector "u".


Thank you, this was very helpful.

> The axis of rotation is actually the vector "u".

Ah, I thought the vector was what we were rotating.


I think "p" is better described as a point instead of a vector. So, a better writing could be: "[..]it is possible rotate any point q by an angle theta around the axis define by u [...]"


tldr tldr (Since your version is for people who already understand undergraduate math, this version is for people who already understand upper-level undergraduate/graduate math):

If you try to use a product of 3 rotation matrices that represent rotations around fixed axes to represent rotations in 3D, there will inevitably be gimbal lock because there cannot exist a covering map from a product of 3 circles to SO(3). (Gimbal lock happens at the points where the map locally fails to be a covering map)

SU(2) is the universal cover of SO(3). The unit quaternions are a faithful representation of SU(2). Conveniently, the double cover map from SU(2) to SO(3) is dead simple in this representation: a unit quaternion q in SU(2) act on a purely imaginary quaternion (thought of as a vector in R^3) by conjugation. This is the formula you wrote.

Since it is a covering map, there is no gimbal lock.

Edited to fix explanation.


I don't believe that most people will consider that "simply explained".


Maybe succinctly?


Yes, it is certainly succinct. But only simple and explained for math majors. :D


Hypercomplex numbers are different to quaternions. They also have 4 components but the multiplication of hypercomplex numbers is commutative.


This is fine; there are lots of similar "intro to quaternions" pages around. One thing I haven't seen yet is someone showing how to interpolate between multiple quaternions over time, smoothly. (Hint: it's not slerp.) It's a non-trivial problem.


See "A General Construction Scheme for Unit Quaternion Curves with Simple High Order Derivatives" (Kim, 1995) for a simple extension of Hermite splines to Lie groups, including unit quaternions.


> Hint: it's not slerp.

What is slerp?


Spherical linear interpolation. (https://en.m.wikipedia.org/wiki/Slerp)


Very nice interactive visualizations! I've made a similar article some time ago https://imadr.me/rotations-with-quaternions/


Is there a reason why, for me, this post contains `[math processing error]` numerous times instead of math symbols?

Update: It’s due to incompatibility with the Dark Reader extension, which causes MathJax to find unexpected nulls in `classList`


Ongoing related thread:

Let's remove Quaternions from every 3D Engine (2018) - https://news.ycombinator.com/item?id=29512302


Nice I will learn these for IMU stuff, I'm still a noob currently.


I don't like this proof of the rotation formula. It seems like juggling formulas without providing any motivation as to how we get there. It does a great job of explaining the problems with other notations, but in demonstrating the formula for quaternion rotation we just pull conjugation out of a hat.

First, let's ask what it means to rotate around an axis. If you consider rotation of a vector v in a plane A around the unit normal n, you can decompose v as follows:

v = proj_n(v) + proj_A(v) = vn + vA

Now a 90 degree rotation of v about n is

rot_n(90,v) = vn + n >< vA = vn + vR = (v•n)n + v >< n

So if we consider v rotated by an angle S around n, we can infer that vn is preserved and the image rot_n(S,vA) can be projected onto vA and vR according to the usual cosine rule for projection:

rot_n(S, vA) = cos(S)vA + cos(s-90)vR = cos(S)vA + sin(S)vR

Likewise,

rot_n(S, v) = cos(S)v + sin(S)rot_n(90, v) = cos(S)v + sin(S)((v•n)n + v >< n)

Okay, now what's wrong with this formula? What if we want to combine rotations? We're stuck, because this "multiplication" isn't associative. So we can turn this into a linear transformation and use the matrix representation, which gives a nine-dimensional algebra, although with symmetry you can make it five-dimensional. (The fifth dimension comes from the requirement that both the determinant and the L2 norm of the matrix coefficients are constant, 1 and 3 respectively.)

But we have perhaps heard about the quaternions, which are associative. And we might have noticed that Im(v*n), where * denotes quaternion multiplication and Im() discards the real part, is equal to v >< n, viewed as vectors. But multiplication under Im() isn't associative either. But we can also define Im() another way, using the apostrophe for conjugation:

Im(v*n) = (v*n - (v*n)')/2 = (v*n - n*v)/2

since (v*n)' = n'*v' = (-n)*(-v) = n*v for pure imaginary v,n, where we recall that conjugation distributes over products of quaternions at the cost of reversing the order.

Now what if we try to construct the rotation again:

rot_n(S,v) = cos(S)v + sin(S)(v*n - n*v)/2 = (v*(cos(S)+ sin(S)n) - (-cos(S) + sin(S))*v)/2 = (v*q(n,S) + q(n,S)'*v)/2

Here q(n,S) = cos(S) + sin(S)n is a perfectly reasonable quaternion, and we call it a rotation quaternion. This is now almost associative but not quite. If we combine rotations q and p, we end up with terms like q'*v*p. How annoying. But it feels like we're getting closer, so let's see if we can learn anything else about these "sandwich" products.

Geometrically, if we rotate the vector forwards and backwards, we should get the same vector. But q(n,-S) = q(n,S)', so we must find (we drop the arguments since there is only one q and we are sick of parentheses):

((v*q + q'*v)*q' + q*(v*q + q'*v))/4 = (v*q*q' + q*q'*v + q'*v*q' + q*v*q)/4 = v

Now it's not so hard to verify that q*q' = q'*q = 1, so we can subtract v/2 from both sides and clear the denominator to find the curious-looking lemma:

q*v*q + q'*v*q' = 2v

Now (q'*v*q')' = q*v'*q = -q*v*q, the last equality being established because v is imaginary. Therefore:

q*v*q - (q*v*q)' = 2Im(q*v*q) = 2v

so Im(qvq) = v, for arbitrary rotation vectors q.

Evidently a multiplication by q on the right undoes a multiplication by q on the left, at least when we are talking about imaginary parts, which we were interested in already. So what happens when we take q'*v*q — the missing sandwich in the above equation? This should give us two rotations in the same direction, since switching sides inverts the rotation and conjugation inverts it again to leave us with the same rotation. But what's the use of writing

rot_n(2S, v) = Im(q'*v*q)?

Just try it:

Im(q'*v*q) = (q'*v*q - (q'*v*q)')/2 = (q'*v*q - q'*v'*q)/2 = (q'*v*q + q'*v*q)/2 = q'*v*q!

So we now have a formula where everything is in one product. It turns out that the ugly "sandwiches" (we also call this conjugation, which can be confusing) are useful after all. (Explicitly verifying that q'vq = rot_n(2S, v) is left as an exercise for the reader. See hint [1]. ) Now if we consider a rotation by a second quaternion p, we find:

p'*q'*v*q*p = (q*p)'*v*(q*p)

by inverting the distributive property for conjugation. So we only need to take one product to combine rotations. Finally, an associative structure!

There is only one sticking point left. Evidently q(n,S) corresponds to the transformation rot_n(2S,v). So in order to get rot_n(S, v) we need:

Q(n,S) = q(n,S/2)

But there is one more thing. What happens when S = 360? We all know that a rotation of 360 degrees doesn't change the geometry. So shouldn't we have Q(n,360) = 1? But in fact:

Q(n,360) = q(n,180) = cos(180) + sin(180)n = -1!

Of course (-1)'v(-1) = v.

Evidently Q has a period of 720 degrees under rotations S rather than the usual 360, i.e., Q is a spinor. This is sometimes called a "double cover".

In fact, we could also represent rotations and positions with the Pauli spin matrices and complex 2-vectors respectively, although (as in quantum mechanics) we pick up a meaningless global phase, and translation is weird.

[1]: Consider various ways of writing parentheses on the expression Im(q*q'*v*q*q), and show that q(n,S)*q(n,S) = q(n,2S).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: