Interactive Article/Video: Let’s remove Quaternions from every 3D Engine (An Interactive Introduction to Rotors from Geometric Algebra)

I have not yet posted on this blog that last year I released an article/video with interactive diagrams on Geometric Algebra, specifically Rotors. (I also recently updated it). Here is the introduction:

To represent 3D rotations graphics programmers use Quaternions. However, Quaternions are taught at face value. We just accept their odd multiplication tables and other arcane definitions and use them as black boxes that rotate vectors in the ways we want. Why does $\mathbf{i}^2=\mathbf{j}^2=\mathbf{k}^2=-1$ and $\mathbf{i} \mathbf{j} = \mathbf{k}$? Why do we take a vector and upgrade it to an “imaginary” vector in order to transform it, like $\mathbf{q} (x\mathbf{i} + y\mathbf{j} + z \mathbf{k}) \mathbf{q}^{*}$? Who cares as long as it rotates vectors the right way, right?

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.

In Geometric Algebra there is a way to represent rotations called a Rotor that generalizes Quaternions (in 3D) and Complex Numbers (in 2D) and even works in any number of dimensions.

3D Rotors are in a sense the true form of quaternions, or in other words Quaternions are an obfuscated version of Rotors. They are equivalent in that they have the same number of components, their API is the same, they are as efficient, they are good for interpolation and avoiding gimbal lock, etc… in fact, they are isomorphic, so it is possible to do some math to turn a rotor into a quaternion, but doing so makes them less general and less intuitive (and loses extra capabilites).

But instead of defining Quaternions out of nowhere and trying to explain how they work retroactively, it is possible to explain Rotors almost entirely from scratch. This obviously takes more time, but I find it is very much worth it because it makes them much easier to understand!

Earth-Centric planetary motion

For example, Quaternions are introduced as this mysterious four-dimensional object, but why introduce a fourth dimension of space to visualize a 3D concept? By contrast 3D Rotors do not require the use of a fourth dimension of space in order to be visualized.

Trying to visualize quaternions as operating in 4D just to explain 3D rotations is a bit like trying to understand planetary motion from an earth-centric perspective i.e. overly complex because you are looking at it from the wrong viewpoint.

It would be great if we could start phasing out the use and teaching of Quaternions and replace them with Rotors. The change is simple and the code remains almost the same, but the understanding grows a lot.

As a side note, Geometric Algebra contains more than just Rotors, and is a very useful tool to have in one’s toolbox. This article also serves as an introduction to it.

And here are some quotes about it:

The clearest explanation of 3D geometric algebra within 15 minutes that I’ve seen so far —BrokenSymmetry
I am sold. While I can understand quaternions to an extent, this way of thinking is a much more intuitive and elegant approach. —Jack Rasksilver
This sets a high standard for educational material, and is a shining example of how we can improve education with today’s technologies. —Sebastien Pierre
When I was in college, I asked one of my math professors why the cross product of two vectors results in a perpendicular vector whose magnitude is equal to the area of the parallelogram formed by the two vectors. Like..what? Why? And what about 2D? They blew me off, and that was a big part of why I stopped taking math in college. […] Anyway, I had pretty much given up on ever truly understanding the whole jumble of seemingly unrelated types that are cross products. But then I saw this: And…wow. Just 15 minutes and a lot more than just cross products suddenly make a lot more sense. —Mason Remaley
I’m a pure math dude at heart, even if I don’t get to do it much any more. Two years ago, my wife asked me, “If you had to get a math equation tattooed on your body, what would it be?” I answered, “i^2 = j^2 = k^2 = ijk = -1”. I felt a brief flush of anger when I saw this headline. This is an extraordinarily good article that should be read by pretty much anyone doing graphics programming. —pflats

I wrote most of in 2011/2012, but didn’t release it because I was not satisfied with part of it. But I thought it was time to let go and release it anyway. I actually think it is hurting the advancement of science that people are still mainly using quaternions instead of Geometric Algebra, so holding on to it was not good.

