Fix cornercase for Rotation3 conversion to euler angles.

Fix #494
This commit is contained in:
sebcrozet 2018-12-04 21:23:21 +01:00 committed by Sébastien Crozet
parent 72d89c75ae
commit c69ab193be
2 changed files with 17 additions and 3 deletions

View File

@ -370,12 +370,12 @@ impl<N: Real> Rotation3<N> {
pub fn euler_angles(&self) -> (N, N, N) { pub fn euler_angles(&self) -> (N, N, N) {
// Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh // Implementation informed by "Computing Euler angles from a rotation matrix", by Gregory G. Slabaugh
// http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578 // http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.371.6578
if self[(2, 0)].abs() != N::one() { if self[(2, 0)].abs() < N::one() {
let yaw = -self[(2, 0)].asin(); let yaw = -self[(2, 0)].asin();
let roll = (self[(2, 1)] / yaw.cos()).atan2(self[(2, 2)] / yaw.cos()); let roll = (self[(2, 1)] / yaw.cos()).atan2(self[(2, 2)] / yaw.cos());
let pitch = (self[(1, 0)] / yaw.cos()).atan2(self[(0, 0)] / yaw.cos()); let pitch = (self[(1, 0)] / yaw.cos()).atan2(self[(0, 0)] / yaw.cos());
(roll, yaw, pitch) (roll, yaw, pitch)
} else if self[(2, 0)] == -N::one() { } else if self[(2, 0)] <= -N::one() {
(self[(0, 1)].atan2(self[(0, 2)]), N::frac_pi_2(), N::zero()) (self[(0, 1)].atan2(self[(0, 2)]), N::frac_pi_2(), N::zero())
} else { } else {
( (

View File

@ -1,4 +1,4 @@
use na::{Vector2, Vector3}; use na::{Quaternion, Real, UnitQuaternion, Vector2, Vector3};
#[test] #[test]
fn angle_2() { fn angle_2() {
@ -16,6 +16,20 @@ fn angle_3() {
assert_eq!(a.angle(&b), 0.0); assert_eq!(a.angle(&b), 0.0);
} }
#[test]
fn quaternion_to_euler_angles_issue_494() {
let quat = UnitQuaternion::from_quaternion(Quaternion::new(
-0.10405792,
-0.6993922f32,
-0.10406871,
0.69942284,
));
let angs = quat.euler_angles();
assert_eq!(angs.0, 2.8461843);
assert_eq!(angs.1, f32::frac_pi_2());
assert_eq!(angs.2, 0.0);
}
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
mod quickcheck_tests { mod quickcheck_tests {
use alga::general::Real; use alga::general::Real;