explainer
Axis-angle rotation: build Rodrigues’ formula from three vector terms
Rotate a vector around any nonzero axis. Normalize the direction, follow Rodrigues’ parallel and perpendicular terms, and understand the equivalent descriptions at zero and 180 degrees.
What you will learn
- Normalize a nonzero rotation axis and apply a signed angle with a stated convention.
- Calculate the parallel, cosine, and cross-product terms of Rodrigues’ formula.
- Connect the vector formula to a three-by-three rotation matrix.
- Explain why zero-angle and half-turn rotations have nonunique axis descriptions.
Before you start
Rotating (1, 0, 1) by 90° around the z axis gives (0, 1, 1). The z part stays put while the x-y part turns. Rodrigues’ rotation formula applies that same idea to an axis pointing in any direction.
You will split the vector into pieces, calculate their new directions, and add them back together. This makes the formula useful beyond a memorized three-by-three matrix.
Describe one turn by its axis and angle
An axis-angle representation specifies a unit direction u and an angle θ. Every proper three-dimensional rotation can be represented this way. The axis is a line through the origin, and u gives that line an orientation.
This lesson uses active rotations, column vectors, and a fixed right-handed orthonormal frame. The geometric vector moves, while its old and new coordinates use the same frame. Positive θ follows the right-hand rule around u: point your right thumb along u and curl your fingers in the turning direction.
For u = (0, 0, 1), a positive quarter-turn carries +x toward +y. The rotation-matrices lesson uses the same convention. A coordinate-frame change is a separate operation, with source and destination labels.
The pair describes the resulting orientation change, not the history of turns used to reach it. Modern Robotics introduces this representation as a unit axis combined with an angle.
Normalize the axis before rotating
Convert an entered direction a to a unit axis:
u = a / ‖a‖₂, provided ‖a‖₂ > 0
The directions (0, 0, 1) and (0, 0, 2) produce the same u. Axis magnitude does not double the angle. Using the unnormalized direction directly in a formula that assumes unit length can produce a transformation that stretches vectors.
The zero vector has no direction and cannot be normalized. The experiment reports that input as invalid and requires a nonzero axis, even at θ = 0. Any chosen unit axis works for the identity; the zero vector cannot supply one.
The controls show degrees, while the trigonometric functions in code take radians. Convert with θ_rad = θ_deg × π/180. The unit axis is dimensionless and uses the same frame as the input vector.
Separate the three vector terms
First project v onto the unit axis:
v∥ = u(u · v)
v⊥ = v − v∥
The parallel part stays fixed. The perpendicular part lies in the plane that turns around u. Within that plane, u × v points a positive quarter-turn from v⊥ and has the same length as v⊥.
Rotate in that plane with a cosine-and-sine combination:
v′ = v∥ + v⊥ cos θ + (u × v) sin θ
The experiment calls these the parallel term, cosine term, and cross term. Its cosine term uses v⊥, excluding the unchanged axial part. Substituting the definitions gives the common form of Rodrigues’ formula:
v′ = v cos θ + (u × v) sin θ + u(u · v)(1 − cos θ)
Both forms give the same result, although they group the terms differently. The University of Illinois derives this formula by rotating within the perpendicular plane. Review the cross product if its sign or magnitude is unfamiliar.
Calculate a quarter-turn and a diagonal turn
Use a = (0, 0, 2), v = (1, 0, 1), and θ = 90°. Normalization gives u = (0, 0, 1), and u · v = 1.
| Quantity | Value |
|---|---|
| Parallel part v∥ | (0, 0, 1) |
| Perpendicular part v⊥ | (1, 0, 0) |
| Cross product u × v | (0, 1, 0) |
| Cosine term, since cos 90° = 0 | (0, 0, 0) |
| Cross term, since sin 90° = 1 | (0, 1, 0) |
| Sum v′ | (0, 1, 1) |
Input and output both have length √2 and signed projection 1 onto u. The axial part survives while the perpendicular part turns through a quarter-circle.
Now use u = (1, 1, 1)/√3, θ = 120°, and v = (1, 0, 0). The three terms are:
- Parallel: (1/3, 1/3, 1/3).
- Cosine: (−1/3, 1/6, 1/6), using cos 120° = −1/2.
- Cross: (0, 1/2, −1/2), using sin 120° = √3/2.
Their sum is (0, 1, 0). This rotation cycles the basis directions: x goes to y, y to z, and z to x. Its axis does not align with a coordinate axis.
Inspect the terms and their projections
The initial state reproduces the z-axis quarter-turn. The three terms connect head to tail in each projection, ending at the rotated vector.
Both views use the same coordinate scale. The xy view omits z; the xz view omits y. A term can appear as a point because all of its change occurs along the omitted coordinate.
Read the full three-coordinate values when terms overlap. Axis projection before and after give the signed scalar u · v. That value remains unchanged by this rotation.
Choose 120° about the diagonal to reproduce the second calculation. With Input parallel to axis, the perpendicular and cross terms vanish, so the vector stays fixed for every angle. Zero vector also stays zero, while the axis still defines a rotation of other vectors.
Starting from the default, set Axis z to 1. Normalization keeps the same rotation. Set it to zero, leaving all three components zero, and the experiment reports the invalid axis without substituting another direction or retaining a stale output.
The axis controls use half steps from −2 to 2. Angles use 15° steps from −180° to 180°. Coordinates display three decimals while calculations retain their precision.
Build the skew matrix with the correct sign
Define K so that multiplying by it computes u × v:
K = [u]× =
[0, −u_z, uᵧ;
u_z, 0, −uₓ;
−uᵧ, uₓ, 0]
Kv = u × v
K is skew-symmetric: Kᵀ = −K. For u = (0, 0, 1), K(1, 0, 0) = (0, 1, 0). Reversing the cross-product order reverses that sign and the intended positive turn.
Rodrigues’ matrix form is:
R = cos θ I + sin θ K + (1 − cos θ)uuᵀ
R = I + sin θ K + (1 − cos θ)K²
For unit u, K² = uuᵀ − I, which makes the expressions equivalent. Applying R to a column vector recovers the vector formula. For the z unit axis, R becomes the familiar z-axis rotation matrix.
With θ in radians, the second expression also equals exp(θK), the matrix exponential. Modern Robotics derives this form from constant angular velocity. The experiment evaluates the closed formula directly.
Check what the rotation preserves
The parallel part is perpendicular to the plane containing the other two terms. Within that plane, v⊥ and u × v are perpendicular and have equal lengths. Using cos²θ + sin²θ = 1 gives:
‖v′‖₂² = ‖v∥‖₂² + ‖v⊥‖₂² = ‖v‖₂²
u · v′ = u · v
The full matrix satisfies RᵀR = I and det(R) = +1. Its transpose undoes the turn: R(u, θ)ᵀ = R(u, −θ). The experiment uses that transpose to calculate Recovered input.
The axis itself stays fixed: Ru = u. One unchanged vector parallel to u does not make R the identity; other vectors can still turn.
For points rotated about an axis through a different pivot c, subtract c, rotate, then add c back: p′ = c + R(p − c). Homogeneous transformations combine those translations with the rotation.
Recognize equivalent descriptions
Reversing both signs leaves the rotation unchanged: R(−u, −θ) = R(u, θ). Adding any integer multiple of 360° to θ also gives the same final rotation.
Two boundary cases matter:
- Zero angle: R is the identity for every unit axis. The identity has no preferred axis.
- 180°: R = 2uuᵀ − I. Replacing u with −u leaves that matrix unchanged; its axis line remains meaningful while the sign is ambiguous.
For a principal angle strictly between 0° and 180°, the complete rotation determines an oriented unit axis. MTEX documents the identity and half-turn ambiguities. These uniqueness statements require the complete rotation. One input-output vector pair can leave multiple rotations possible.
For example, a half-turn about (1, 1, 0)/√2 sends (1, 0, 0) to (0, 1, 0). The opposite axis gives the same full matrix. At a general angle such as 90°, reversing the axis alone gives the inverse rotation.
Combining the pair as φ = θu, with θ in radians, gives a rotation vector, also called exponential coordinates. Its length is |θ|. The zero rotation vector encodes identity, but its direction cannot supply a unique axis; the experiment separately requires an axis and angle.
Euler angles describe a sequence of named-axis turns. Unit quaternions encode a rotation using the axis and half-angle. Each representation needs a stated convention and has rules for equivalent coordinates.
Reproduce the calculation in Python
This standard-library example normalizes the entered axis and evaluates the decomposed formula. It rejects a zero or nonfinite axis. The inputs below contain three finite coordinates; the formatter only rounds what you see.
from math import cos, sin, radians, hypot, isfinite
def unit_axis(axis):
if not all(isfinite(x) for x in axis):
raise ValueError("Axis components must be finite")
maximum = max(abs(x) for x in axis)
if maximum == 0:
raise ValueError("Axis must be nonzero")
scaled = tuple(x / maximum for x in axis)
length = hypot(*scaled)
return tuple(x / length for x in scaled)
def rotate(vector, axis, degrees):
u = unit_axis(axis)
theta = radians(degrees)
projection = sum(a * b for a, b in zip(u, vector))
parallel = tuple(x * projection for x in u)
cross = (u[1] * vector[2] - u[2] * vector[1],
u[2] * vector[0] - u[0] * vector[2],
u[0] * vector[1] - u[1] * vector[0])
return tuple(parallel[i] + (vector[i] - parallel[i]) * cos(theta)
+ cross[i] * sin(theta) for i in range(3))
def show(vector):
clean = (0.0 if abs(x) < 0.0005 else x for x in vector)
return "(" + ", ".join(f"{x:.3f}" for x in clean) + ")"
axis, vector = (0, 0, 2), (1, 0, 1)
u = unit_axis(axis)
output = rotate(vector, axis, 90)
print("Unit axis:", show(u))
print("Rotated:", show(output))
print(f"Output length: {hypot(*output):.3f}")
print(f"Axis projection: {sum(a * b for a, b in zip(u, output)):.3f}")
print("Recovered:", show(rotate(output, axis, -90)))
print("Diagonal 120:", show(rotate((1, 0, 0), (1, 1, 1), 120)))
Expected output:
Unit axis: (0.000, 0.000, 1.000)
Rotated: (0.000, 1.000, 1.000)
Output length: 1.414
Axis projection: 1.000
Recovered: (1.000, 0.000, 1.000)
Diagonal 120: (0.000, 1.000, 0.000)
For numerical work near zero angle, 1 − cos θ = 2 sin²(θ/2) avoids subtracting nearly equal values. Recovering an axis from a measured matrix also needs care near 0° and 180°. This experiment constructs rotations from a supplied axis and does not implement that inverse conversion.
Try it yourself
Exercise 1. Rotate v = (1, 1, 0) by +90° about the entered axis a = (0, 2, 0). Find the unit axis, the three terms, the output, and its signed projection onto the axis.
Show solution 1
The unit axis is u = (0, 1, 0). Since u · v = 1, the parallel term is (0, 1, 0). The perpendicular part is (1, 0, 0), and its cosine term vanishes at 90°.
The cross term is u × v = (0, 0, −1). Adding gives v′ = (0, 1, −1). The signed axial projection stays 1, and the length stays √2.
Exercise 2. Use axis u = (1, 1, 0)/√2 and angle 180°. Where does v = (1, 0, 0) go? What changes if you reverse the axis sign, and why does a zero-angle rotation have more axis freedom?
Show solution 2
The parallel part is (1/2, 1/2, 0), and the perpendicular part is (1/2, −1/2, 0). At 180°, cosine is −1 and sine is zero. The sum is (0, 1, 0).
Reversing the axis leaves 2uuᵀ − I unchanged, so it gives the same complete half-turn. At zero angle, the matrix is I for every unit axis, allowing any axis line as well as either sign.
Continue with unit quaternions to compose rotations using the same axis and angle. Keep the frame and sign conventions alongside the new coordinates.
Sources and further study
- University of Illinois: Rotations and angular velocity. Rodrigues’ vector formula and its perpendicular-plane derivation.
- Modern Robotics: Exponential Coordinates of Rotation, Part 1. Unit axes, angles, and rotation vectors.
- Modern Robotics: Exponential Coordinates of Rotation, Part 2. The skew matrix and Rodrigues’ matrix-exponential form.
- MTEX: Defining rotations. Active rotations, axis-angle conventions, and the special cases at identity and 180°.