Euler Angles
Euler Angles
Contents
1 Introduction 3
1
3.6 Factor Pz Py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2
1 Introduction
Rotations about the coordinate axes are easy to define and work with. Rotation about the x-axis by angle
θ is
1 0 0
Rx (θ) = 0 cos θ − sin θ
0 sin θ cos θ
where θ > 0 indicates a counterclockwise rotation in the plane x = 0. The observer is assumed to be
positioned on the side of the plane with x > 0 and looking at the origin. Rotation about the y-axis by angle
θ is
cos θ 0 sin θ
Ry (θ) =
0 1 0
− sin θ 0 cos θ
where θ > 0 indicates a counterclockwise rotation in the plane y = 0. The observer is assumed to be
positioned on the side of the plane with y > 0 and looking at the origin. Rotation about the z-axis by angle
θ is
cos θ − sin θ 0
Rz (θ) = sin θ
cos θ 0
0 0 1
where θ > 0 indicates a counterclockwise rotation in the plane z = 0. The observer is assumed to be
positioned on the side of the plane with z > 0 and looking at the origin. Rotation by an angle θ about an
arbitrary axis containing the origin and having unit length direction U = (Ux , Uy , Uz ) is given by
RU (θ) = I + (sin θ)S + (1 − cos θ)S 2
where I is the identity matrix,
0 −Uz Uy
S = Uz −Ux
0
−Uy Ux 0
and θ > 0 indicates a counterclockwise rotation in the plane U · (x, y, z) = 0. The observer is assumed to be
positioned on the side of the plane to which U points and is looking at the origin.
A common problem is to factor a rotation matrix as a product of rotations about the coordinate axes.
The form of the factorization depends on the needs of the application and what ordering is specified. For
example, one might want to factor a rotation as R = Rx (θx )Ry (θy )Rz (θz ) for some angles θx , θy , and θz .
The ordering is xyz. Five other possibilities are xzy, yxz, yzx, zxy, and zyx. It is also possible to factor
as R = Rx (θx0 )Ry (θy )Rx (θx1 ), the ordering referred to as xyx. Five other possibilites are xzx, yxy, yzy,
zxz, and zyz. These are also discussed here. The following discussion uses the notation ca = cos(θa ) and
sa = sin(θa ) for a = x, y, z.
3
2.1 Factor as Rx Ry Rz
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Rx (θx )Ry (θy )Rz (θz ), and equating yields
r00 r01 r02 cy cz −cy sz sy
r10 r11 r12 = cz sx sy + cx sz cx cz − sx sy sz −cy sx
r20 r21 r22 −cx cz sy + sx sz cz sx + cx sy sz cx cy
The simplest term to work with is sy = r02 , so θy = asin(r02 ). There are three cases to consider.
Case 1: If θy ∈ (−π/2, π/2), then cy 6= 0 and cy (sx , cx ) = (−r12 , r22 ), in which case θx = atan2(−r12 , r22 ),
and cy (sz , cz ) = (−r01 , r00 ), in which case θz = atan2(−r01 , r00 ). In summary,
Therefore, θz + θx = atan2(r10 , r11 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θy = π/2, θz + θx = atan2(r10 , r11 ) (2)
Therefore, θz − θx = atan2(r10 , r11 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θy = −π/2, θz − θx = atan2(r10 , r11 ) (3)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r02
is tested for the three cases.
i f ( r 0 2 < +1)
{
i f ( r 0 2 > −1)
{
thetaY = a s i n ( r02 ) ;
t h e t a X = a t a n 2 (−r12 , r 2 2 ) ;
t h e t a Z = a t a n 2 (−r01 , r 0 0 ) ;
}
else // r 0 2 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a Z − t h e t a X = a t a n 2 ( r10 , r 1 1 )
t h e t a Y = −P I / 2 ;
t h e t a X = −a t a n 2 ( r10 , r 1 1 ) ;
thetaZ = 0;
}
}
4
else // r 0 2 = +1
{
// Not a unique s o l u t i o n : t h e t a Z + t h e t a X = a t a n 2 ( r10 , r 1 1 )
thetaY = +P I / 2 ;
thetaX = a t a n 2 ( r10 , r 1 1 ) ;
thetaZ = 0;
}
2.2 Factor as Rx Rz Ry
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Rx (θx )Rz (θz )Ry (θy ), and equating yields
r00 r01 r02 cy cz −sz cz sy
r10 r11 r12 = sx sy + cx cy sz cx cz −cy sx + cx sy sz
r20 r21 r22 −cx sy + cy sx sz cz sx cx cy + sx sy sz
The simplest term to work with is −sz = r01 , so θz = asin(−r01 ). There are three cases to consider.
Case 1: If θz ∈ (−π/2, π/2), then cz 6= 0 and cz (sy , cy ) = (r02 , r00 ), in which case θy = atan2(r02 , r00 ), and
cz (sx , cx ) = (r21 , r11 ), in which case θx = atan2(r21 , r11 ). In summary,
Therefore, θy − θx = atan2(−r20 , r22 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θz = +π/2, θy − θx = atan2(−r20 , r22 ) (5)
Therefore, θy + θx = atan2(−r20 , r22 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θz = −π/2, θy + θx = atan2(−r20 , r22 ) (6)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r01
is tested for the three cases.
i f ( r 0 1 < +1)
{
i f ( r 0 1 > −1)
{
t h e t a Z = a s i n (− r 0 1 ) ;
5
t h e t a X = a t a n 2 ( r21 , r 1 1 ) ;
t h e t a Y = a t a n 2 ( r02 , r 0 0 ) ;
}
e l s e // r 0 1 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a Y − t h e t a X = a t a n 2 (−r20 , r 2 2 )
t h e t a z = +p i / 2 ;
t h e t a x = −a t a n 2 (−r20 , r 2 2 ) ;
theta y = 0;
}
}
e l s e // r 0 1 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a Y + t h e t a X = a t a n 2 (−r20 , r 2 2 )
t h e t a z = −p i / 2 ;
t h e t a x = a t a n 2 (−r20 , r 2 2 ) ;
theta y = 0;
}
2.3 Factor as Ry Rx Rz
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Ry (θy )Rx (θx )Rz (θz ), and equating yields
r00 r01 r02 cy cz + sx sy sz cz sx sy − cy sz cx sy
r10 r11 r12 = −sx
cx sz cx cz
r20 r21 r22 −cz sy + cy sx sz cy cz sx + sy sz cx cy
The simplest term to work with is −sx = r12 , so θx = asin(−r12 ). There are three cases to consider.
Case 1: If θx ∈ (−π/2, π/2), then cx 6= 0 and cx (sy , cy ) = (r02 , r22 ), in which case θy = atan2(r02 , r22 ), and
cx (sz , cz ) = (r10 , r11 ), in which case θz = atan2(r10 , r11 ). In summary,
Therefore, θz − θy = atan2(−r01 , r00 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θx = +π/2, θz − θy = atan2(−r01 , r00 ) (8)
Therefore, θz + θy = atan2(−r01 , r00 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θx = −π/2, θz + θy = atan2(−r01 , r00 ) (9)
6
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r12
is tested for the three cases.
i f ( r 1 2 < +1)
{
i f ( r 1 2 > −1)
{
t h e t a X = a s i n (− r 1 2 ) ;
t h e t a Y = a t a n 2 ( r02 , r 2 2 ) ;
t h e t a Z = a t a n 2 ( r10 , r 1 1 ) ;
}
e l s e // r 1 2 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a Z − t h e t a Y = a t a n 2 (−r01 , r 0 0 )
t h e t a X = +p i / 2 ;
t h e t a Y = −a t a n 2 (−r01 , r 0 0 ) ;
thetaZ = 0;
}
}
e l s e // r 1 2 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a Z + t h e t a Y = a t a n 2 (−r01 , r 0 0 )
t h e t a X = −p i / 2 ;
t h e t a Y = a t a n 2 (−r01 , r 0 0 ) ;
thetaZ = 0;
}
2.4 Factor as Ry Rz Rx
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Ry (θy )Rz (θz )Rx (θx ), and equating yields
r00 r01 r02 cy cz sx sy − cx cy sz cx sy + cy sx sz
r10 r11 r12 = sz −cz sx
cx cz
r20 r21 r22 −cz sy cy sx + cx sy sz cx cy − sx sy sz
The simplest term to work with is sz = r10 , so θz = asin(r10 ). There are three cases to consider.
Case 1: If θz ∈ (−π/2, π/2), then cz 6= 0 and cz (sx , cx ) = (−r12 , r11 ), in which case θx = atan2(−r12 , r11 ),
and cz (sy , cy ) = (−r20 , r00 ), in which case θy = atan2(−r20 , r00 ). In summary,
θz = asin(r10 ), θy = atan2(−r20 , r00 ), θx = atan2(−r12 , r11 ) (10)
Therefore, θx + θy = atan2(r21 , r22 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θz = +π/2, θx + θy = atan2(r21 , r22 ) (11)
7
Therefore, θx − θy = atan2(r21 , r22 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θz = −π/2, θx − θy = atan2(r21 , r22 ) (12)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r10
is tested for the three cases.
i f ( r 1 0 < +1)
{
i f ( r 1 0 > −1)
{
thetaZ = a s i n ( r10 ) ;
t h e t a Y = a t a n 2 (−r20 , r 0 0 ) ;
t h e t a X = a t a n 2 (−r12 , r 1 1 ) ;
}
e l s e // r 1 0 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a X − t h e t a Y = a t a n 2 ( r21 , r 2 2 )
t h e t a Z = −p i / 2 ;
t h e t a Y = −a t a n 2 ( r21 , r 2 2 ) ;
thetaX = 0;
}
}
else
{
// Not a u n i q u e s o l u t i o n : t h e t a X + t h e t a Y = a t a n 2 ( r21 , r 2 2 )
t h e t a Z = +p i / 2 ;
t h e t a Y = a t a n 2 ( r21 , r 2 2 ) ;
thetaX = 0;
}
2.5 Factor as Rz Rx Ry
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Rz (θz )Rx (θx )Ry (θy ), and equating yields
r00 r01 r02 cy cz − sx sy sz −cx sz cz sy + cy sx sz
r10 r11 r12 = cz sx sy + cy sz cx cz −cy cz sx + sy sz
r20 r21 r22 −cx sy sx cx cy
The simplest term to work with is sx = r21 , so θx = asin(r21 ). There are three cases to consider.
Case 1: If θx ∈ (−π/2, π/2), then cx 6= 0 and cx (sy , cy ) = (−r20 , r22 ), in which case θy = atan2(−r20 , r22 ),
and cx (sz , cz ) = (−r01 , r11 ), in which case θz = atan2(−r01 , r11 ). In summary,
Therefore, θy + θz = atan2(r02 , r00 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θx = +π/2, θy + θz = atan2(r02 , r00 ) (14)
8
Case 3: If θx = −π/2, then sx = −1 and cx = 0. In this case,
r00 r02 cy sz + sy cz cz sy − cy sz cos(θy − θz ) sin(θy − θz )
= =
r10 r12 −cz sy + cy sz cy cz + sy sz − sin(θy − θz ) cos(θy − θz )
Therefore, θy − θz = atan2(r02 , r00 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θx = −π/2, θy − θz = atan2(r02 , r00 ) (15)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r21
is tested for the three cases.
i f ( r 2 1 < +1)
{
i f ( r 2 1 > −1)
{
thetaX = a s i n ( r21 ) ;
t h e t a Z = a t a n 2 (−r01 , r 1 1 ) ;
t h e t a Y = a t a n 2 (−r20 , r 2 2 ) ;
}
e l s e // r 2 1 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a Y − t h e t a Z = a t a n 2 ( r02 , r 0 0 )
t h e t a X = −p i / 2 ;
t h e t a Z = −a t a n 2 ( r02 , r 0 0 ) ;
thetaY = 0;
}
}
e l s e // r 2 1 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a Y + t h e t a Z = a t a n 2 ( r02 , r 0 0 )
t h e t a X = +p i / 2 ;
t h e t a Z = a t a n 2 ( r02 , r 0 0 ) ;
thetaY = 0;
}
2.6 Factor as Rz Ry Rx
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Rz (θz )Ry (θy )Rx (θx ), and equating yields
r00 r01 r02 cy cz cz sx sy − cx sz cx cz sy + sx sz
r10 r11 r12 = cy sz cx cz + sx sy sz −cz sx + cx sy sz
r20 r21 r22 −sy cy sx cx cy
The simplest term to work with is sy = −r20 , so θy = asin(−r20 ). There are three cases to consider.
Case 1: If θy ∈ (−π/2, π/2), then cy 6= 0 and cy (sx , cx ) = (r21 , r22 ), in which case θx = atan2(r21 , r22 ), and
cy (sz , cz ) = (r10 , r00 ), in which case θz = atan2(r10 , r00 ). In summary,
θy = asin(−r20 ), θz = atan2(r10 , r00 ), θx = atan2(r21 , r22 ) (16)
9
Therefore, θx − θz = atan2(−r12 , r11 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θy = +π/2, θx − θz = atan2(−r12 , r11 ) (17)
Therefore, θx + θz = atan2(−r12 , r11 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θy = −π/2, θx + θz = atan2(−r12 , r11 ) (18)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r20
is tested for the three cases.
i f ( r 2 0 < +1)
{
i f ( r 2 0 > −1)
{
t h e t a Y = a s i n (− r 2 0 ) ;
t h e t a Z = a t a n 2 ( r10 , r 0 0 ) ;
t h e t a X = a t a n 2 ( r21 , r 2 2 ) ;
}
e l s e // r 2 0 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a X − t h e t a Z = a t a n 2 (−r12 , r 1 1 )
t h e t a Y = +p i / 2 ;
t h e t a Z = −a t a n 2 (−r12 , r 1 1 ) ;
thetaX = 0;
}
}
e l s e // r 2 0 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a X + t h e t a Z = a t a n 2 (−r12 , r 1 1 )
t h e t a Y = −p i / 2 ;
t h e t a Z = a t a n 2 (−r12 , r 1 1 ) ;
thetaX = 0;
}
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Rx (θx0 )Ry (θy )Rx (θx1 ), and equating
yields
r r01 r02 cy sy sx1 sy cx1
00
r12 = sy sx0 cx0 cx1 − cy sx0 sx1 −cy cx1 sx0 − cx0 sx1
r10 r11
r20 r21 r22 −sy cx0 cx1 sx0 + cy cx0 sx1 cy cx0 cx1 − sx0 sx1
The simplest term to work with is cy = r00 , so θy = acos(r00 ). There are three cases to consider.
Case 1: If θy ∈ (0, π), then sy 6= 0 and sy (sx0 , cx0 ) = (r10 , −r20 ), in which case θx0 = atan2(r10 , −r20 ), and
sy (sx1 , cx1 ) = (r01 , r02 ), in which case θx1 = atan2(r01 , r02 ). In summary,
10
Case 2: If θy = 0, then cy = 1 and sy = 0. In this case,
r11 r12 cx0 cx1 − sx0 sx1 −cx1 sx0 − cx0 sx1 cos(θx1 + θx0 ) − sin(θx1 + θx0 )
= =
r21 r22 cx1 sx0 + cx0 sx1 cx0 cx1 − sx0 sx1 sin(θx1 + θx0 ) cos(θx1 + θx0 )
Therefore, θx1 + θx0 = atan2(−r12 , r11 ). There is one degree of freedom, so the factorization is not unique.
In summary,
θy = 0, θx1 + θx0 = atan2(−r12 , r11 ) (20)
Therefore, θx1 − θx0 = atan2(−r12 , r11 ). There is one degree of freedom, so the factorization is not unique.
In summary,
θy = π, θx1 − θx0 = atan2(−r12 , r11 ) (21)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r00
is tested for the three cases.
i f ( r 0 0 < +1)
{
i f ( r 0 0 > −1)
{
thetaY = acos ( r00 ) ;
t h e t a X 0 = a t a n 2 ( r10 ,− r 2 0 ) ;
t h e t a X 1 = a t a n 2 ( r01 , r 0 2 ) ;
}
e l s e // r 0 0 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a X 1 − t h e t a X 0 = a t a n 2 (−r12 , r 1 1 )
thetaY = p i ;
t h e t a X 0 = −a t a n 2 (−r12 , r 1 1 ) ;
thetaX1 = 0;
}
}
e l s e // r 0 0 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a X 1 + t h e t a X 0 = a t a n 2 (−r12 , r 1 1 )
thetaY = 0;
t h e t a X 0 = a t a n 2 (−r12 , r 1 1 ) ;
thetaX1 = 0;
}
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Rx (θx0 )Ry (θy )Rz (θx1 ), and equating
yields
r00 r01 r02 cz −sz cx1 sz sx1
r10 r11 r12 = sz cx0 cz cx0 cx1 − sx0 sx1 −cx1 sx0 − cz cx0 sx1
r20 r21 r22 sz sx0 cz cx1 sx0 + cx0 sx1 cx0 cx1 − cz sx0 sx1
11
The simplest term to work with is cz = r00 , so θz = acos(r00 ). There are three cases to consider.
Case 1: If θz ∈ (0, π), then sz 6= 0 and sz (sx0 , cx0 ) = (r20 , r10 ), in which case θx0 = atan2(r20 , r10 ), and
sz (sx1 , cx1 ) = (r02 , −r01 ), in which case θx1 = atan2(r02 , −r01 ). In summary,
Therefore, θx1 + θx0 = atan2(r21 , r22 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θz = 0, θx1 + θx0 = atan2(r21 , r22 ) (23)
Therefore, θx1 − θx0 = atan2(r21 , r22 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θz = π, θx1 − θx0 = atan2(r21 , r22 ) (24)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r00
is tested for the three cases.
i f ( r 0 0 < +1)
{
i f ( r 0 0 > −1)
{
thetaZ = acos ( r00 ) ;
t h e t a X 0 = a t a n 2 ( r20 , r 1 0 ) ;
t h e t a X 1 = a t a n 2 ( r02 ,− r 0 1 ) ;
}
e l s e // r 0 0 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a X 1 − t h e t a X 0 = a t a n 2 ( r21 , r 2 2 )
thetaZ = pi ;
t h e t a X 0 = −a t a n 2 ( r21 , r 2 2 ) ;
thetaX1 = 0;
}
}
e l s e // r 0 0 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a X 1 + t h e t a X 0 = a t a n 2 ( r21 , r 2 2 )
thetaZ = 0;
t h e t a X 0 = a t a n 2 ( r21 , r 2 2 ) ;
thetaX1 = 0;
}
12
2.9 Factor as Ry0 Rx Ry1
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Ry (θy0 )Rx (θx )Ry (θy1 ), and equating
yields
r00 r01 r02 cy0 cy1 − cx sy0 sy1 sx sy0 cx cy1 sy0 + cy0 sy1
r10 r11 r12 = −sx cy1
sx sy1 cx
r20 r21 r22 −cy1 sy0 − cx cy0 sy1 sx cy0 cx cy0 cy1 − sy0 sy1
The simplest term to work with is cx = r11 , so θx = acos(r11 ). There are three cases to consider.
Case 1: If θx ∈ (0, π), then sx 6= 0 and sx (sy0 , cy0 ) = (r01 , r21 ), in which case θy0 = atan2(r01 , r21 ), and
sx (sy1 , cy1 ) = (r10 , −r12 ), in which case θy1 = atan2(r10 , −r12 ). In summary,
Therefore, θy1 + θy0 = atan2(r02 , r00 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θx = 0, θy1 + θy0 = atan2(r02 , r00 ) (26)
Therefore, θy1 − θy0 = atan2(r02 , r00 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θx = π, θy1 − θy0 = atan2(r02 , r00 ) (27)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r11
is tested for the three cases.
i f ( r 1 1 < +1)
{
i f ( r 1 1 > −1)
{
thetaX = acos ( r11 ) ;
t h e t a Y 0 = a t a n 2 ( r01 , r 2 1 ) ;
t h e t a Y 1 = a t a n 2 ( r10 ,− r 1 2 ) ;
}
e l s e // r 1 1 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a Y 1 − t h e t a Y 0 = a t a n 2 ( r02 , r 0 0 )
thetaX = p i ;
t h e t a Y 0 = −a t a n 2 ( r02 , r 0 0 ) ;
thetaY1 = 0;
}
}
13
e l s e // r 1 1 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a Y 1 + t h e t a Y 0 = a t a n 2 ( r02 , r 0 0 )
thetaX = 0;
t h e t a Y 0 = a t a n 2 ( r02 , r 0 0 ) ;
thetaY1 = 0;
}
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Ry (θy0 )Rz (θz )Ry (θy1 ), and equating
yields
r r01 r02 cz cy0 cy1 − sy0 sy1 −sz cy0 cy1 sy0 + cz cy0 sy1
00
r12 =
r10 r11 sz cy1 cz sz sy1
r20 r21 r22 −cz cy1 sy0 − cy0 sy1 sz sy0 cy0 cy1 − cz sy0 sy1
The simplest term to work with is cz = r11 , so θz = acos(r11 ). There are three cases to consider.
Case 1: If θz ∈ (0, π), then sz 6= 0 and sz (sy0 , cy0 ) = (r21 , −r01 ), in which case θy0 = atan2(r21 , −r01 ), and
sz (sy1 , cy1 ) = (r12 , r10 ), in which case θy1 = atan2(r12 , r10 ). In summary,
Therefore, θy1 + θy0 = atan2(−r20 , r22 ). There is one degree of freedom, so the factorization is not unique.
In summary,
θz = 0, θy1 + θy0 = atan2(−r20 , r22 ) (29)
Therefore, θy1 − θy0 = atan2(−r20 , r22 ). There is one degree of freedom, so the factorization is not unique.
In summary,
θz = π, θy1 − θy0 = atan2(−r20 , r22 ) (30)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r11
is tested for the three cases.
i f ( r 1 1 < +1)
{
i f ( r 1 1 > −1)
{
thetaZ = acos ( r11 ) ;
14
t h e t a Y 0 = a t a n 2 ( r21 ,− r 0 1 ) ;
t h e t a Y 1 = a t a n 2 ( r12 , r 1 0 ) ;
}
e l s e // r 1 1 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a Y 1 − t h e t a Y 0 = a t a n 2 (−r20 , r 2 2 )
thetaZ = pi ;
t h e t a Y 0 = −a t a n 2 (−r20 , r 2 2 ) ;
thetaY1 = 0;
}
}
e l s e // r 1 1 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a Y 1 + t h e t a Y 0 = a t a n 2 (−r20 , r 2 2 )
thetaZ = 0;
t h e t a Y 0 = a t a n 2 (−r20 , r 2 2 ) ;
thetaY1 = 0;
}
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Rz (θz0 )Rx (θx )Rz (θz1 ), and equating
yields
r r01 r02 cz0 cz1 − cx sz0 sz1 −cx cz1 sz0 − cz0 sz1 sx sz0
00
r12 = cz1 sz0 + cx cz0 sz1 cx cz0 cz1 − sz0 sz1 −sx cz0
r10 r11
r20 r21 r22 sx sz1 sx cz1 cx
The simplest term to work with is cx = r22 , so θx = acos(r22 ). There are three cases to consider.
Case 1: If θx ∈ (0, π), then sx 6= 0 and sx (sz0 , cz0 ) = (r02 , −r12 ), in which case θz0 = atan2(r02 , −r12 ), and
sx (sz1 , cz1 ) = (r20 , r21 ), in which case θz1 = atan2(r20 , r21 ). In summary,
Therefore, θz1 + θz0 = atan2(−r01 , r00 ). There is one degree of freedom, so the factorization is not unique.
In summary,
θx = 0, θz1 + θz0 = atan2(−r01 , r00 ) (32)
Therefore, θz1 − θz0 = atan2(−r01 , r00 ). There is one degree of freedom, so the factorization is not unique.
In summary,
θx = π, θz1 − θz0 = atan2(−r01 , r00 ) (33)
15
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r22
is tested for the three cases.
i f ( r 2 2 < +1)
{
i f ( r 2 2 > −1)
{
thetaX = acos ( r22 ) ;
t h e t a Z 0 = a t a n 2 ( r02 ,− r 1 2 ) ;
t h e t a Z 1 = a t a n 2 ( r20 , r 2 1 ) ;
}
e l s e // r 2 2 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a Z 1 − t h e t a Z 0 = a t a n 2 (−r01 , r 0 0 )
thetaX = p i ;
t h e t a Z 0 = −a t a n 2 (−r01 , r 0 0 ) ;
thetaZ1 = 0;
}
}
e l s e // r 2 2 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a Z 1 + t h e t a Z 0 = a t a n 2 (−r01 , r 0 0 )
thetaX = 0;
t h e t a Z 0 = a t a n 2 (−r01 , r 0 0 ) ;
thetaZ1 = 0;
}
Setting R = [rij ] for 0 ≤ i ≤ 2 and 0 ≤ j ≤ 2, formally multiplying Rz (θz0 )Ry (θy )Rz (θz1 ), and equating
yields
r00 r01 r02 cy cz0 cz1 − sz0 sz1 −cz1 sz0 − cy cz0 sz1 sy cz0
r10 r11 r12 = cy cz1 sz0 + cz0 sz1 cz0 cz1 − cy sz0 sz1 sy sz0
r20 r21 r22 −sy cz1 sy sz1 cy
The simplest term to work with is cy = r22 , so θy = acos(r22 ). There are three cases to consider.
Case 1: If θy ∈ (0, π), then sy 6= 0 and sy (sz0 , cz0 ) = (r12 , r02 ), in which case θz0 = atan2(r12 , r02 ), and
sy (sz1 , cz1 ) = (r21 , −r20 ), in which case θz1 = atan2(r20 , r21 ). In summary,
θy = acos(r22 ), θz0 = atan2(r12 , r02 ), θz1 = atan2(r21 , −r−20 ) (34)
16
Therefore, θz1 − θz0 = atan2(r10 , r11 ). There is one degree of freedom, so the factorization is not unique. In
summary,
θy = π, θz1 − θz0 = atan2(r10 , r11 ) (36)
Pseudocode for the factorization is listed below. To avoid the arcsin call until needed, the matrix entry r22
is tested for the three cases.
i f ( r 2 2 < +1)
{
i f ( r 2 2 > −1)
{
thetaY = acos ( r22 ) ;
t h e t a Z 0 = a t a n 2 ( r12 , r 0 2 ) ;
t h e t a Z 1 = a t a n 2 ( r21 ,− r 2 0 ) ;
}
e l s e // r 2 2 = −1
{
// Not a u n i q u e s o l u t i o n : t h e t a Z 1 − t h e t a Z 0 = a t a n 2 ( r10 , r 1 1 )
thetaY = p i ;
t h e t a Z 0 = −a t a n 2 ( r10 , r 1 1 ) ;
thetaZ1 = 0;
}
}
e l s e // r 2 2 = +1
{
// Not a u n i q u e s o l u t i o n : t h e t a Z 1 + t h e t a Z 0 = a t a n 2 ( r10 , r 1 1 )
thetaY = 0;
t h e t a Z 0 = a t a n 2 ( r10 , r 1 1 ) ;
thetaZ1 = 0;
}
Given a rotation R that is a product of two coordinate axis rotations, the problem is to factor it into
three coordinate axis rotations using the ordering xyz. Derivations for the other orderings are similar. In
the subsections the matrices are Px = Rx (φx ), Py = Ry (φy ), and Pz = Rz (φz ). Define sa = sin(φx ),
sb = sin(φy ), sc = sin(φz ), ca = cos(φx ), cb = cos(φy ), and cc = cos(φz ).
3.1 Factor Px Py
This is a trivial case. The factorization is R = Rx (φx )Ry (φy ) = Rx (θx )Ry (θy )Rz (θz ). Therefore, θx = φx ,
θy = φy , and θz = 0.
3.2 Factor Py Px
The factorization is R = Ry (φy )Rx (φx ) = Rx (θx )Ry (θy )Rz (θz ). Formal multiplication of the various terms
leads to the equation
cb sa sb ca sb cy cz −cy sz sy
−sa = cz sx sy + cx sz cx cz − sx sy sz −cy sx .
0 ca
−sb cb sa ca cb −cx cz sy + sx sz cz sx + cx sy sz cx cy
17
It is easy to see that sy = ca sb in which case θy = asin(cos θy sin θx ). Adding the 10 and 21 terms yields
0 + cb sa = (cz sx sy + cx sz ) + (cz sx + cx sy sz ) = (1 + sy )(cz sx + cx sz )
which leads to sin(θx + θz ) = cb sa /(1 + ca sb ). In the even that ca sb = −1, this leads to a special case in the
coding that is easy to solve. Subtracting the 10 term from the 21 term yields
cb sa − 0 = (cz sx sy + cx sz ) − (cz sx + cx sy sz ) = (1 − sy )(cz sx − cx sz )
which leads to sin(θx − θz ) = cb sa /(1 − ca sb ). In the event that ca sb = 1, this also leads to a special case in
the coding that is easy to solve. The sine functions can be inverted and the two resulting equations for θx
and θz can be solved. For the case |ca sb | < 1,
h i
cb sa cb sa
θx = 21 asin 1+c b sa
+ asin 1−cb sa
θy = asin(ca sb )
h i
cb sa cb sa
θz = 21 asin 1+c b sa
− asin 1−cb sa
3.3 Factor Px Pz
This is a trivial case. The factorization is R = Rx (φx )Rz (φz ) = Rx (θx )Ry (θy )Rz (θz ). Therefore, θx = φx ,
θy = 0, and θz = φz .
3.4 Factor Pz Px
θy = asin(sa sc )
h i
ca cc ca cc
θz = 12 asin 1+s a sc
− asin 1−s a sc
3.5 Factor Py Pz
This is a trivial case. The factorization is R = Ry (φy )Rz (φz ) = Rx (θx )Ry (θy )Rz (θz ). Therefore, θx = 0,
θy = φy , and θz = φz .
3.6 Factor Pz Py
θy = asin(sb cc )
h i
cb sc cb sc
θz = 12 asin 1+s c
b c
+ asin 1−s c
b c
18