diff --git a/src/geometry/isometry_ops.rs b/src/geometry/isometry_ops.rs index 4c0b5860..8b00fcda 100644 --- a/src/geometry/isometry_ops.rs +++ b/src/geometry/isometry_ops.rs @@ -5,11 +5,13 @@ use simba::scalar::{ClosedAdd, ClosedMul}; use simba::simd::SimdRealField; use crate::base::allocator::Allocator; -use crate::base::dimension::{DimName, U1, U3, U4}; +use crate::base::dimension::{DimName, U1, U2, U3, U4}; use crate::base::{DefaultAllocator, Unit, VectorN}; use crate::Scalar; -use crate::geometry::{AbstractRotation, Isometry, Point, Rotation, Translation, UnitQuaternion}; +use crate::geometry::{ + AbstractRotation, Isometry, Point, Rotation, Translation, UnitComplex, UnitQuaternion, +}; // FIXME: there are several cloning of rotations that we could probably get rid of (but we didn't // yet because that would require to add a bound like `where for<'a, 'b> &'a R: Mul<&'b R, Output = R>` @@ -228,6 +230,23 @@ md_assign_impl_all!( [ref] => *self *= rhs.inverse(); ); +md_assign_impl_all!( + MulAssign, mul_assign where N: SimdRealField for N::Element: SimdRealField; + (U2, U2), (U2, U2) for; + self: Isometry>, rhs: UnitComplex; + [val] => self.rotation *= rhs; + [ref] => self.rotation *= rhs.clone(); +); + +md_assign_impl_all!( + DivAssign, div_assign where N: SimdRealField for N::Element: SimdRealField; + (U2, U2), (U2, U2) for; + self: Isometry>, rhs: UnitComplex; + // FIXME: don't invert explicitly? + [val] => *self *= rhs.inverse(); + [ref] => *self *= rhs.inverse(); +); + // Isometry × Point isometry_binop_impl_all!( Mul, mul; @@ -487,3 +506,27 @@ isometry_from_composition_impl_all!( [val ref] => Isometry::from_parts(self, right.clone()); [ref ref] => Isometry::from_parts(self.clone(), right.clone()); ); + +// Isometry × UnitComplex +isometry_from_composition_impl_all!( + Mul, mul; + (U2, U1), (U2, U1); + self: Isometry>, rhs: UnitComplex, + Output = Isometry>; + [val val] => Isometry::from_parts(self.translation, self.rotation * rhs); + [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs); // FIXME: do not clone. + [val ref] => Isometry::from_parts(self.translation, self.rotation * rhs.clone()); + [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() * rhs.clone()); +); + +// Isometry ÷ UnitComplex +isometry_from_composition_impl_all!( + Div, div; + (U2, U1), (U2, U1); + self: Isometry>, rhs: UnitComplex, + Output = Isometry>; + [val val] => Isometry::from_parts(self.translation, self.rotation / rhs); + [ref val] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs); // FIXME: do not clone. + [val ref] => Isometry::from_parts(self.translation, self.rotation / rhs.clone()); + [ref ref] => Isometry::from_parts(self.translation.clone(), self.rotation.clone() / rhs.clone()); +); diff --git a/src/geometry/point.rs b/src/geometry/point.rs index bc1b138a..b2b44033 100644 --- a/src/geometry/point.rs +++ b/src/geometry/point.rs @@ -12,6 +12,8 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; +use simba::simd::SimdPartialOrd; + use crate::base::allocator::Allocator; use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::iter::{MatrixIter, MatrixIterMut}; @@ -307,6 +309,32 @@ where DefaultAllocator: Allocator } } +/* + * inf/sup + */ +impl Point +where DefaultAllocator: Allocator +{ + /// Computes the infimum (aka. componentwise min) of two points. + #[inline] + pub fn inf(&self, other: &Self) -> Point { + self.coords.inf(&other.coords).into() + } + + /// Computes the supremum (aka. componentwise max) of two points. + #[inline] + pub fn sup(&self, other: &Self) -> Point { + self.coords.sup(&other.coords).into() + } + + /// Computes the (infimum, supremum) of two points. + #[inline] + pub fn inf_sup(&self, other: &Self) -> (Point, Point) { + let (inf, sup) = self.coords.inf_sup(&other.coords); + (inf.into(), sup.into()) + } +} + /* * * Display diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs index 701d534a..ed98d217 100755 --- a/src/geometry/similarity.rs +++ b/src/geometry/similarity.rs @@ -124,11 +124,15 @@ where self.scaling = scaling; } +} +impl Similarity +where DefaultAllocator: Allocator +{ /// The scaling factor of this similarity transformation. #[inline] pub fn scaling(&self) -> N { - self.scaling.clone() + self.scaling.inlined_clone() } } diff --git a/src/geometry/similarity_ops.rs b/src/geometry/similarity_ops.rs index f98063dc..9043a667 100644 --- a/src/geometry/similarity_ops.rs +++ b/src/geometry/similarity_ops.rs @@ -5,11 +5,12 @@ use simba::scalar::{ClosedAdd, ClosedMul}; use simba::simd::SimdRealField; use crate::base::allocator::Allocator; -use crate::base::dimension::{DimName, U1, U3, U4}; +use crate::base::dimension::{DimName, U1, U2, U3, U4}; use crate::base::{DefaultAllocator, Scalar, VectorN}; use crate::geometry::{ - AbstractRotation, Isometry, Point, Rotation, Similarity, Translation, UnitQuaternion, + AbstractRotation, Isometry, Point, Rotation, Similarity, Translation, UnitComplex, + UnitQuaternion, }; // FIXME: there are several cloning of rotations that we could probably get rid of (but we didn't @@ -252,6 +253,23 @@ md_assign_impl_all!( [ref] => *self *= rhs.inverse(); ); +md_assign_impl_all!( + MulAssign, mul_assign where N: SimdRealField for N::Element: SimdRealField; + (U2, U2), (U2, U2) for; + self: Similarity>, rhs: UnitComplex; + [val] => self.isometry.rotation *= rhs; + [ref] => self.isometry.rotation *= rhs.clone(); +); + +md_assign_impl_all!( + DivAssign, div_assign where N: SimdRealField for N::Element: SimdRealField; + (U2, U2), (U2, U2) for; + self: Similarity>, rhs: UnitComplex; + // FIXME: don't invert explicitly? + [val] => *self *= rhs.inverse(); + [ref] => *self *= rhs.inverse(); +); + // Similarity × Isometry // Similarity ÷ Isometry similarity_binop_impl_all!( @@ -513,7 +531,7 @@ similarity_from_composition_impl_all!( [ref ref] => Similarity::from_isometry(self * &right.isometry, right.scaling()); ); -// Similarity ÷ Rotation +// Similarity ÷ UnitQuaternion similarity_from_composition_impl_all!( Div, div; (U4, U1), (U3, U1); @@ -543,3 +561,39 @@ similarity_from_composition_impl_all!( [val ref] => self * right.inverse(); [ref ref] => self * right.inverse(); ); + +// Similarity × UnitComplex +similarity_from_composition_impl_all!( + Mul, mul; + (U2, U1), (U2, U1); + self: Similarity>, rhs: UnitComplex, + Output = Similarity>; + [val val] => { + let scaling = self.scaling(); + Similarity::from_isometry(self.isometry * rhs, scaling) + }; + [ref val] => Similarity::from_isometry(&self.isometry * rhs, self.scaling()); + [val ref] => { + let scaling = self.scaling(); + Similarity::from_isometry(self.isometry * rhs, scaling) + }; + [ref ref] => Similarity::from_isometry(&self.isometry * rhs, self.scaling()); +); + +// Similarity ÷ UnitComplex +similarity_from_composition_impl_all!( + Div, div; + (U2, U1), (U2, U1); + self: Similarity>, rhs: UnitComplex, + Output = Similarity>; + [val val] => { + let scaling = self.scaling(); + Similarity::from_isometry(self.isometry / rhs, scaling) + }; + [ref val] => Similarity::from_isometry(&self.isometry / rhs, self.scaling()); + [val ref] => { + let scaling = self.scaling(); + Similarity::from_isometry(self.isometry / rhs, scaling) + }; + [ref ref] => Similarity::from_isometry(&self.isometry / rhs, self.scaling()); +); diff --git a/src/geometry/unit_complex_ops.rs b/src/geometry/unit_complex_ops.rs index d10d323e..32281020 100644 --- a/src/geometry/unit_complex_ops.rs +++ b/src/geometry/unit_complex_ops.rs @@ -29,8 +29,6 @@ use simba::simd::SimdRealField; * UnitComplex × Similarity * UnitComplex × Translation -> Isometry * - * NOTE: -UnitComplex is already provided by `Unit`. - * * (Assignment Operators) * * UnitComplex ×= UnitComplex diff --git a/src/lib.rs b/src/lib.rs index 5ecab6d6..d0a20c36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -153,7 +153,7 @@ pub use num_complex::Complex; pub use simba::scalar::{ ClosedAdd, ClosedDiv, ClosedMul, ClosedSub, ComplexField, Field, RealField, }; -pub use simba::simd::{SimdBool, SimdComplexField, SimdRealField}; +pub use simba::simd::{SimdBool, SimdComplexField, SimdPartialOrd, SimdRealField}; /// Gets the multiplicative identity element. /// @@ -249,29 +249,47 @@ pub fn min(a: T, b: T) -> T { /// The absolute value of `a`. /// /// Deprecated: Use [Matrix::abs] or [RealField::abs] instead. -#[deprecated(note = "use `Matrix::abs` or `RealField::abs` instead")] +#[deprecated(note = "use the inherent method `Matrix::abs` or `RealField::abs` instead")] #[inline] pub fn abs(a: &T) -> T { a.abs() } -///// Returns the infimum of `a` and `b`. -//#[inline] -//pub fn inf(a: &T, b: &T) -> T { -// a.meet(b) -//} -// -///// Returns the supremum of `a` and `b`. -//#[inline] -//pub fn sup(a: &T, b: &T) -> T { -// a.join(b) -//} -// -///// Returns simultaneously the infimum and supremum of `a` and `b`. -//#[inline] -//pub fn inf_sup(a: &T, b: &T) -> (T, T) { -// a.meet_join(b) -//} +/// Returns the infimum of `a` and `b`. +#[deprecated(note = "use the inherent method `Matrix::inf` instead")] +#[inline] +pub fn inf(a: &MatrixMN, b: &MatrixMN) -> MatrixMN +where + N: Scalar + SimdPartialOrd, + DefaultAllocator: Allocator, +{ + a.inf(b) +} + +/// Returns the supremum of `a` and `b`. +#[deprecated(note = "use the inherent method `Matrix::sup` instead")] +#[inline] +pub fn sup(a: &MatrixMN, b: &MatrixMN) -> MatrixMN +where + N: Scalar + SimdPartialOrd, + DefaultAllocator: Allocator, +{ + a.sup(b) +} + +/// Returns simultaneously the infimum and supremum of `a` and `b`. +#[deprecated(note = "use the inherent method `Matrix::inf_sup` instead")] +#[inline] +pub fn inf_sup( + a: &MatrixMN, + b: &MatrixMN, +) -> (MatrixMN, MatrixMN) +where + N: Scalar + SimdPartialOrd, + DefaultAllocator: Allocator, +{ + a.inf_sup(b) +} /// Compare `a` and `b` using a partial ordering relation. #[inline]