So last fall/summer I cleaned up some of the diagrams and made a 15 minute long video that follows the article exactly. I never made a video this long, and it was quite exhausting. But I thought it would be really cool to make an article that is perfectly synced to a video, so you can either read it or watch it, and the article serves as an exact table of contents for the video.

I think I came across Geometric Algebra from attending SIGGRAPH a long time ago? Specifically this book: Geometric Algebra for Computer Science by Dorst et al. Later on I found this great book: Linear and Geometric Algebra by Macdonald

Geometric Algebra soon came in handy for Miegakure, specifically to define the 4D equivalent to Quaternions, which I posted about on this blog. Later on it became the backbone of 4D Toys.

Learning about Geometric Algebra was also great because it answered so many questions I had when learning linear algebra, the cross product, quaternions, etc… I basically wrote this article for my past self as a college student.

I recently rewrote the introduction to add more detail about the properties of Rotors and how they relate to quaternions. Even though the content went into detail, it should now be clear what Rotors are from only reading the introduction. I can already see from reading recent comments that it was worth it.

I deliberately picked a cheeky click-bait title…

Something else that might be of interest is the history of Geometric Algebra, so I recently added a heavily summarized version to the end of the article. I think looking at the history makes it clearer how the quaternion viewpoint stayed in people’s minds for longer than necessary…

