Function to_euler_angles

Source
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 );