diff --git a/src/geometry/dual_quaternion_ops.rs b/src/geometry/dual_quaternion_ops.rs index d6cb35b6..2cf91b0f 100644 --- a/src/geometry/dual_quaternion_ops.rs +++ b/src/geometry/dual_quaternion_ops.rs @@ -242,6 +242,66 @@ dual_quaternion_op_impl!( self: DualQuaternion, rhs: DualQuaternion, Output = DualQuaternion; &self * &rhs; ); +// DualQuaternion × UnitDualQuaternion +dual_quaternion_op_impl!( + Mul, mul; + (U4, U1), (U4, U1); + self: &'a DualQuaternion, rhs: &'b UnitDualQuaternion, Output = DualQuaternion; + self * rhs.dual_quaternion(); + 'a, 'b); + +dual_quaternion_op_impl!( + Mul, mul; + (U4, U1), (U4, U1); + self: &'a DualQuaternion, rhs: UnitDualQuaternion, Output = DualQuaternion; + self * rhs.dual_quaternion(); + 'a); + +dual_quaternion_op_impl!( + Mul, mul; + (U4, U1), (U4, U1); + self: DualQuaternion, rhs: &'b UnitDualQuaternion, Output = DualQuaternion; + self * rhs.dual_quaternion(); + 'b); + +dual_quaternion_op_impl!( + Mul, mul; + (U4, U1), (U4, U1); + self: DualQuaternion, rhs: UnitDualQuaternion, Output = DualQuaternion; + self * rhs.dual_quaternion();); + +// DualQuaternion ÷ UnitDualQuaternion +dual_quaternion_op_impl!( + Div, div; + (U4, U1), (U4, U1); + self: &'a DualQuaternion, rhs: &'b UnitDualQuaternion, Output = DualQuaternion; + #[allow(clippy::suspicious_arithmetic_impl)] + { self * rhs.inverse().dual_quaternion() }; + 'a, 'b); + +dual_quaternion_op_impl!( + Div, div; + (U4, U1), (U4, U1); + self: &'a DualQuaternion, rhs: UnitDualQuaternion, Output = DualQuaternion; + #[allow(clippy::suspicious_arithmetic_impl)] + { self * rhs.inverse().dual_quaternion() }; + 'a); + +dual_quaternion_op_impl!( + Div, div; + (U4, U1), (U4, U1); + self: DualQuaternion, rhs: &'b UnitDualQuaternion, Output = DualQuaternion; + #[allow(clippy::suspicious_arithmetic_impl)] + { self * rhs.inverse().dual_quaternion() }; + 'b); + +dual_quaternion_op_impl!( + Div, div; + (U4, U1), (U4, U1); + self: DualQuaternion, rhs: UnitDualQuaternion, Output = DualQuaternion; + #[allow(clippy::suspicious_arithmetic_impl)] + { self * rhs.inverse().dual_quaternion() };); + // UnitDualQuaternion × UnitDualQuaternion dual_quaternion_op_impl!( Mul, mul; @@ -298,6 +358,38 @@ dual_quaternion_op_impl!( self: UnitDualQuaternion, rhs: UnitDualQuaternion, Output = UnitDualQuaternion; &self / &rhs; ); +// UnitDualQuaternion × DualQuaternion +dual_quaternion_op_impl!( + Mul, mul; + (U4, U1), (U4, U1); + self: &'a UnitDualQuaternion, rhs: &'b DualQuaternion, + Output = DualQuaternion => U1, U4; + self.dual_quaternion() * rhs; + 'a, 'b); + +dual_quaternion_op_impl!( + Mul, mul; + (U4, U1), (U4, U1); + self: &'a UnitDualQuaternion, rhs: DualQuaternion, + Output = DualQuaternion => U3, U3; + self.dual_quaternion() * rhs; + 'a); + +dual_quaternion_op_impl!( + Mul, mul; + (U4, U1), (U4, U1); + self: UnitDualQuaternion, rhs: &'b DualQuaternion, + Output = DualQuaternion => U3, U3; + self.dual_quaternion() * rhs; + 'b); + +dual_quaternion_op_impl!( + Mul, mul; + (U4, U1), (U4, U1); + self: UnitDualQuaternion, rhs: DualQuaternion, + Output = DualQuaternion => U3, U3; + self.dual_quaternion() * rhs;); + // UnitDualQuaternion × UnitQuaternion dual_quaternion_op_impl!( Mul, mul; @@ -917,8 +1009,44 @@ dual_quaternion_op_impl!( MulAssign, mul_assign; (U4, U1), (U4, U1); self: DualQuaternion, rhs: DualQuaternion; + *self *= &rhs;); + +// DualQuaternion ×= UnitDualQuaternion +dual_quaternion_op_impl!( + MulAssign, mul_assign; + (U4, U1), (U4, U1); + self: DualQuaternion, rhs: &'b UnitDualQuaternion; + { + let res = &*self * rhs; + self.real.coords.copy_from(&res.real.coords); + self.dual.coords.copy_from(&res.dual.coords); + }; + 'b); + +dual_quaternion_op_impl!( + MulAssign, mul_assign; + (U4, U1), (U4, U1); + self: DualQuaternion, rhs: UnitDualQuaternion; *self *= &rhs; ); +// DualQuaternion ÷= UnitDualQuaternion +dual_quaternion_op_impl!( + DivAssign, div_assign; + (U4, U1), (U4, U1); + self: DualQuaternion, rhs: &'b UnitDualQuaternion; + { + let res = &*self / rhs; + self.real.coords.copy_from(&res.real.coords); + self.dual.coords.copy_from(&res.dual.coords); + }; + 'b); + +dual_quaternion_op_impl!( + DivAssign, div_assign; + (U4, U1), (U4, U1); + self: DualQuaternion, rhs: UnitDualQuaternion; + *self /= &rhs; ); + // UnitDualQuaternion ×= UnitDualQuaternion dual_quaternion_op_impl!( MulAssign, mul_assign; diff --git a/tests/geometry/dual_quaternion.rs b/tests/geometry/dual_quaternion.rs index 727e6aa1..c3254ce6 100644 --- a/tests/geometry/dual_quaternion.rs +++ b/tests/geometry/dual_quaternion.rs @@ -1,7 +1,7 @@ #![cfg(feature = "arbitrary")] #![allow(non_snake_case)] -use na::{Isometry3, Point3, Translation3, UnitDualQuaternion, UnitQuaternion, Vector3}; +use na::{DualQuaternion, Isometry3, Point3, Translation3, UnitDualQuaternion, UnitQuaternion, Vector3}; quickcheck!( fn isometry_equivalence(iso: Isometry3, p: Point3, v: Vector3) -> bool { @@ -68,61 +68,86 @@ quickcheck!( #[cfg_attr(rustfmt, rustfmt_skip)] fn all_op_exist( - dq: UnitDualQuaternion, + dq: DualQuaternion, + udq: UnitDualQuaternion, uq: UnitQuaternion, + s: f64, t: Translation3, v: Vector3, p: Point3 ) -> bool { - let iMi = dq * dq; - let iMuq = dq * uq; - let iDi = dq / dq; - let iDuq = dq / uq; + let dqMs: DualQuaternion<_> = dq * s; - let iMp = dq * p; - let iMv = dq * v; + let dqMdq: DualQuaternion<_> = dq * dq; + let dqMudq: DualQuaternion<_> = dq * udq; + let udqMdq: DualQuaternion<_> = udq * dq; - let iMt = dq * t; - let tMi = t * dq; + let iMi: UnitDualQuaternion<_> = udq * udq; + let iMuq: UnitDualQuaternion<_> = udq * uq; + let iDi: UnitDualQuaternion<_> = udq / udq; + let iDuq: UnitDualQuaternion<_> = udq / uq; - let tMuq = t * uq; + let iMp: Point3<_> = udq * p; + let iMv: Vector3<_> = udq * v; - let uqMi = uq * dq; - let uqDi = uq / dq; + let iMt: UnitDualQuaternion<_> = udq * t; + let tMi: UnitDualQuaternion<_> = t * udq; - let uqMt = uq * t; + let uqMi: UnitDualQuaternion<_> = uq * udq; + let uqDi: UnitDualQuaternion<_> = uq / udq; - let mut iMt1 = dq; - let mut iMt2 = dq; + let mut dqMs1 = dq; - let mut iMi1 = dq; - let mut iMi2 = dq; + let mut dqMdq1 = dq; + let mut dqMdq2 = dq; - let mut iMuq1 = dq; - let mut iMuq2 = dq; + let mut dqMudq1 = dq; + let mut dqMudq2 = dq; - let mut iDi1 = dq; - let mut iDi2 = dq; + let mut iMt1 = udq; + let mut iMt2 = udq; - let mut iDuq1 = dq; - let mut iDuq2 = dq; + 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 *= dq; - iMi2 *= &dq; + iMi1 *= udq; + iMi2 *= &udq; iMuq1 *= uq; iMuq2 *= &uq; - iDi1 /= dq; - iDi2 /= &dq; + iDi1 /= udq; + iDi2 /= &udq; iDuq1 /= uq; iDuq2 /= &uq; - iMt == iMt1 + dqMs == dqMs1 + && dqMdq == dqMdq1 + && dqMdq == dqMdq2 + && dqMudq == dqMudq1 + && dqMudq == dqMudq2 + && iMt == iMt1 && iMt == iMt2 && iMi == iMi1 && iMi == iMi2 @@ -132,41 +157,45 @@ quickcheck!( && iDi == iDi2 && iDuq == iDuq1 && iDuq == iDuq2 - && iMi == &dq * &dq - && iMi == dq * &dq - && iMi == &dq * dq - && iMuq == &dq * &uq - && iMuq == dq * &uq - && iMuq == &dq * uq - && iDi == &dq / &dq - && iDi == dq / &dq - && iDi == &dq / dq - && iDuq == &dq / &uq - && iDuq == dq / &uq - && iDuq == &dq / uq - && iMp == &dq * &p - && iMp == dq * &p - && iMp == &dq * p - && iMv == &dq * &v - && iMv == dq * &v - && iMv == &dq * v - && iMt == &dq * &t - && iMt == dq * &t - && iMt == &dq * t - && tMi == &t * &dq - && tMi == t * &dq - && tMi == &t * dq - && tMuq == &t * &uq - && tMuq == t * &uq - && tMuq == &t * uq - && uqMi == &uq * &dq - && uqMi == uq * &dq - && uqMi == &uq * dq - && uqDi == &uq / &dq - && uqDi == uq / &dq - && uqDi == &uq / dq - && uqMt == &uq * &t - && uqMt == uq * &t - && uqMt == &uq * t + && 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 } );