18 Responses to “Interactive Article/Video: Let’s remove Quaternions from every 3D Engine (An Interactive Introduction to Rotors from Geometric Algebra)”

  1. godefv says:

    Hi !

    I am happy to see that some people know about geometric algebra.
    You can check out my math library (which includes geometric algebra in any dimension) : https://github.com/godefv/math

    I was hoping to make it available on GPU by using SYCL but SYCL does not support C++17 and C++-Concepts yet.

    I wonder what you have used. Have you implementes 4D rotors in CUDA directly ?

    Godeffroy

    • marc says:

      I just wrote my own. I wrote some c++ to generate the optimized methods I needed. They are just in c++, no CUDA.

  2. Sam says:

    very cool, very informative 😀

  3. godefv says:

    Also, this talk “Geometric algebra for computer graphics” from Siggraph2019 (https://www.youtube.com/watch?v=tX4H_ctggYo) is quite interesting.

    It seems that the use of the metric (N,0,1) for projective geometry is quite new, and it provides translations as rotors as in conformal geometry, but in a much simpler space. One drawback is that the objects have to be represented in the dual space.

  4. Brett Brownlee says:

    In 2018 you mentioned not having a good way to explain geometric product.

    Have you found a good way? Or any hints at an alternative method?

    How important is the geometric product to everything like GA’s ability to relate to Maxwell Equations?

  5. brett says:

    I was reading about this in threads and saw in 2018 you said this:

    “Yeah, I spent a long time trying to find a very clean path to the geometric product and failed so far, but I feel I am getting closer, ahah.”

    In this thread https://news.ycombinator.com/item?id=18367262

    Did you ever feel like you got closer to a clean path to explaining geometric product simply. Nowadays do you have any new hints that might pull it off? Where is this space now?

  6. daec says:

    Earlier I was doing some algebra shenanigans with 4D rotors and tried performing a 4D double rotation around a point, rotating simultaneously in two planes that intersect only at one point.

    My first thought was to use a rotor like `cos(θ/2) + sin(θ/2)*(sqrt(1/2)*xz + sqrt(1/2)*yw)`. This produced something that looked like a double rotation, but the vectors gradually shrank down to zero vectors as the angle approached`θ = pi`!

    My next thought was to compose/multiply the rotors `cos(θ₁/2) + sin(θ₁/2)*(xz)` and `cos(θ₂/2) + sin(θ₂/2)*(yw)`, but it didn’t give out the expected double rotation. Additionally, sometimes composing unit rotors resulted in the product not being of unit length, which I didn’t expect.

    I found I could get a successful double rotation by rotating the points by `cos(θ₁/2) + sin(θ₁/2)*(xz)`, and then rotating them again by `cos(θ₂/2) + sin(θ₂/2)*(yw)`. I thought this was the same as composition; why are they not the same here?

    Did you ever have to work with double rotations? How would you represent them, and would it be possible to represent them as a single 4D rotor? Should one of my other methods have worked but my math is probably just wrong? 😀

    Cheers!

  7. Erhannis says:

    This was all fine and good (well, mostly) until I actually tried to use it. I quickly got an expression that represented the solution, and was promptly stumped in how to reduce it. Consider – geometric product was explained as an operation on two vectors, yielding a sum of a scalar and a bivector. In the case of `-ava`, are there two instances of the geometric product operator present? Is there some other kind of operator implicitly present? There’s no explicit symbol denoting the operation. (Which, granted, isn’t your fault.) Assuming it’s `-a (g-product) v (g-product) a`, then consider `va = v*a + v^a` implies `-ava = -a(v*a + v^a)`, and so now we’re taking the geometric product of a vector and some immiscible sum, which is outside the declared domain of our operator. If we ignore that for a moment: IF a geometric product can be distributed across a sum, then we get `-a(v*a) – a(v^a)`, and since `v*a` is a scalar, we’re taking the geometric product of a vector and a scalar, which is surely nonsense…right? How do you actually *crunch the numbers* once you have a solution? With quaternions or matrices I can just multiply everything out (using the rules given with each), but with rotors it seems like too few rules have been given for them to be usable. Now, if that was your intent – to provide high-level overview without actually giving enough details to use them, well, I guess that’s a valid goal, but it SEEMED like you were trying to explain how to actually use them. What key insight am I missing?

    • marc says:

      Good question. Basically you would use the rules for multiplication from section 3.2.

      You could expand to a coordinate basis. That would be equivalent of matrix and quaternion multiplication.

      Or you could split the vector into parallel are perpendicular parts: If a and b are perpendicular then ab is a^b, if they are parallel then ab is a dot b.

      • Erhannis says:

        Well, I don’t think that segment contains the information I needed – or, if it does, it’s in a form such that the answer isn’t immediately apparent to me. BUT! After scouring the internet for 6 hours, I pieced together enough information to figure it out! The first requisite fact: scalars, vectors, bivectors, trivectors, etc. are each a particular case of a larger group called multivectors. A multivector is a sum of a scalar, and a vector, and a bivector, etc. So, e.g. a vector is a multivector with all the non-vector elements 0. The second requisite fact: the geometric product operates on multivectors and returns a multivector (as do addition and subtraction). That’s why you’re allowed to take the geometric product of a scalar and a multivector, etc.; it’s why distributing across multiple different datatypes is allowed: they’re all multivectors. 😀 Final requisite data point: I found this website! https://www.euclideanspace.com/maths/algebra/clifford/d3/functions/index.htm It has exactly the multiplication table I wanted! Taking the geometric product of an arbitrary multivector has a lot of multiplications of different elements, it turns out. I implemented it into a new class in my junk-drawer math library, though my implementation is sadly restricted to 3d atm, since that’s all I needed. https://github.com/Erhannis/MathNStuff/blob/master/src/main/java/com/erhannis/mathnstuff/Multivector.java But through testing, I found out some interesting things – in my test case, at least, for example, as you multiply “bavab” from left to right, you start with b is a vector, then ba is a scalar+bivector, then bav is a vector+trivector, then bava is a bivector, then bavab is back to a plain vector. I expect that requires the palindrome structure to come back around to a plain vector, though I haven’t tested it. Anyway, thanks! It was a very aggravating evening, but having pieced together enough things I now have another way of thinking about the world.

      • Erhannis says:

        (Oops, in my second/response post I used the wrong link; it should have been https://www.euclideanspace.com/maths/algebra/clifford/d3/arithmetic/index.htm , rather than functions/index.htm )