This commit is contained in:
Terence 2021-01-28 18:46:14 -05:00
parent 6be0365203
commit 388b77108e
11 changed files with 77 additions and 71 deletions

View File

@ -1,11 +1,11 @@
use std::fmt;
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
use crate::{
Quaternion, SimdRealField, VectorN, U8, Vector3, Point3, Isometry3, Unit, Matrix4,
Translation3, UnitQuaternion, Scalar, Normed
Isometry3, Matrix4, Normed, Point3, Quaternion, Scalar, SimdRealField, Translation3, Unit,
UnitQuaternion, Vector3, VectorN, U8,
};
use approx::{AbsDiffEq, RelativeEq, UlpsEq};
#[cfg(feature = "serde-serialize")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
use simba::scalar::{ClosedNeg, RealField};
@ -432,7 +432,9 @@ where
#[inline]
#[must_use = "Did you mean to use inverse_mut()?"]
pub fn inverse(&self) -> Self {
let real = Unit::new_unchecked(self.as_ref().real).inverse().into_inner();
let real = Unit::new_unchecked(self.as_ref().real)
.inverse()
.into_inner();
let dual = -real * self.as_ref().dual * real;
UnitDualQuaternion::new_unchecked(DualQuaternion { real, dual })
}
@ -634,9 +636,11 @@ where
moment * sin + direction * (pitch * half * cos),
);
Some(self * UnitDualQuaternion::new_unchecked(
DualQuaternion::from_real_and_dual(real, dual)
))
Some(
self * UnitDualQuaternion::new_unchecked(DualQuaternion::from_real_and_dual(
real, dual,
)),
)
}
/// Return the rotation part of this unit dual quaternion.
@ -844,8 +848,7 @@ where
/// assert_relative_eq!(dq.to_homogeneous(), expected, epsilon = 1.0e-6);
/// ```
#[inline]
pub fn to_homogeneous(&self) -> Matrix4<N>
{
pub fn to_homogeneous(&self) -> Matrix4<N> {
self.to_isometry().to_homogeneous()
}
}

View File

