Get Euler angles from rotation matrix.
angles = eulang(Rp) [alpha,beta,gamma] = eulang(Rp)
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 α.
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
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