a2.0.0 (major) - Quaternion Pairs


So for a while I’ve been struggling with handling 4D rotations internally.

Right up until now I used to use Euler angles (rotating a point using an angle in the planes XW, YW, ZW, XY, XZ, YZ) and I’ve been having a lot of issues:

  • Rotation order: I couldn’t just add to a rotation variable and then every frame rotate every point by that variable. Because the order that rotations are applied matters. Embarassingly, I didn’t figure out that this was the cause for my initial problems for the longest time.
  • How do I rotate a vector along its relative planes? Euler angles are really just for world space. Maybe there’s some way to get around this, but if there is, it’s probably not very easy.

So I found a pretty weird workaround. Basically, instead of rotating the camera, I continously moved and rotated every vertex relative to the camera and rendered that. This worked, but it had a couple of issues:

  • The code was a mess. Because you couldn’t just have a camera rotation and position, but had to instead move every point relative to it… it was not particularly easy to work with.
  • Now, how do I rotate a vector along world space? Since the “world space” is now relative to the camera, we got our original problem again.
  • Not being able to save and load rotations: Sure I could store the Euler angles, but it’d be useless unless I find some way to encompass the rotation order.
  • Floating point: While I didn’t notice that, I figure even if I did just decide to continue like this and store every point as rotated, I figure over time small floating point errors would accumulate, since I’m applying rotations to already rotated points instead of re-calculating the rotations.

Most of the time, when the problems of Euler angles are mentioned, “Gimbal Lock” is a magic word that’s used. Do I understand what it is? Kind of, yeah. But I don’t think this does a great job at explaining the practical issues that I had at least with Euler angles.

So okay. What’s the alternative? For 3D rotations, quaternions. So I looked up how to use those in 4D. Apparently, it’s possible, but not with a single quaternion - to be able to describe every rotation in 4-dimensional space (also called SO(4)) you need two quaternions: A quaternion pair.

Cool. In theory. Well in practice as well, unless you’re an idiot like me. See, for the longest time I not only had the difficult task of figuring out what the heck quaternions really are in the first place, but also how to use them in 4D?? And since quaternions are 4D numbers, you can imagine it was a pain to not find resources about quaternions in general but specifically about quaternions to describe 4-dimensional rotations. The fact that there were barely any resources on this to begin with did not make this better.

In my research, I also stumbled upon what seems to be the most commonly used approach to handle 4D rotations: Rotor4. Whatever the hell that is. Since I didn’t want to bother to start from 0 again, I decided to stick with quaternion pairs unless I find an absolute reason to not use them.

Up until I stumbled upon this StackExchange answer by Jim Belk. Even though my smooth brain nearly had a short circuit trying to understand this, this answer had basically all information that I had needed. After a lot of trial and error, I finally got quaternion pair rotation to work.

And honestly, it’s beautiful. You can basically use the Rotation4 class I made like a normal quaternion, but for 4D rotation. It uses two quaternions internally, leftQuaternion and rightQuaternion, and applying a rotation to a point is super easy, whether it is in world space or relative to the vector itself, and the order does not matter, both quaternions can be in any order when applied to a vector.

I don’t know why most 4D projects I’ve taken a look at seem to use the Rotor4 approach; I guess maybe for even more complex tasks such as a physics engines quaternion pairs might not make the cut either. Though I assume it really just came from a thought process like “it’s not possible to use a single quaternion to represent four-dimensional rotations, so that would mean I’d have to use something completely different”, or maybe because one person did it and so everyone else just followed. Or maybe Rotor4 is actually superior to quaternion pairs, I don’t know. For now it’s working pretty well at least, though.

If you’re curious about my implementation, here are the relevant parts:

Other changes I made in this update:

  • You can view and edit the two quaternion values in the bottom left panel using the switch button.
  • Euler rotation is now purely relative - dragging the sliders around will apply a continuous delta to each plane.
  • Added a continously rotating tesseract object (rotating in the XY plane) to the main scene. This would not have been possible without the new rotation system!
  • Added a FixedRotationalPlanes scene. It contains all four axes with all six planes of rotation, and a 3D cube next to it.
  • More small tweaks such as an FPS counter in the top right.

Nobody’s probably going to see this but hey, it’s cool to get my thoughts written down somewhere at least :) Plus, if even just one person reads this develog and is at least remotely interested, I can consider it a win.

Files

a2-0-0_webgl.zip Play in browser
Jul 15, 2025

Get 4D Simulation

Download NowName your own price

Leave a comment

Log in with itch.io to leave a comment.