Loading editor...

3D rotation matrices

2. 3D rotation matrices

Rotations in 3D space are more complex than in 2D space. In 2D space, we can describe a rotation with just one angle (assuming center of rotation is the origin). In 3D space, there are many ways to describe a rotation but they can roughly be categorized into two types:

  • rotations around the axes (Davenport rotations, Euler angles)
  • axis-angle representation (Euler-Rodrigues formula, quaternions)

Let's start with rotations around fixed coordinate axes since they are simplest to define and other rotations can be defined as a composition of these simpler rotations.

Rotations in 3D introduce a new concept: the axis of rotation. A common way is to describe any rotation as a composition of rotations about the x-, y- and z- axes.


2.1 3D Rotations are NOT commutative

Using the same logic used in 2D rotations above, the rotation matrices for rotations about the x-, y- and z-axes by an angle are:

  • Around x-axis:
  • Around y-axis:
  • Around z-axis:

Rotations in 2D commute but in any higher dimension they don't commute.

Rotating about the x-axis and then the y-axis gives a different result than rotating about the y-axis and then the x-axis. This is visualized below:

  • Set up

Rotate the left cube first: then :

  • the left cube by 60 degrees about x-axis.
  • Then it by 30 degrees about y-axis.

Rotate the right cube next: then :

  • Then it by 30 degrees about y-axis.
  • the left cube by 60 degrees about x-axis.

It is clear that they end up in different orientations.


2.2 Intrinsic and extrinsic rotations

In 3D space, we can rotate a vector about the x-axis, y-axis or z-axis. These axes are fixed and such rotations are called extrinsic rotations. Now imagine that a rotation also rotates the axes. Eg consider a rotation about z-axis followed by x-axis. Rotating about the z-axis also rotates the x and y-axes. Then the second rotation is with respect to the rotated x-axis.

Imagine the x-, y- and z-axes attached to an aircraft. These axes are initially aligned with the fixed axes. When the aircraft rotates about z-axis, the x- and y-axes attached to the aircraft also rotate. The next rotation can be described with respect to rotated x-axis. These rotations are called intrinsic rotations. Note that the aircraft continue to point in the (intrinsic) x-axis direction after the rotation as well.

We want to find the connection between intrinsic rotations and extrinsic rotations.

These two kinds of rotations are just a special case of change of basis. An intrinsic rotation is a change of basis followed by a rotation. Using our knowledge of change of basis, we can map an intrinsic rotation to an extrinsic rotation. First, let's see how the same set of rotations is described using intrinsic and extrinsic rotations.

We rotate a vector in two different ways.


2.2.1 Extrinsic rotations

Image the screen as the 2D plane with in the plane, and the z-axis pointing outwards perpendicular to the screen.

In this view, a 3D vector looks like a 2D vector .

Thus the input vector looks like .

  • The vector is .
    • The rotation matrix for this transform is .
  • And then by .
    • The rotation matrix for this transform is .

The final rotation matrix is .

This composition of rotations and the final rotated vector can be described like so:

When viewed on the 2D plane, .

from scipy.spatial.transform import Rotation

# lower case axis names imply extrinsic rotations
# r = rotation about z-axis by 30 degrees followed by rotation about x-axis by 180 degrees
r = Rotation.from_euler('zx', [30,180], degrees=True)
print(r.as_matrix())

'''
Output
- note that cos(30) ≈ 0.866 and sin(30) = 0.5
- the matrix is the same as what we just calculated above
'''
[[ 8.66025404e-01 -5.00000000e-01  0.00000000e+00]
 [-5.00000000e-01 -8.66025404e-01 -1.22464680e-16]
 [ 6.12323400e-17  1.06057524e-16 -1.00000000e+00]]

2.2.2 Intrinsic rotations

In this case, we have the same setup of and the .

  • The first rotation rotates not just the vector but also the x- and y-axes:

The rotated vector still has the same coordinates in this new basis with rotated x- and y-axes. In other words, the vector is still in the basis defined by the rotation matrix .

Now the second rotation is about the x-axis. In this case, is also rotated.

  • The second rotation about the x-axis ends up .

The coordinates of the vector in the new basis are . To get the coordinates of the vector in the original basis, we simply multiply the rotated vector by the basis matrix . Thus, the final rotation matrix is .

Indeed you can verify that:

The matrix can also be interpreted as a composition of two rotations around the fixed axes: a 180 degree rotation about the x-axis followed by a 30 degree rotation about the z-axis.

from scipy.spatial.transform import Rotation

# upper case axis names imply intrinsic rotations
# r = _intrinsic_ rotation about z-axis by 30 degrees followed by rotation about x-axis by 180 degrees
r = Rotation.from_euler('ZX', [30,180], degrees=True)
print(r.as_matrix())

'''
Output
- note that cos(30) ≈ 0.866 and sin(30) = 0.5
- the matrix is the same as what we just calculated above
'''
[[ 8.66025404e-01  5.00000000e-01  6.12323400e-17]
 [ 5.00000000e-01 -8.66025404e-01 -1.06057524e-16]
 [ 0.00000000e+00  1.22464680e-16 -1.00000000e+00]]

2.3 Euler angles

Euler angles are an extension of the idea of intrinsic rotations. They involve three rotations about the (intrinsic) axes by three angles . The three axes of rotations have the format axis 1 → (rotated) axis 2 → (twice rotated) axis 1 where each axis is one of the x-, y- or z-axes. There are 6 such combinations:

Each rotation not only rotates the vector but also the remaining two axes. The single and double ticks denote that these axes are intrinsic axes.

Now consider the rotation by angles . The corresponding rotation matrices are . Using the same logic as above, we can consider the first rotation as a change of basis. The second and third rotations can also be considered change of bases. Note that after each change of basis, the vector coordinates in the new basis remain the same. Thus the coordinates of the (thrice rotated) vector in the original basis is .

from scipy.spatial.transform import Rotation

# upper case axis names imply intrinsic rotations
# r = three 90 degree intrinsic rotations about x, z and x axes respectively
r = Rotation.from_euler('XZX', [90,90,90], degrees=True)
print(r.as_matrix())

'''
Output
'''
[[ 2.22044605e-16 -1.89526925e-16  1.00000000e+00]
 [ 1.89526925e-16 -1.00000000e+00 -1.89526925e-16]
 [ 1.00000000e+00  1.89526925e-16 -2.22044605e-16]]

2.3.1 Intrinsic to extrinsic rotations and vice versa

Note that the composition of rotations can be interpreted in two different ways.

  1. Consider the rotations as intrinsic rotations, which we have already covered.
  2. Consider the rotations as extrinsic rotations. In this interpretation, all rotations occur around the fixed x-, y- and z-axes. The first rotation is about the z-axis by an angle , the second rotation is about the new x-axis by an angle and the third rotation is about the new z-axis by an angle .

Thus, an intrinsic rotation around the axes by angles is equivalent to an extrinsic rotation around the axes by angles .


← 2D rotations · Quaternions →