eulang

Get Euler angles from rotation matrix.

Syntax
angles = eulang(Rp)
[alpha,beta,gamma] = eulang(Rp)
Description

Given a rotation matrix Rp, the function eulang computes the Euler angles defining the same rotation and returns them separately or as a 3-element vector angles = [alpha, beta, gamma]. The angles are in radians.

The calculated Euler angles are such that if provided to erot, the input rotation matrix is recovered.

For details about Euler angles and rotation matrices, see the page on relative orientations.

The rotation matrix must be a 3x3 real matrix with determinant +1 to within 0.01, otherwise the function errors. For smaller deviations, a warning is issued.

Since (α,β,γ) and (α+/-π,-β,γ+/-π) describe the same rotation, there is more than one set of Euler angles that give the same rotation matrix. eulang returns the one with positive β. In the special cases β=0 and β=π, the rotation axes for α and γ coincide, and the two angles cannot be distinguished. In this case eulang sets γ to zero and describes the entire z rotation by α.

Algorithm

eulang first checks if the input matrix is orthogonal and then determines the Euler angles analytically from the matrix elements. If the input matrix is close to orthogonal, eulang replaces it by its closest orthogonal neighbor using singular-value decomposition. If the the matrix is too far from orthogonal, eulang errors.

You can manually use SVD to orthogonalize a matrix using

[U,~,V] = svd(R);  % calculate SVD, ignoring singular values
R = U*V.';         % construct orthogonal rotation matrix 
Examples

Taking three arbitrary angles, we compute the rotation matrix

ang = [34 72 -143]*pi/180;
R = erot(ang)
R =
    0.1319   -0.6369    0.7595
    0.6008   -0.5581   -0.5724
    0.7885    0.5318    0.3090

Now, feeding this rotation matrix into eulang, we get back the three original angles.

eulang(R)*180/pi
ans =
   34.0000   72.0000 -143.0000

If the elements of a rotation matrix are not known to sufficient precision, the matrix might not be orthogonal:

R_approx = [-0.04    0.99   -0.11
            -0.77    0.04    0.63
             0.63    0.11    0.77];
det(R_approx)
ans =
    0.9935

and eulang will refuse to calculate Euler angles. To orthogonalize the matrix, use

[U,~,V] = svd(R_approx)
R = U*V.'
R =
   -0.0394    0.9931   -0.1103
   -0.7747    0.0394    0.6311
    0.6311    0.1103    0.7678

eulang now works:

eulang(R)
ans =
    0.1730    0.6954    1.3978
See also

ang2vec, erot, vec2ang