nalgebra/tests/geometry/dual_quaternion.rs
2021-02-28 17:52:14 +01:00

211 lines
6.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#![cfg(feature = "proptest-support")]
#![allow(non_snake_case)]
use na::{DualQuaternion, Point3, UnitDualQuaternion, Vector3};
use crate::proptest::*;
use proptest::{prop_assert, proptest};
proptest!(
#[test]
fn isometry_equivalence(iso in isometry3(), p in point3(), v in vector3()) {
let dq = UnitDualQuaternion::from_isometry(&iso);
prop_assert!(relative_eq!(iso * p, dq * p, epsilon = 1.0e-7));
prop_assert!(relative_eq!(iso * v, dq * v, epsilon = 1.0e-7));
}
#[test]
fn inverse_is_identity(i in unit_dual_quaternion(), p in point3(), v in vector3()) {
let ii = i.inverse();
prop_assert!(relative_eq!(i * ii, UnitDualQuaternion::identity(), epsilon = 1.0e-7)
&& relative_eq!(ii * i, UnitDualQuaternion::identity(), epsilon = 1.0e-7)
&& relative_eq!((i * ii) * p, p, epsilon = 1.0e-7)
&& relative_eq!((ii * i) * p, p, epsilon = 1.0e-7)
&& relative_eq!((i * ii) * v, v, epsilon = 1.0e-7)
&& relative_eq!((ii * i) * v, v, epsilon = 1.0e-7));
}
#[cfg_attr(rustfmt, rustfmt_skip)]
#[test]
fn multiply_equals_alga_transform(
dq in unit_dual_quaternion(),
v in vector3(),
p in point3()
) {
prop_assert!(dq * v == dq.transform_vector(&v)
&& dq * p == dq.transform_point(&p)
&& relative_eq!(
dq.inverse() * v,
dq.inverse_transform_vector(&v),
epsilon = 1.0e-7
)
&& relative_eq!(
dq.inverse() * p,
dq.inverse_transform_point(&p),
epsilon = 1.0e-7
));
}
#[cfg_attr(rustfmt, rustfmt_skip)]
#[test]
fn composition(
dq in unit_dual_quaternion(),
uq in unit_quaternion(),
t in translation3(),
v in vector3(),
p in point3()
) {
// (rotation × dual quaternion) * point = rotation × (dual quaternion * point)
prop_assert!(relative_eq!((uq * dq) * v, uq * (dq * v), epsilon = 1.0e-7));
prop_assert!(relative_eq!((uq * dq) * p, uq * (dq * p), epsilon = 1.0e-7));
// (dual quaternion × rotation) * point = dual quaternion × (rotation * point)
prop_assert!(relative_eq!((dq * uq) * v, dq * (uq * v), epsilon = 1.0e-7));
prop_assert!(relative_eq!((dq * uq) * p, dq * (uq * p), epsilon = 1.0e-7));
// (translation × dual quaternion) * point = translation × (dual quaternion * point)
prop_assert!(relative_eq!((t * dq) * v, (dq * v), epsilon = 1.0e-7));
prop_assert!(relative_eq!((t * dq) * p, t * (dq * p), epsilon = 1.0e-7));
// (dual quaternion × translation) * point = dual quaternion × (translation * point)
prop_assert!(relative_eq!((dq * t) * v, dq * v, epsilon = 1.0e-7));
prop_assert!(relative_eq!((dq * t) * p, dq * (t * p), epsilon = 1.0e-7));
}
#[cfg_attr(rustfmt, rustfmt_skip)]
#[test]
fn all_op_exist(
dq in dual_quaternion(),
udq in unit_dual_quaternion(),
uq in unit_quaternion(),
s in PROPTEST_F64,
t in translation3(),
v in vector3(),
p in point3()
) {
let dqMs: DualQuaternion<_> = dq * s;
let dqMdq: DualQuaternion<_> = dq * dq;
let dqMudq: DualQuaternion<_> = dq * udq;
let udqMdq: DualQuaternion<_> = udq * dq;
let iMi: UnitDualQuaternion<_> = udq * udq;
let iMuq: UnitDualQuaternion<_> = udq * uq;
let iDi: UnitDualQuaternion<_> = udq / udq;
let iDuq: UnitDualQuaternion<_> = udq / uq;
let iMp: Point3<_> = udq * p;
let iMv: Vector3<_> = udq * v;
let iMt: UnitDualQuaternion<_> = udq * t;
let tMi: UnitDualQuaternion<_> = t * udq;
let uqMi: UnitDualQuaternion<_> = uq * udq;
let uqDi: UnitDualQuaternion<_> = uq / udq;
let mut dqMs1 = dq;
let mut dqMdq1 = dq;
let mut dqMdq2 = dq;
let mut dqMudq1 = dq;
let mut dqMudq2 = dq;
let mut iMt1 = udq;
let mut iMt2 = udq;
let mut iMi1 = udq;
let mut iMi2 = udq;
let mut iMuq1 = udq;
let mut iMuq2 = udq;
let mut iDi1 = udq;
let mut iDi2 = udq;
let mut iDuq1 = udq;
let mut iDuq2 = udq;
dqMs1 *= s;
dqMdq1 *= dq;
dqMdq2 *= &dq;
dqMudq1 *= udq;
dqMudq2 *= &udq;
iMt1 *= t;
iMt2 *= &t;
iMi1 *= udq;
iMi2 *= &udq;
iMuq1 *= uq;
iMuq2 *= &uq;
iDi1 /= udq;
iDi2 /= &udq;
iDuq1 /= uq;
iDuq2 /= &uq;
prop_assert!(dqMs == dqMs1
&& dqMdq == dqMdq1
&& dqMdq == dqMdq2
&& dqMudq == dqMudq1
&& dqMudq == dqMudq2
&& iMt == iMt1
&& iMt == iMt2
&& iMi == iMi1
&& iMi == iMi2
&& iMuq == iMuq1
&& iMuq == iMuq2
&& iDi == iDi1
&& iDi == iDi2
&& iDuq == iDuq1
&& iDuq == iDuq2
&& dqMs == &dq * s
&& dqMdq == &dq * &dq
&& dqMdq == dq * &dq
&& dqMdq == &dq * dq
&& dqMudq == &dq * &udq
&& dqMudq == dq * &udq
&& dqMudq == &dq * udq
&& udqMdq == &udq * &dq
&& udqMdq == udq * &dq
&& udqMdq == &udq * dq
&& iMi == &udq * &udq
&& iMi == udq * &udq
&& iMi == &udq * udq
&& iMuq == &udq * &uq
&& iMuq == udq * &uq
&& iMuq == &udq * uq
&& iDi == &udq / &udq
&& iDi == udq / &udq
&& iDi == &udq / udq
&& iDuq == &udq / &uq
&& iDuq == udq / &uq
&& iDuq == &udq / uq
&& iMp == &udq * &p
&& iMp == udq * &p
&& iMp == &udq * p
&& iMv == &udq * &v
&& iMv == udq * &v
&& iMv == &udq * v
&& iMt == &udq * &t
&& iMt == udq * &t
&& iMt == &udq * t
&& tMi == &t * &udq
&& tMi == t * &udq
&& tMi == &t * udq
&& uqMi == &uq * &udq
&& uqMi == uq * &udq
&& uqMi == &uq * udq
&& uqDi == &uq / &udq
&& uqDi == uq / &udq
&& uqDi == &uq / udq)
}
);