pub fn to_euler_angles<T>(
rt: RotationType,
rs: RotationSequence,
q: Quaternion<T>,
) -> Vector3<T>where
T: Float + FloatConst,
Expand description
Convert versor to euler angles.
The type of rotation (Intrinsic or Extrinsic) is specified by RotationType
enum,
and the rotation sequence (XZX, XYZ, …) is specified by RotationSequence
enum.
let angles = to_euler_angles(Intrinsic, XYZ, q);
Each element of angles
takes a value in the range: (-pi, pi]
.
Sequences: angles[0]
—> angles[1]
—> angles[2]
§Singularity
§RotationType::Intrinsic
For Proper Euler angles (ZXZ, XYX, YZY, ZYZ, XZX, YXY), the singularity is reached when the sine of the second rotation angle is 0 (angle = 0, ±π, …), and for Tait-Bryan angles (XYZ, YZX, ZXY, XZY, ZYX, YXZ), the singularity is reached when the cosine of the second rotation angle is 0 (angle = ±π/2).
At the singularity, the third rotation angle is set to 0[rad].
§RotationType::Extrinsic
As in the case of Intrinsic rotation, for Proper Euler angles, the singularity occurs when the sine of the second rotation angle is 0 (angle = 0, ±π, …), and for Tait-Bryan angles, the singularity occurs when the cosine of the second rotation angle is 0 (angle = ±π/2).
At the singularity, the first rotation angle is set to 0[rad].
§Examples
Depending on the rotation angle of each axis, it may not be possible to recover the same rotation angle as the original. However, they represent the same rotation in 3D space.
use quaternion_core::{RotationType::*, RotationSequence::XYZ};
let angles = [PI/6.0, PI/4.0, PI/3.0];
// ---- Intrinsic (X-Y-Z) ---- //
let q_in = from_euler_angles(Intrinsic, XYZ, angles);
let e_in = to_euler_angles(Intrinsic, XYZ, q_in);
assert!( (angles[0] - e_in[0]).abs() < 1e-12 );
assert!( (angles[1] - e_in[1]).abs() < 1e-12 );
assert!( (angles[2] - e_in[2]).abs() < 1e-12 );
// ---- Extrinsic (X-Y-Z) ---- //
let q_ex = from_euler_angles(Extrinsic, XYZ, angles);
let e_ex = to_euler_angles(Extrinsic, XYZ, q_ex);
assert!( (angles[0] - e_ex[0]).abs() < 1e-12 );
assert!( (angles[1] - e_ex[1]).abs() < 1e-12 );
assert!( (angles[2] - e_ex[2]).abs() < 1e-12 );