Page 3: Axis Angle Representations
CS559 Spring 2023 Sample Solution
Axis Angle Representation
With Euler Angles, we built rotations by using the “building block” of rotations about coordinate axes. We rotate around the X, Y or Z axis.
We can actually rotate about any axis. As we mentioned on page 1, we can represent any rotation as a single rotation about some axis. The only trick is that we need to specify the axis. (contrast this with Euler Angles that require 3 rotations, but around pre-determined axes).
This leads to a different way to represent a rotation: we can provide the direction of the axis (a vector), and an amount to rotate around that axis. This is called axis angle.
As an aside… both of these representations were invented by mathmetician Leonard Euler, and are consequences of his basic theorems about rotation.
You can try it with this gadget. On the left, we have Euler Angles (which you should be used to by now). On the right, we have Axis Angle form - note how it has 4 numbers (3 for the vector of the axis, one for the amount of rotation around that axis). With the gadget, the axis of rotation is shown by the yellow cylinder.
You can see that if you set the axis to be one of the coordinate axes (the default setup has the vector as 0,0,1 - or the Z axis), it is the same as a rotation about that axis. But try making the vector be something else. For example, set the axis to be 1,1,1 (so the cylinder is pointing “diagonally”) and note how the object rotates around this axis.
With axis-angle form, we ignore the magnitude of the vector - we just use its direction. Things break if the vector has zero length.
Axis angle form is useful if the object naturally has some axis to rotate around. If you want to make a particular rotation, it can be difficult to figure out what the right axis is.
The rest of the page gives an example where axis angle form is useful that can help appreciating the difference between axis angles and Euler Angles.
Box 1: A simple example that isn’t so simple
The real learning goal of this page is to get you to think about axis angle representations. To do that, we will use an example you have seen before: trying to understand what is going on in the first spinning cube demo in Workbook 6.
The code is in 07-03-01.js ( 07-03-01.html) (it’s the same as on page 1 of Workbook 6). The key lines are:
|
|
07-03-01
Notice that this animation loop causes a somewhat complicated motion - it goes left and right, even though it moves through a simple progression in Euler Angles (incrementing by 0.5*timeDelta
each frame) … THREE’s built in Euler Angles are XYZ.
What is going on here is that each time we change the X rotation, which changes the meaning of the Y rotation. So we don’t get a simple motion as we might have expected.
For the first Euler angles, that first step would be: $ R_x(.01) \circ R_y(.01) $
(rotation about X followed by a rotation about Z). If we wanted to continue another step, we could repeat that, composing those same rotations again.
$$R_x(.01) \circ R_y(.01) \circ R_x(.01) \circ R_y(.01) \neq R_x(.01+.01) \circ R_y(.01 + .01)$$
The left side of that inequality would be uniform steps. The right side is what we did when we just added to the Euler Angles. Since you read Page 1 (Rotations in 3D), you were reminded that just because $ R_x(\alpha) \circ R_x(\beta) = R_x(\alpha+\beta) $
, this doesn’t work when there’s a rotation about Y stuck in between.
Box 2: A Simpler Rotation
What if we wanted to keep rotating in the direction we started rotating in on that first step? We could on every frame apply the transformations. We could change the two angle additions to:
|
|
But a thing to note is that this does not lead to a simple progression of the Euler Angles. In fact, after the second step, we would get a configuration that requires a bit of the Y rotation.
We can think of this as follows: the sequence of rotations $R_x(.01)$
and $R_z(.01)$
is equivalent to a single rotation about some other axis. (The Axis is the vector (.712,-0.0178,.712) if you really want to know - but we’ll explain how to figure that out in a moment).
So, if we wanted to just keep spinning around that axis, we could instead write:
cube.rotateOnAxis(axis, angle);
where axis
is the vector we figured out before, and angle is an amount to rotate about that axis.
In the demo below, you can see these three different versions. For the Euler addition thing, you can see it wobbling all over the place. For the two rotation composition motions, you see the same consistent motion around an axis. We’ve drawn the axis as a white line to make it clearer. We compute axis
and angle
to be the same step as the Euler increment. Over the course of many steps, you’ll see they become a little bit different because of rounding errors.
Try starting from zero and going a step at a time. On the first step, all three are the same. But after that, notice how on each step, the Euler incrementing version has a simple increment of the Euler Angles, but the axis angle representation changes (the axis changes on each frame). In contrast, the other two (which, as expected, have the same motion) keep the same axis and step around it uniformly.
Now, you might wonder, given the Euler angles (like the step increment above) how do I convert it to axis angle? The good news is that THREE has a lot of code to help with doing these conversions. However, for this specific one, we first need to convert to a different form (called a Quaternion), because this is what THREE supports the best. In the code (file for_students/07-03-02.js
), you can see a function called “axisAngle” that converts an Euler Angle to axis angle form. It will make sense after we talk about Quaternions on the next page.
After playing with the incremental comparison toy (below and 07-03-02.js ( 07-03-02.html)), go on to Page 4 (Quaternions) where we’ll see how we extend axis angle representations into Unit Quaternions.