1
\$\begingroup\$

When working with rotations expressed as angles, it makes sense to be able do to something like

void GameLoop::update(){
     pawn.rotation.x += 0.01;
}

And slowly watch the model rotate. However when I tried to do the same thing with a Quaternion based rotation, I observed that the rotation did not behave as expected. For context I'm using GLM's Quaternion implementation. What is the best known method for updating and interacting with Quaternions? should I convert the Quat back to Euler angles, do the update and then store the updated value, or is there a Quat analog to += 0.01 that is considered standard? Am I wrong for storing a model's rotation as a Quaternion in the first place?

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Applying the rotation that a quaternion represents is done via multiplication. This is really neat, because it works on vectors, like so:

v2 = q * v1

but also on other quaternions:

q2 = q * q1

...which means that combining rotations is quite easy. The downside is that, compared to euler angles, it's a bit more difficult to immediately translate between your intuition of what a rotation is like and its quaternion representation (although I find that quaternion rotations seem far less arcane if you think about angle-axis rotations, since there is a very straightforward conversion between the two).

For your case, since you know the Euler representation of the rotation you want, you might want to just convert that directly to a quaternion and multiply it by the current rotation every frame (note that the order matters, quaternion multiplication is not commutative).

I'm not sure if glm has a built-in conversion between the two models, but the answer I linked before has several examples of how to implement one if you need it. So, once you have the eulerToQuaternion function, you can do something like this:

Quaternion q = eulerToQuaternion(0.01, 0, 0);
void GameLoop::update(){
     pawn.rotation = q * pawn.rotation;
}

Also, as to whether it's a good idea to use quaternions or not, it kind of depends on what exactly you are doing, but I think the general consensus is that yes, they are the most convenient way to work with rotations. The wikipedia page on the subject says:

Compared to rotation matrices, quaternions are more compact, efficient, and numerically stable. Compared to Euler angles, they are simpler to compose. However, they are not as intuitive and easy to understand and, due to the periodic nature of sine and cosine, rotation angles differing precisely by the natural period will be encoded into identical quaternions and recovered angles in radians will be limited to [ 0 , 2 π ].

Which sums it up pretty well, I think.

\$\endgroup\$
1
  • \$\begingroup\$ It might be worth mentioning that the order of rotation matters: q * q1 gives the result of rotating the object by q1 and then by q with respect to the world axes, or equivalently by q1 and then ``q1` with respect to the object's local axes. Either way, you get a shift from "more local" on the right to "more global" on the left. q1 * q reverses the sequence. \$\endgroup\$
    – DMGregory
    Oct 31, 2022 at 12:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .