Home Subscribe

3. Rotation Matrix About an Arbitrary Axis

rotation-about-arbitrary-axis
Figure 5. Rotation about an arbitrary axis.

To perform a rotation about an arbitrary axis through the origin, OXYZ is taken to be the fixed frame. A mobile coordinate frame OABC is rotated through the origin \(O\) about a vector \(V = (x,y,z)\) with components \(V_x, V_y, V_z\). The arbitrary axis can be written as \(V = V_xi + V_yj + V_zk\). The rotation matrix \(R(V, O)\) comprises the following steps as illustrated by Figure 5.

  1. A rotation by angle \(\alpha\) about x-axis

  2. A rotation by angle \(-\beta\) about y-axis

  3. A rotation by angle \(\theta\) about z-axis

  4. A rotation by angle \(\beta\) about y-axis

  5. A rotation by angle \(-\alpha\) about x-axis

This rotation, \(R(V, O)\), may be summarized as \(R(V, O) = R(x,-\alpha) R(y,\beta) R(z,\theta) R(y,-\beta) R(x,\alpha)\).

The resultant rotation matrix about \(V\) is \(R(V, O)\)

\[\mathrm{R}(\mathrm{V}, O)=\left[\begin{array}{ccc} 1 & 0 & 0 \\ 0 & c \alpha & s \alpha \\ 0 & -s \alpha & c \alpha \end{array}\right]\left[\begin{array}{ccc} c \beta & 0 & s \beta \\ 0 & 1 & 0 \\ -s \beta & 0 & c \beta \end{array}\right]\left[\begin{array}{ccc} c \theta & -s \theta & 0 \\ s \theta & c \theta & 0 \\ 0 & 0 & 1 \end{array}\right] \left[\begin{array}{ccc} c \beta & 0 & -s \beta \\ 0 & 1 & 0 \\ s \beta & 0 & c \beta \end{array}\right]\left[\begin{array}{ccc} 1 & 0 & 0 \\ 0 & c \alpha & -s \alpha \\ 0 & s \alpha & c \alpha \end{array}\right]\]

Let

\[|V| = \sqrt{V_x^2+V_y^2+V_z^2} \sim 1 \text{unit}\]

From the geometry of Figure 5 it follows that,

\[\begin{array}{ll} \sin \alpha=s \alpha=\frac{\mathrm{V}_y}{\sqrt{\mathrm{V}_y^2+\mathrm{V}_z^2}}, \quad & c \alpha=\cos \alpha=\frac{\mathrm{V}_z}{\sqrt{\mathrm{V}_y^2+\mathrm{V}_z^2}} \\ \sin \beta=s \beta=\frac{\mathrm{V}_x}{V} = \mathrm{V}_x & \text { and } \cos \beta=c \beta=\sqrt{\mathrm{V}_y^2+\mathrm{V}_z^2} \end{array}\]
\[\begin{align} \mathrm{R}(\mathrm{V}, O) &= \left[\begin{array}{ccc}\mathrm{V}_{x}^{2}(1-c \theta)+c \theta, & \mathrm{V}_{x} \mathrm{~V}_{y}(1-c \theta)-\mathrm{V}_{z} s \theta, & \mathrm{V}_{x} \mathrm{~V}_{z}(1-c \theta)+\mathrm{V}_{y} s \theta \\\mathrm{V}_{x} \mathrm{~V}_{y}(1-c \theta)+\mathrm{V}_{z} s \theta, & \mathrm{V}_{y}^{2}(1-c \theta)+c \theta, & \mathrm{V}_{y} \mathrm{~V}_{z}(1-c \theta)-\mathrm{V}_{x} s \theta \\\mathrm{V}_{x} \mathrm{~V}_{z}(1-c \theta)-\mathrm{V}_{y} s \theta, & \mathrm{V}_{y} \mathrm{~V}_{z}(1-c \theta)+\mathrm{V}_{x} s \theta, & \mathrm{V}_{z}^{2}(1-c \theta)+c \theta\end{array}\right] \\ \mathrm{R}(\mathrm{V}, O) &= \left[\begin{array}{ccc}\mathrm{V}_{x}^{2}T+C, & \mathrm{V}_{x} \mathrm{~V}_{y}T-\mathrm{V}_{z} S, & \mathrm{V}_{x} \mathrm{~V}_{z}T+\mathrm{V}_{y} S \\\mathrm{V}_{x} \mathrm{~V}_{y}T+\mathrm{V}_{z} S, & \mathrm{V}_{y}^{2}T+C, & \mathrm{V}_{y} \mathrm{~V}_{z}T-\mathrm{V}_{x} S \\\mathrm{V}_{x} \mathrm{~V}_{z}T-\mathrm{V}_{y} S, & \mathrm{V}_{y} \mathrm{~V}_{z}T+\mathrm{V}_{x} S, & \mathrm{V}_{z}^{2}T+C\end{array}\right] \\ \mathrm{R}\left(\mathrm{V}, O\right) &= \left[\begin{array}{lll}n_{x} & s_{x} & q_{x} \\n_{y} & s_{y} & q_{y} \\n_{z} & s_{z} & q_{z}\end{array}\right] \\ & \text { where, } \quad C =\cos \theta \text {, } \quad S =\sin \theta \text {, } \quad T = (1-cos \theta) \text{ .} \end{align}\]

We need to use the components of vector V about the principal axes of the OXYZ frame.

\[\begin{align*} V_{x} = \frac{x}{\sqrt{{x}^{2}+{y}^{2}+{z}^{2}}} \text {, } V_{y} = \frac{y}{\sqrt{{x}^{2}+{y}^{2}+{z}^{2}}} \text {, } V_{z} = \frac{z}{\sqrt{{x}^{2}+{y}^{2}+{z}^{2}}} \end{align*}\]

3.1. Rotation About an Arbitrary Axis Through the Origin

Idea

Example 1

Compute the rotation matrix to represent a rotation of \(90^o\) about an arbitrary vector \(V = (2, 2, 2)^T\).

Solution:
\[ \begin{aligned} & V_{x} = \frac{2}{2\sqrt{3}}, V_{y}=\frac{2}{2\sqrt{3}} \text {, and } V_{z}=\frac{2}{2\sqrt{3}} \\ \end{aligned}\]
\[ \begin{aligned} & C =\cos(90) = 0 \text {, } \quad S =\sin(90) = 1 \text {, } \quad T = (1-cos(90)) = 1 \\ & n_{x}=\mathrm{V}_{x}^{2}T+C=\left(\frac{2}{(2\sqrt{3})}\right)^2(1)+0=\frac{1}{3} \\ & n_{y}=\mathrm{V}_{x} \mathrm{~V}_{y}T+\mathrm{V}_{z} S=\frac{2}{2\sqrt{3}} \cdot \frac{2}{2\sqrt{3}}(1)+\frac{2}{2\sqrt{3}}(1)= \frac{1 + \sqrt{3}}{3} \\ & n_{z}=\mathrm{V}_{x} \mathrm{~V}_{z}T-\mathrm{V}_{y} S=\frac{2}{2\sqrt{3}} \cdot \frac{2}{2\sqrt{3}}(1)-\frac{2}{2\sqrt{3}}(1)= \frac{1 - \sqrt{3}}{3} \\ & s_{x}=\mathrm{V}_{x} \mathrm{~V}_{y}T-\mathrm{V}_{z} S=\frac{2}{2\sqrt{3}} \cdot \frac{2}{2\sqrt{3}}(1)-\frac{2}{2\sqrt{3}}(1)= \frac{1 - \sqrt{3}}{3} \\ & s_{y}=\mathrm{V}_{y}^{2}T+C=\left(\frac{2}{(2\sqrt{3})}\right)^2(1)+0= \frac{1}{3} \\ & s_{z}=\mathrm{V}_{y} \mathrm{~V}_{z}T+\mathrm{V}_{x} S=\frac{2}{2\sqrt{3}} \cdot \frac{2}{2\sqrt{3}}(1)+\frac{2}{2\sqrt{3}}(1)= \frac{1 + \sqrt{3}}{3} \\ & q_{x}=\mathrm{V}_{x} \mathrm{~V}_{z}T+\mathrm{V}_{y} S=\frac{2}{2\sqrt{3}} \cdot \frac{2}{2\sqrt{3}}(1)+\frac{2}{2\sqrt{3}}(1)= \frac{1 + \sqrt{3}}{3} \\ & q_{y}=\mathrm{V}_{y} \mathrm{~V}_{z}T-\mathrm{V}_{x} S=\frac{2}{2\sqrt{3}} \cdot \frac{2}{2\sqrt{3}}(1)-\frac{2}{2\sqrt{3}}(1)= \frac{1 - \sqrt{3}}{3} \\ & q_{z}=\mathrm{V}_{z}^{2}T+C=\left(\frac{2}{(2\sqrt{3})}\right)^2(1)+0= \frac{1}{3} \\ \end{aligned}\]
\[ \mathrm{R}\left(\mathrm{V}, 90^{\circ}\right)=\left[\begin{array}{ccc} \frac{1}{3} & \frac{1 - \sqrt{3}}{3} & \frac{1 + \sqrt{3}}{3} \\ \frac{1 + \sqrt{3}}{3} & \frac{1}{3} & \frac{1 - \sqrt{3}}{3} \\ \frac{1 - \sqrt{3}}{3} & \frac{1 + \sqrt{3}}{3} & \frac{1}{3} \end{array}\right]\]
The following is a Python code implementation of the above calculation (Click to reveal). This code implementation provides 3 outputs: a matrix in surd form, 4 decimal numerical values, and a latex format.

 1# orcid.org/0000-0002-7326-7502
 2import sympy
 3# Initialize the pretty-printing functionality
 4from sympy import init_printing
 5init_printing()
 6
 7# Define the vector V as a sympy matrix
 8V = sympy.Matrix([2,2,2])
 9
10# Calculate the angle in radians using sympy's pi function
11angle = 90
12angle = sympy.pi*angle/180
13
14# Calculate the length of V
15length = sympy.sqrt(V.dot(V))
16
17# Calculate the components of a vector about the principal axes 
18Vx = V[0]/length
19Vy = V[1]/length
20Vz = V[2]/length
21
22C = sympy.cos(angle)
23S = sympy.sin(angle)
24T = 1-C
25
26nx = ((Vx**2)*T) + C
27ny = Vx*Vy*T + (Vz*S)
28nz = Vx*Vz*T - (Vy*S)
29sx = Vx*Vy*T - (Vz*S)
30sy = ((Vy**2)*T) + C
31sz = Vy*Vz*T + (Vx*S)
32qx = Vx*Vz*T + (Vy*S)
33qy = Vy*Vz*T - (Vx*S)
34qz = ((Vz**2)*T) + C
35
36# Construct the rotation matrix Rv as a sympy matrix
37Rv = sympy.Matrix([[nx,sx,qx], [ny,sy,qy], [nz,sz,qz]])
38
39# Simplify the matrix using powsimp()
40simplified_Rv = Rv.applyfunc(sympy.powsimp)
41
42# Print the matrix in surd form
43print("\nmatrix in surd form:")
44sympy.pprint(simplified_Rv)
45
46# Convert the result to a sympy matrix
47transformation_matrix = Rv
48
49# Convert the symbolic values to numerical values with 4 decimal places
50transformation_matrix = transformation_matrix.applyfunc(lambda x: sympy.N(x, 4))
51
52# Display the transformation matrix in LaTeX-like format
53print("\nnumerical values with 4 decimal places:")
54sympy.pprint(transformation_matrix)
55
56print("\nlatex output:")
57print(sympy.latex(transformation_matrix))
python arbitrary axis

3.2. Rodrigues' Rotation Formula

An alternative would be to use Rodrigues' Rotation Formula (Rodrigues’ Rotation Formula – from Wolfram MathWorld, n.d.), which is similar to the derived matrix above. It is important to note that the Rodrigues formula only works for rotations about an axis through the origin.

\[\begin{align} \mathrm{R}(\mathrm{V}, O) &= e^{W\theta} \\ & = I + W \sin(\theta) + W^2(1-\cos(\theta))\\ & \text{where, }\\ I &= 3 \times 3 \text{ identity matrix } \\ W &= \left[\begin{matrix}0 & -V_z & V_y\\V_z & 0 & -V_x\\-V_y & V_x & 0\end{matrix}\right] \end{align}\]
The following is a Python code implementation of the above calculation (Click to reveal). This code implementation provides 3 outputs: a matrix in surd form, 4 decimal numerical values, and a latex format.

 1# orcid.org/0000-0002-7326-7502
 2from sympy import *
 3init_printing()
 4
 5# Define the x, y, and z components of the vector as symbols
 6x, y, z = symbols("x y z")
 7
 8# Define the vector as a SymPy Matrix
 9V = Matrix([x, y, z])