@ -7,13 +7,12 @@ use alga::general::{
};
use alga::linear::{
AffineTransformation, DirectIsometry, FiniteDimVectorSpace, Isometry, NormedSpace,
ProjectiveTransformation, Similarity, Transformation,
VectorSpace,
ProjectiveTransformation, Similarity, Transformation, VectorSpace,
};
use crate::base::Vector3;
use crate::geometry::{
Point3, Quaternion, UnitQuaternion, DualQuaternion, UnitDualQuaternion, Translation3
DualQuaternion, Point3, Quaternion, Translation3, UnitDualQuaternion, UnitQuaternion,
};
impl<N: RealField + simba::scalar::RealField> Identity<Multiplicative> for DualQuaternion<N> {
@ -103,12 +102,12 @@ impl<N: RealField + simba::scalar::RealField> FiniteDimVectorSpace for DualQuate
if i < 4 {
DualQuaternion::from_real_and_dual(
Quaternion::canonical_basis_element(i),
Quaternion::zero()
Quaternion::zero(),
)
} else {
DualQuaternion::from_real_and_dual(
Quaternion::zero(),
Quaternion::canonical_basis_element(i - 4)
Quaternion::canonical_basis_element(i - 4),
)
}
}
@ -157,7 +156,10 @@ impl<N: RealField + simba::scalar::RealField> NormedSpace for DualQuaternion<N>
fn try_normalize(&self, min_norm: N) -> Option<Self> {
let real_norm = self.real.norm();
if real_norm > min_norm {
Some(Self::from_real_and_dual(self.real / real_norm, self.dual / real_norm))
Some(Self::from_real_and_dual(
self.real / real_norm,
self.dual / real_norm,
))
} else {
None
}
@ -188,7 +190,9 @@ impl<N: RealField + simba::scalar::RealField> Identity<Multiplicative> for UnitD
}
}
impl<N: RealField + simba::scalar::RealField> AbstractMagma<Multiplicative> for UnitDualQuaternion<N> {
impl<N: RealField + simba::scalar::RealField> AbstractMagma<Multiplicative>
for UnitDualQuaternion<N>
{
#[inline]
fn operate(&self, rhs: &Self) -> Self {
self * rhs
@ -253,7 +257,12 @@ impl<N: RealField + simba::scalar::RealField> AffineTransformation<Point3<N>>
#[inline]
fn decompose(&self) -> (Self::Translation, Self::Rotation, Id, Self::Rotation) {
(self.translation(), self.rotation(), Id::new(), UnitQuaternion::identity())
(
self.translation(),
self.rotation(),
Id::new(),
UnitQuaternion::identity(),
)
}
#[inline]
@ -313,4 +322,3 @@ macro_rules! marker_impl(
);
marker_impl!(Isometry, DirectIsometry);

View File

@ -1,10 +1,10 @@
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
use crate::{
DualQuaternion, Quaternion, UnitDualQuaternion, SimdRealField, Isometry3,
Translation3, UnitQuaternion
DualQuaternion, Isometry3, Quaternion, SimdRealField, Translation3, UnitDualQuaternion,
UnitQuaternion,
};
use num::{One, Zero};
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};
impl<N: SimdRealField> DualQuaternion<N> {
/// Creates a dual quaternion from its rotation and translation components.
@ -50,9 +50,8 @@ impl<N: SimdRealField> DualQuaternion<N> {
impl<N: SimdRealField> DualQuaternion<N>
where
N::Element: SimdRealField
N::Element: SimdRealField,
{
/// Creates a dual quaternion from only its real part, with no translation
/// component.
///
@ -67,7 +66,10 @@ where
/// ```
#[inline]
pub fn from_real(real: Quaternion<N>) -> Self {
Self { real, dual: Quaternion::zero() }
Self {
real,
dual: Quaternion::zero(),
}
}
}
@ -87,10 +89,7 @@ where
{
#[inline]
fn zero() -> Self {
DualQuaternion::from_real_and_dual(
Quaternion::zero(),
Quaternion::zero()
)
DualQuaternion::from_real_and_dual(Quaternion::zero(), Quaternion::zero())
}
#[inline]
@ -107,10 +106,7 @@ where
{
#[inline]
fn arbitrary<G: Gen>(rng: &mut G) -> Self {
Self::from_real_and_dual(
Arbitrary::arbitrary(rng),
Arbitrary::arbitrary(rng)
)
Self::from_real_and_dual(Arbitrary::arbitrary(rng), Arbitrary::arbitrary(rng))
}
}
@ -151,10 +147,7 @@ where
/// assert_relative_eq!(dq * point, Point3::new(1.0, 0.0, 2.0), epsilon = 1.0e-6);
/// ```
#[inline]
pub fn from_parts(
translation: Translation3<N>,
rotation: UnitQuaternion<N>
) -> Self {
pub fn from_parts(translation: Translation3<N>, rotation: UnitQuaternion<N>) -> Self {
let half: N = crate::convert(0.5f64);
UnitDualQuaternion::new_unchecked(DualQuaternion {
real: rotation.clone().into_inner(),

View File

@ -4,8 +4,8 @@ use simba::simd::SimdRealField;
use crate::base::dimension::U3;
use crate::base::{Matrix4, Vector4};
use crate::geometry::{
Isometry3, DualQuaternion, Similarity3, SuperTCategoryOf,
TAffine, Transform, Translation3, UnitQuaternion, UnitDualQuaternion
DualQuaternion, Isometry3, Similarity3, SuperTCategoryOf, TAffine, Transform, Translation3,
UnitDualQuaternion, UnitQuaternion,
};
/*
@ -35,14 +35,15 @@ where
#[inline]
fn is_in_subset(dq: &DualQuaternion<N2>) -> bool {
crate::is_convertible::<_, Vector4<N1>>(&dq.real.coords) &&
crate::is_convertible::<_, Vector4<N1>>(&dq.dual.coords)
crate::is_convertible::<_, Vector4<N1>>(&dq.real.coords)
&& crate::is_convertible::<_, Vector4<N1>>(&dq.dual.coords)
}
#[inline]
fn from_superset_unchecked(dq: &DualQuaternion<N2>) -> Self {
DualQuaternion::from_real_and_dual(
dq.real.to_subset_unchecked(), dq.dual.to_subset_unchecked()
dq.real.to_subset_unchecked(),
dq.dual.to_subset_unchecked(),
)
}
}
@ -71,7 +72,7 @@ where
impl<N1, N2> SubsetOf<Isometry3<N2>> for UnitDualQuaternion<N1>
where
N1: RealField,
N2: RealField + SupersetOf<N1>
N2: RealField + SupersetOf<N1>,
{
#[inline]
fn to_superset(&self) -> Isometry3<N2> {
@ -82,8 +83,8 @@ where
#[inline]
fn is_in_subset(iso: &Isometry3<N2>) -> bool {
crate::is_convertible::<_, UnitQuaternion<N1>>(&iso.rotation) &&
crate::is_convertible::<_, Translation3<N1>>(&iso.translation)
crate::is_convertible::<_, UnitQuaternion<N1>>(&iso.rotation)
&& crate::is_convertible::<_, Translation3<N1>>(&iso.translation)
}
#[inline]
@ -96,7 +97,7 @@ where
impl<N1, N2> SubsetOf<Similarity3<N2>> for UnitDualQuaternion<N1>
where
N1: RealField,
N2: RealField + SupersetOf<N1>
N2: RealField + SupersetOf<N1>,
{
#[inline]
fn to_superset(&self) -> Similarity3<N2> {
@ -136,7 +137,9 @@ where
}
}
impl<N1: RealField, N2: RealField + SupersetOf<N1>> SubsetOf<Matrix4<N2>> for UnitDualQuaternion<N1> {
impl<N1: RealField, N2: RealField + SupersetOf<N1>> SubsetOf<Matrix4<N2>>
for UnitDualQuaternion<N1>
{
#[inline]
fn to_superset(&self) -> Matrix4<N2> {
self.to_homogeneous().to_superset()
@ -183,4 +186,3 @@ where
Self::from_isometry(&iso)
}
}

View File

@ -22,15 +22,15 @@
* - https://cs.gmu.edu/~jmlien/teaching/cs451/uploads/Main/dual-quaternion.pdf
*/
use crate::{
DualQuaternion, SimdRealField, Point3, Point, Vector3, Isometry3, Quaternion,
UnitDualQuaternion, UnitQuaternion, U1, U3, U4, Unit, Allocator,
DefaultAllocator, Vector, Translation3
};
use crate::base::storage::Storage;
use crate::{
Allocator, DefaultAllocator, DualQuaternion, Isometry3, Point, Point3, Quaternion,
SimdRealField, Translation3, Unit, UnitDualQuaternion, UnitQuaternion, Vector, Vector3, U1, U3,
U4,
};
use std::mem;
use std::ops::{
Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign
Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
};
impl<N: SimdRealField> AsRef<[N; 8]> for DualQuaternion<N> {

View File

@ -7,7 +7,7 @@ use crate::base::{DefaultAllocator, MatrixN, Scalar};
use crate::geometry::{
AbstractRotation, Isometry, Isometry3, Similarity, SuperTCategoryOf, TAffine, Transform,
Translation, UnitDualQuaternion, UnitQuaternion
Translation, UnitDualQuaternion, UnitQuaternion,
};
/*
@ -62,8 +62,8 @@ where
#[inline]
fn is_in_subset(dq: &UnitDualQuaternion<N2>) -> bool {
crate::is_convertible::<_, UnitQuaternion<N1>>(&dq.rotation()) &&
crate::is_convertible::<_, Translation<N1, _>>(&dq.translation())
crate::is_convertible::<_, UnitQuaternion<N1>>(&dq.rotation())
&& crate::is_convertible::<_, Translation<N1, _>>(&dq.translation())
}
#[inline]

View File

@ -10,7 +10,7 @@ use crate::base::dimension::U3;
use crate::base::{Matrix3, Matrix4, Scalar, Vector4};
use crate::geometry::{
AbstractRotation, Isometry, Quaternion, Rotation, Rotation3, Similarity, SuperTCategoryOf,
TAffine, Transform, Translation, UnitQuaternion, UnitDualQuaternion
TAffine, Transform, Translation, UnitDualQuaternion, UnitQuaternion,
};
/*
@ -125,7 +125,7 @@ where
impl<N1, N2> SubsetOf<UnitDualQuaternion<N2>> for UnitQuaternion<N1>
where
N1: RealField,
N2: RealField + SupersetOf<N1>
N2: RealField + SupersetOf<N1>,
{
#[inline]
fn to_superset(&self) -> UnitDualQuaternion<N2> {

View File

@ -12,7 +12,7 @@ use crate::base::{DefaultAllocator, Matrix2, Matrix3, Matrix4, MatrixN, Scalar};
use crate::geometry::{
AbstractRotation, Isometry, Rotation, Rotation2, Rotation3, Similarity, SuperTCategoryOf,
TAffine, Transform, Translation, UnitComplex, UnitQuaternion, UnitDualQuaternion,
TAffine, Transform, Translation, UnitComplex, UnitDualQuaternion, UnitQuaternion,
};
/*
@ -90,8 +90,8 @@ where
#[inline]
fn is_in_subset(dq: &UnitDualQuaternion<N2>) -> bool {
crate::is_convertible::<_, UnitQuaternion<N1>>(&dq.rotation()) &&
dq.translation().vector.is_zero()
crate::is_convertible::<_, UnitQuaternion<N1>>(&dq.rotation())
&& dq.translation().vector.is_zero()
}
#[inline]

View File

@ -9,7 +9,7 @@ use crate::base::{DefaultAllocator, MatrixN, Scalar, VectorN};
use crate::geometry::{
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation,
Translation3, UnitDualQuaternion, UnitQuaternion
Translation3, UnitDualQuaternion, UnitQuaternion,
};
/*
@ -84,8 +84,8 @@ where
#[inline]
fn is_in_subset(dq: &UnitDualQuaternion<N2>) -> bool {
crate::is_convertible::<_, Translation<N1, _>>(&dq.translation()) &&
dq.rotation() == UnitQuaternion::identity()
crate::is_convertible::<_, Translation<N1, _>>(&dq.translation())
&& dq.rotation() == UnitQuaternion::identity()
}
#[inline]

View File

@ -1,9 +1,7 @@
#![cfg(feature = "arbitrary")]
#![allow(non_snake_case)]
use na::{
Isometry3, Point3, Translation3, UnitQuaternion, UnitDualQuaternion, Vector3,
};
use na::{Isometry3, Point3, Translation3, UnitDualQuaternion, UnitQuaternion, Vector3};
quickcheck!(
fn isometry_equivalence(iso: Isometry3<f64>, p: Point3<f64>, v: Vector3<f64>) -> bool {
@ -25,7 +23,9 @@ quickcheck!(
}
fn multiply_equals_alga_transform(
dq: UnitDualQuaternion<f64>, v: Vector3<f64>, p: Point3<f64>
dq: UnitDualQuaternion<f64>,
v: Vector3<f64>,
p: Point3<f64>,
) -> bool {
dq * v == dq.transform_vector(&v)
&& dq * p == dq.transform_point(&p)

View File

@ -1,3 +1,4 @@
mod dual_quaternion;
mod isometry;
mod point;
mod projection;
@ -5,4 +6,3 @@ mod quaternion;
mod rotation;
mod similarity;
mod unit_complex;
mod dual_quaternion;