Skip to content

Axis-angle, quaternion, and homogeneous transforms

To solve the gimbal lock problem, we can adopt a redundant parameterisation using an axis 𝒌=[𝑘𝑥,𝑘𝑦,𝑘𝑧] with ‖𝒌‖=1 and an angle 𝜃, resulting in four parameters overall.

Frame 0 in gray and frame 1 in blue

The rotation 𝑹𝒌(𝜃) can be found by transforming the coordinates of 𝒌:

  1. Given frame 1 with axes 𝑥1,𝑦1,𝑧1 (with 𝑧1 coincident with 𝒌), we can rotate frame 0 by 𝛼 about the 𝑧-axis and by 𝛽 around the 𝑦-axis.

    𝑹10=𝑹𝑧(𝛼)𝑹𝑦(𝛽)
  2. If a transformation 𝑨 is expressed in frame 1 as 𝑞1=𝑨𝑝1, then:

    𝑞0=(𝑹01)−1𝑨𝑹01𝑝0=𝑹𝑧(𝛼)𝑹𝑦(𝛽)𝑨(𝑹𝑧(𝛼)𝑹𝑦(𝛽))−1𝑝0

    which leads to:

    𝑹𝒌(𝜃)=𝑹𝑧(𝛼)𝑹𝑦(𝛽)𝑹𝑧(𝜃)𝑹𝑦(−𝛽)𝑹𝑧(−𝛼)
  3. Using trigonometry we can find 𝛼 and 𝛽:

    sin(𝛼)=𝑘𝑦𝑘𝑥2+𝑘𝑦2cos(𝛼)=𝑘𝑥𝑘𝑥2+𝑘𝑦2sin(𝛽)=𝑘𝑥2+𝑘𝑦2cos(𝛽)=𝑘𝑧

The rotation matrix is:

𝑹𝒌(𝜃)=[𝑘𝑥2(1−𝑐𝜃)+𝑐𝜃𝑘𝑥𝑘𝑦(1−𝑐𝜃)−𝑘𝑧𝑠𝜃𝑘𝑥𝑘𝑧(1−𝑐𝜃)+𝑘𝑦𝑠𝜃𝑘𝑥𝑘𝑦(1−𝑐𝜃)+𝑘𝑧𝑠𝜃𝑘𝑦2(1−𝑐𝜃)+𝑐𝜃𝑘𝑦𝑘𝑧(1−𝑐𝜃)−𝑘𝑥𝑠𝜃𝑘𝑥𝑘𝑧(1−𝑐𝜃)−𝑘𝑦𝑠𝜃𝑘𝑦𝑘𝑧(1−𝑐𝜃)+𝑘𝑥𝑠𝜃𝑘𝑧2(1−𝑐𝜃)+𝑐𝜃]

We specified four parameters (𝒌 and 𝜃), but there’s the constraint 𝑘𝑥2+𝑘𝑦2+𝑘𝑧2=1, so the system actually has three degrees of freedom.

We can see that 𝑹−𝒌(−𝜃)=𝑹𝒌(𝜃).

The axis-angle parameterisation isn’t globally invertible. However, it is locally invertible, which means that unlike the Euler one, there are no singularities such as gimbal lock.

The inverse of a real number 𝑥 is 𝑥−1=1𝑥, which, when multiplied by 𝑥, gives 1.

For complex numbers we can find a similar concept: a number 𝑧 multiplied by its inverse 𝑧̅‖𝑧‖2 still gives 1.

There is no equivalent concept in ℝ3, but it exists in ℝ4.

A quaternion is an element of a vector space over the reals with the form 𝑞=𝑞0+𝑞1𝒊+𝑞2𝒋+𝑞3𝒌 where {1,𝒊,𝒋,𝒌} is the basis set.

Let’s define an axiom for quaternion bases:

𝑖2=𝑗2=𝑘2=𝑖𝑗𝑘=−1

from which we can derive the multiplication rules between any two basis elements:

𝑖𝑗=𝑘𝑗𝑖=−𝑘𝑗𝑘=𝑖𝑘𝑗=−𝑖𝑘𝑖=𝑗𝑖𝑘=−𝑗

To compute the product of quaternions we can use the shorthand notation:

𝑝𝑞=(𝑝0+𝒑)(𝑞0+𝒒)=𝑝0𝑞0+𝑝0𝒒+𝑞0𝒑+𝒑𝒒

Using the rules from the axiom above, the product of the vector parts can be simplified as 𝒑𝒒=−𝒑⋅𝒒+𝒑×𝒒. Thus the full product, with scalar and vector parts grouped, is:

𝑝𝑞=(𝑝0𝑞0−𝒑⋅𝒒)+(𝑝0𝒒+𝑞0𝒑+𝒑×𝒒)