10V = Matrix([2, 2, 2])
11
12# Calculate the angle of rotation
13angle = 90
14theta = pi*angle/180
15
16# Calculate the magnitude of the vector
17magnitude = V.norm()
18
19# Calculate the components of a vector about the principal axes 
20Vxyz = V / magnitude
21
22C = cos(theta)
23S = sin(theta)
24T = 1-C
25
26I = eye(3) # 3x3 identity matrix 
27W = Matrix([[0, -Vxyz[2], Vxyz[1]],
28                [Vxyz[2], 0, -Vxyz[0]],
29                [-Vxyz[1], Vxyz[0], 0]])
30
31# Calculate the rotation matrix using the Rodrigues formula
32rotation_matrix = I + (W*S) + W**2*T 
33
34# Output the rotation matrix in surd form
35print("Rotation matrix in surd form:")
36pprint(powsimp(rotation_matrix))
37
38# Output the rotation matrix in 4 decimal places
39print("\nRotation matrix in 4 decimal places:")
40pprint( rotation_matrix.applyfunc(lambda x: N(x, 4)) )
41
42# Output the rotation matrix in LaTeX-like format
43print("\nRotation matrix (LaTeX-like format):")
44# pprint(sympy.latex(rotation_matrix))
45pprint(latex( rotation_matrix.applyfunc(lambda x: N(x, 4)) ))

Idea

Example 2

Compute the rotation matrix to represent a rotation of \(80^o\) about an arbitrary vector \(V = (2, 3, 4)^T\).

Solution:
\[ \begin{aligned} & V_{x}=\frac{2\sqrt{29}}{29}, V_{y}=\frac{3\sqrt{29}}{29} \text {, and } V_{z}=\frac{4\sqrt{29}}{29} \\ & C =\cos(80) = 0.1736 \text {, } \quad S =\sin(80) = 0.9848 \text {, } \quad T = (1-cos(80)) = 0.8264 \\ & n_{x}=\mathrm{V}_{x}^{2}T+C=\left(\frac{2\sqrt{29}}{29}\right)^2(0.8264)+0.1736= 0.2876 \\ & n_{y}=\mathrm{V}_{x} \mathrm{~V}_{y}T+\mathrm{V}_{z} S=\frac{2\sqrt{29}}{29} \cdot \frac{3\sqrt{29}}{29}(0.8264)+\frac{4\sqrt{29}}{29}(0.9848)= 0.9025 \\ & n_{z}=\mathrm{V}_{x} \mathrm{~V}_{z}T-\mathrm{V}_{y} S=\frac{2\sqrt{29}}{29} \cdot \frac{4\sqrt{29}}{29}(0.8264)-\frac{3\sqrt{29}}{29}(0.9848)= -0.3206 \\ \end{aligned}\]
\[ \begin{aligned} & s_{x}=\mathrm{V}_{x} \mathrm{~V}_{y}T-\mathrm{V}_{z} S=\frac{2\sqrt{29}}{29} \cdot \frac{3\sqrt{29}}{29}(0.8264)-\frac{4\sqrt{29}}{29}(0.9848)= -0.5605 \\ & s_{y}=\mathrm{V}_{y}^{2}T+C=\left(\frac{3\sqrt{29}}{29}\right)^2(0.8264)+0.1736= 0.4301 \\ & s_{z}=\mathrm{V}_{y} \mathrm{~V}_{z}T+\mathrm{V}_{x} S=\frac{3\sqrt{29}}{29} \cdot \frac{4\sqrt{29}}{29}(0.8264)+\frac{2\sqrt{29}}{29}(0.9848)= 0.7077 \\ & q_{x}=\mathrm{V}_{x} \mathrm{~V}_{z}T+\mathrm{V}_{y} S=\frac{2\sqrt{29}}{29} \cdot \frac{4\sqrt{29}}{29}(0.8264)+\frac{3\sqrt{29}}{29}(0.9848)= 0.7766 \\ & q_{y}=\mathrm{V}_{y} \mathrm{~V}_{z}T-\mathrm{V}_{x} S=\frac{3\sqrt{29}}{29} \cdot \frac{4\sqrt{29}}{29}(0.8264)-\frac{2\sqrt{29}}{29}(0.9848)= -0.0238 \\ & q_{z}=\mathrm{V}_{z}^{2}T+C=\left(\frac{4\sqrt{29}}{29}\right)^2(0.8264)+0.1736= 0.6295 \\ \end{aligned}\]
\[ \mathrm{R}\left(\mathrm{V}, 80^{\circ}\right)=\left[\begin{array}{ccc} 0.2876 & -0.5605 & 0.7766 \\ 0.9025 & 0.4301 & -0.0238 \\ -0.3206 & 0.7077 & 0.6295 \end{array}\right]\]
The following is a Python code implementation of the above calculation (Click to reveal). This code implementation provides 3 outputs: a matrix in surd form, 4 decimal numerical values, and a latex format.

 1# orcid.org/0000-0002-7326-7502
 2import sympy
 3# Initialize the pretty-printing functionality
 4from sympy import init_printing
 5init_printing()
 6
 7# Define the vector V as a sympy matrix
 8V = sympy.Matrix([2,3,4])
 9
10# Calculate the angle in radians using sympy's pi function
11angle = 80
12angle = sympy.pi*angle/180
13
14# Calculate the length of V
15length = sympy.sqrt(V.dot(V))
16
17# Calculate the components of a vector about the principal axes 
18Vx = V[0]/length
19Vy = V[1]/length
20Vz = V[2]/length
21
22C = sympy.cos(angle)
23S = sympy.sin(angle)
24T = 1-C
25
26nx = ((Vx**2)*T) + C
27ny = Vx*Vy*T + (Vz*S)
28nz = Vx*Vz*T - (Vy*S)
29sx = Vx*Vy*T - (Vz*S)
30sy = ((Vy**2)*T) + C
31sz = Vy*Vz*T + (Vx*S)
32qx = Vx*Vz*T + (Vy*S)
33qy = Vy*Vz*T - (Vx*S)
34qz = ((Vz**2)*T) + C
35
36# Construct the rotation matrix Rv as a sympy matrix
37Rv = sympy.Matrix([[nx,sx,qx], [ny,sy,qy], [nz,sz,qz]])
38
39# Simplify the matrix using powsimp()
40simplified_Rv = Rv.applyfunc(sympy.powsimp)
41
42# Print the matrix in surd form
43print("\nmatrix in surd form:")
44sympy.pprint(simplified_Rv)
45
46# Convert the result to a sympy matrix
47transformation_matrix = Rv
48
49# Convert the symbolic values to numerical values with 4 decimal places
50transformation_matrix = transformation_matrix.applyfunc(lambda x: sympy.N(x, 4))
51
52# Display the transformation matrix in LaTeX-like format
53print("\nnumerical values with 4 decimal places:")
54sympy.pprint(transformation_matrix)
55
56print("\nlatex output:")
57print(sympy.latex(transformation_matrix))

The formula for calculating the unit vector in the direction of a vector \(V = (x,y,z)\) is:

\(\text{unit_vector} = V / |V|\)

where \(|V|\) is the magnitude of the vector \(V\).

This formula is equivalent to:

\(\text{unit_vector} = (x/magnitude, y/magnitude, z/magnitude)\)

where \(\text{magnitude} = sqrt(x^2 + y^2 + z^2)\).

The formula for calculating the components of a vector V = (x,y,z) about the principal axes is:

\[V_x = x / sqrt(x^2 + y^2 + z^2)\\ V_y = y / sqrt(x^2 + y^2 + z^2)\\ V_z = z / sqrt(x^2 + y^2 + z^2)\]

The formulas for calculating the unit vector and the components of a vector about the principal axes may seem similar, but they are actually solving different problems.

The unit vector formula normalizes the vector to have a magnitude of 1, preserving the direction of the vector but setting the magnitude to 1. This allows for easier comparison of vectors, as the magnitude is not a factor.

On the other hand, the formula for calculating the components of a vector about the principal axes projects the vector onto each axis and divides by the magnitude of the vector. This allows for the vector to be described in terms of its position along each axis, rather than its direction.

The components of a vector about the principal axes can be used to represent the orientation of a vector in 3D space. This orientation can then be used to determine the axis of rotation and the angle of rotation, which are needed to calculate a rotation matrix using the above formulas.



Add Comment

* Required information
1000
Drag & drop images (max 3)
Out of 56, 14 or 27, which is the smallest?

Comments (4)

Avatar
New
Dr. Sam

Using the knowledge of spatial mechanics and computer programming introduced in this course, you can go on to perform advanced kinematic analysis of 3D mechanisms.

These skills apply to robotics systems design, research, and development.

Avatar
New
Joe Disamalu

The notes are on point. I've gained alot of skill and visualization from the unit.

Avatar
New
Aggrey

Does it mean the inverse of a 3x3 matrix same as its transpose

Upload
Avatar
New
Dr. Sam

In spatial mechanics, the inverse and transpose of a 3x3 matrix are not the same, but they can be related in specific cases. The inverse (A⁻¹) is a matrix that, when multiplied by A, results in the identity matrix (A * A⁻¹ = I). The transpose (Aᵀ) is obtained by interchanging the rows and columns of A.

For 3x3 orthogonal matrices, often used to represent rotations, the transpose is equal to the inverse (A⁻¹ = Aᵀ) because they satisfy Aᵀ * A = I. This property is unique to orthogonal matrices, and for general 3x3 matrices, the inverse and transpose are not the same.