For a quaternion 𝑞=𝑞0+𝑞1𝒊+𝑞2𝒋+𝑞3𝒌, the conjugate is:

𝑞̅=𝑞0−𝑞1𝒊−𝑞2𝒋−𝑞3𝒌

The real number ‖𝑞‖=𝑞𝑞̅=𝑞02+𝑞12+𝑞22+𝑞32 is the norm of the quaternion.

A quaternion (except 0) has a unique inverse 𝑞−1=𝑞̅‖𝑞‖2.

Let’s go back to complex numbers. Recall that they can also be expressed in polar coordinates as 𝑧=𝜌(cos(𝜃)+𝑗sin(𝜃)).

Multiplying two complex numbers rotates the resulting vector, especially when both have unit norm:

𝑧1𝑧2=𝜌1(cos(𝜃1)+𝑗sin(𝜃1))𝜌2(cos(𝜃2)+𝑗sin(𝜃2))=𝜌1𝜌2(cos(𝜃1+𝜃2)+𝑗sin(𝜃1+𝜃2))

Let’s consider a unit-length quaternion 𝑞=[𝜂,𝜺]. We can express it as 𝑞=[cos(𝜃2),sin(𝜃2)𝒌] where 𝒌 is a unit vector defined as 𝒌=𝜺‖𝜺‖ and 𝜃=2atan2(‖𝜺‖,𝜂).

The quaternion 𝑞 represents a rotation of angle 𝜃 about the axis defined by the vector 𝒌.

Let’s take a pure quaternion 𝑝=[0,𝒑]. The vector 𝑝′ rotated by 𝑞 can be computed using 𝑝′=𝑞𝑝𝑞̅ which yields a quaternion of the form [0,𝒑′].

𝒑′=(𝜂2−‖𝜺‖2)𝒑+2𝜂(𝜺×𝒑)+2(𝜺⋅𝒑)𝜺

Substituting 𝜃 and 𝒌, we obtain Rodrigues’ rotation formula that describes the rotation of the vector 𝒑:

𝒑′=cos(𝜃)𝒑+sin(𝜃)(𝒌×𝒑)+(1−cos(𝜃))(𝒌⋅𝒑)𝒌

The parameters of a unit-length quaternion correspond to three degrees of freedom, which can be expressed as:

  • 𝜂, 𝜀𝑥, 𝜀𝑦, 𝜀𝑧, with the constraint 𝜂2+𝜀𝑥2+𝜀𝑦2+𝜀𝑧2=1;
  • 𝜃, 𝑘𝑥, 𝑘𝑦, 𝑘𝑧, with the constraint 𝑘𝑥2+𝑘𝑦2+𝑘𝑧2=1;

Given a rotation matrix 𝑹=[𝑟1,1𝑟1,2𝑟1,3𝑟2,1𝑟2,2𝑟2,3𝑟3,1𝑟3,2𝑟3,3], we can find the parameters:

𝜂=12𝑟1,1+𝑟2,2+𝑟3,3+1𝜺=12(sgn(𝑟3,2−𝑟2,3)𝑟1,1−𝑟2,2−𝑟3,3+1sgn(𝑟1,3−𝑟3,1)−𝑟1,1+𝑟2,2−𝑟3,3+1sgn(𝑟2,1−𝑟1,2)−𝑟1,1−𝑟2,2+𝑟3,3+1)

Let’s consider two rotations associated with the unit-length quaternions 𝑞0 and 𝑞1. The first rotation transforms a vector 𝒑 into 𝒑′ and the second transforms 𝒑′ into 𝒑″.

𝒑″=𝑞1𝑝′𝑞1̅=𝑞1(𝑞0𝑝𝑞0̅)𝑞1̅=(𝑞1𝑞0)𝑝(𝑞1𝑞0)̅

The composition of rotations is the product of their corresponding quaternions.

A point 𝒑1 in frame 1 can be expressed in frame 0 as 𝒑0=𝒐10+𝑹10𝒑1.

The inverse relation is found by isolating 𝒑1:

𝒑1=𝑹01𝒑0−𝑹01𝒐10

We need a compact way to represent both rotation and translation.

To do that, we create the homogeneous representation 𝒑̃ of 𝒑 by appending a coordinate with value 1.

The homogeneous transformation matrix is defined as:

𝑨10=[𝑹10𝒐10𝟎𝑇1]

which can then be used as usual to apply transformations by multiplying with vectors:

𝒑̃0=𝑨10𝒑̃1

The inverse transformation can be found by inverting the matrix:

𝑨01=(𝑨10)−1=[(𝑹10)𝑇−(𝑹10)𝑇𝒐10𝟎𝑇1]

Unlike rotation matrices, homogeneous transformations are not orthogonal, so 𝑨−1≠𝑨𝑇. But they can still be composed using matrix multiplication.