From 8c6ad490bc90155f8e6e397b374a161986b6233b Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 14:02:07 +0200 Subject: [PATCH 01/35] Initial commit copy all translation_x files into scale_x files --- src/geometry/scale_alias.rs | 19 ++ src/geometry/scale_construction.rs | 123 ++++++++++++ src/geometry/scale_conversion.rs | 306 +++++++++++++++++++++++++++++ src/geometry/scale_coordinates.rs | 39 ++++ src/geometry/scale_ops.rs | 119 +++++++++++ src/geometry/scale_simba.rs | 49 +++++ 6 files changed, 655 insertions(+) create mode 100644 src/geometry/scale_alias.rs create mode 100644 src/geometry/scale_construction.rs create mode 100644 src/geometry/scale_conversion.rs create mode 100644 src/geometry/scale_coordinates.rs create mode 100644 src/geometry/scale_ops.rs create mode 100755 src/geometry/scale_simba.rs diff --git a/src/geometry/scale_alias.rs b/src/geometry/scale_alias.rs new file mode 100644 index 00000000..06dc0794 --- /dev/null +++ b/src/geometry/scale_alias.rs @@ -0,0 +1,19 @@ +use crate::geometry::Translation; + +/// A 1-dimensional translation. +pub type Translation1 = Translation; + +/// A 2-dimensional translation. +pub type Translation2 = Translation; + +/// A 3-dimensional translation. +pub type Translation3 = Translation; + +/// A 4-dimensional translation. +pub type Translation4 = Translation; + +/// A 5-dimensional translation. +pub type Translation5 = Translation; + +/// A 6-dimensional translation. +pub type Translation6 = Translation; diff --git a/src/geometry/scale_construction.rs b/src/geometry/scale_construction.rs new file mode 100644 index 00000000..5371b648 --- /dev/null +++ b/src/geometry/scale_construction.rs @@ -0,0 +1,123 @@ +#[cfg(feature = "arbitrary")] +use crate::base::storage::Owned; +#[cfg(feature = "arbitrary")] +use quickcheck::{Arbitrary, Gen}; + +use num::{One, Zero}; +#[cfg(feature = "rand-no-std")] +use rand::{ + distributions::{Distribution, Standard}, + Rng, +}; + +use simba::scalar::{ClosedAdd, SupersetOf}; + +use crate::base::{SVector, Scalar}; +use crate::geometry::Translation; + +impl Translation { + /// Creates a new identity translation. + /// + /// # Example + /// ``` + /// # use nalgebra::{Point2, Point3, Translation2, Translation3}; + /// let t = Translation2::identity(); + /// let p = Point2::new(1.0, 2.0); + /// assert_eq!(t * p, p); + /// + /// // Works in all dimensions. + /// let t = Translation3::identity(); + /// let p = Point3::new(1.0, 2.0, 3.0); + /// assert_eq!(t * p, p); + /// ``` + #[inline] + pub fn identity() -> Translation + where + T: Zero, + { + Self::from(SVector::::from_element(T::zero())) + } + + /// Cast the components of `self` to another type. + /// + /// # Example + /// ``` + /// # use nalgebra::Translation2; + /// let tra = Translation2::new(1.0f64, 2.0); + /// let tra2 = tra.cast::(); + /// assert_eq!(tra2, Translation2::new(1.0f32, 2.0)); + /// ``` + pub fn cast(self) -> Translation + where + Translation: SupersetOf, + { + crate::convert(self) + } +} + +impl One for Translation { + #[inline] + fn one() -> Self { + Self::identity() + } +} + +#[cfg(feature = "rand-no-std")] +impl Distribution> for Standard +where + Standard: Distribution, +{ + /// Generate an arbitrary random variate for testing purposes. + #[inline] + fn sample(&self, rng: &mut G) -> Translation { + Translation::from(rng.gen::>()) + } +} + +#[cfg(feature = "arbitrary")] +impl Arbitrary for Translation +where + Owned>: Send, +{ + #[inline] + fn arbitrary(rng: &mut Gen) -> Self { + let v: SVector = Arbitrary::arbitrary(rng); + Self::from(v) + } +} + +/* + * + * Small translation construction from components. + * + */ +macro_rules! componentwise_constructors_impl( + ($($doc: expr; $D: expr, $($args: ident:$irow: expr),*);* $(;)*) => {$( + impl Translation + { + #[doc = "Initializes this translation from its components."] + #[doc = "# Example\n```"] + #[doc = $doc] + #[doc = "```"] + #[inline] + pub const fn new($($args: T),*) -> Self { + Self { vector: SVector::::new($($args),*) } + } + } + )*} +); + +componentwise_constructors_impl!( + "# use nalgebra::Translation1;\nlet t = Translation1::new(1.0);\nassert!(t.vector.x == 1.0);"; + 1, x:0; + "# use nalgebra::Translation2;\nlet t = Translation2::new(1.0, 2.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0);"; + 2, x:0, y:1; + "# use nalgebra::Translation3;\nlet t = Translation3::new(1.0, 2.0, 3.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0);"; + 3, x:0, y:1, z:2; + "# use nalgebra::Translation4;\nlet t = Translation4::new(1.0, 2.0, 3.0, 4.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0);"; + 4, x:0, y:1, z:2, w:3; + "# use nalgebra::Translation5;\nlet t = Translation5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0);"; + 5, x:0, y:1, z:2, w:3, a:4; + "# use nalgebra::Translation6;\nlet t = Translation6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0 && t.vector.b == 6.0);"; + 6, x:0, y:1, z:2, w:3, a:4, b:5; +); diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs new file mode 100644 index 00000000..70000efb --- /dev/null +++ b/src/geometry/scale_conversion.rs @@ -0,0 +1,306 @@ +use num::{One, Zero}; + +use simba::scalar::{RealField, SubsetOf, SupersetOf}; +use simba::simd::PrimitiveSimdValue; + +use crate::base::allocator::Allocator; +use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; +use crate::base::{Const, DefaultAllocator, DimName, OMatrix, OVector, SVector, Scalar}; + +use crate::geometry::{ + AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, + Translation3, UnitDualQuaternion, UnitQuaternion, +}; +use crate::Point; + +/* + * This file provides the following conversions: + * ============================================= + * + * Translation -> Translation + * Translation -> Isometry + * Translation3 -> UnitDualQuaternion + * Translation -> Similarity + * Translation -> Transform + * Translation -> Matrix (homogeneous) + */ + +impl SubsetOf> for Translation +where + T1: Scalar, + T2: Scalar + SupersetOf, +{ + #[inline] + fn to_superset(&self) -> Translation { + Translation::from(self.vector.to_superset()) + } + + #[inline] + fn is_in_subset(rot: &Translation) -> bool { + crate::is_convertible::<_, SVector>(&rot.vector) + } + + #[inline] + fn from_superset_unchecked(rot: &Translation) -> Self { + Translation { + vector: rot.vector.to_subset_unchecked(), + } + } +} + +impl SubsetOf> for Translation +where + T1: RealField, + T2: RealField + SupersetOf, + R: AbstractRotation, +{ + #[inline] + fn to_superset(&self) -> Isometry { + Isometry::from_parts(self.to_superset(), R::identity()) + } + + #[inline] + fn is_in_subset(iso: &Isometry) -> bool { + iso.rotation == R::identity() + } + + #[inline] + fn from_superset_unchecked(iso: &Isometry) -> Self { + Self::from_superset_unchecked(&iso.translation) + } +} + +impl SubsetOf> for Translation3 +where + T1: RealField, + T2: RealField + SupersetOf, +{ + #[inline] + fn to_superset(&self) -> UnitDualQuaternion { + let dq = UnitDualQuaternion::::from_parts(self.clone(), UnitQuaternion::identity()); + dq.to_superset() + } + + #[inline] + fn is_in_subset(dq: &UnitDualQuaternion) -> bool { + crate::is_convertible::<_, Translation>(&dq.translation()) + && dq.rotation() == UnitQuaternion::identity() + } + + #[inline] + fn from_superset_unchecked(dq: &UnitDualQuaternion) -> Self { + let dq: UnitDualQuaternion = crate::convert_ref_unchecked(dq); + dq.translation() + } +} + +impl SubsetOf> for Translation +where + T1: RealField, + T2: RealField + SupersetOf, + R: AbstractRotation, +{ + #[inline] + fn to_superset(&self) -> Similarity { + Similarity::from_parts(self.to_superset(), R::identity(), T2::one()) + } + + #[inline] + fn is_in_subset(sim: &Similarity) -> bool { + sim.isometry.rotation == R::identity() && sim.scaling() == T2::one() + } + + #[inline] + fn from_superset_unchecked(sim: &Similarity) -> Self { + Self::from_superset_unchecked(&sim.isometry.translation) + } +} + +impl SubsetOf> for Translation +where + T1: RealField, + T2: RealField + SupersetOf, + C: SuperTCategoryOf, + Const: DimNameAdd, + DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + + Allocator, U1>, DimNameSum, U1>>, +{ + #[inline] + fn to_superset(&self) -> Transform { + Transform::from_matrix_unchecked(self.to_homogeneous().to_superset()) + } + + #[inline] + fn is_in_subset(t: &Transform) -> bool { + >::is_in_subset(t.matrix()) + } + + #[inline] + fn from_superset_unchecked(t: &Transform) -> Self { + Self::from_superset_unchecked(t.matrix()) + } +} + +impl + SubsetOf, U1>, DimNameSum, U1>>> for Translation +where + T1: RealField, + T2: RealField + SupersetOf, + Const: DimNameAdd, + DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + + Allocator, U1>, DimNameSum, U1>>, + // + Allocator + // + Allocator +{ + #[inline] + fn to_superset(&self) -> OMatrix, U1>, DimNameSum, U1>> { + self.to_homogeneous().to_superset() + } + + #[inline] + fn is_in_subset(m: &OMatrix, U1>, DimNameSum, U1>>) -> bool { + let id = m.generic_slice((0, 0), (DimNameSum::, U1>::name(), Const::)); + + // Scalar types agree. + m.iter().all(|e| SupersetOf::::is_in_subset(e)) && + // The block part does nothing. + id.is_identity(T2::zero()) && + // The normalization factor is one. + m[(D, D)] == T2::one() + } + + #[inline] + fn from_superset_unchecked( + m: &OMatrix, U1>, DimNameSum, U1>>, + ) -> Self { + let t = m.fixed_slice::(0, D); + Self { + vector: crate::convert_unchecked(t.into_owned()), + } + } +} + +impl From> + for OMatrix, U1>, DimNameSum, U1>> +where + Const: DimNameAdd, + DefaultAllocator: + Allocator, U1>, DimNameSum, U1>> + Allocator>, +{ + #[inline] + fn from(t: Translation) -> Self { + t.to_homogeneous() + } +} + +impl From>> for Translation { + #[inline] + fn from(vector: OVector>) -> Self { + Translation { vector } + } +} + +impl From<[T; D]> for Translation { + #[inline] + fn from(coords: [T; D]) -> Self { + Translation { + vector: coords.into(), + } + } +} + +impl From> for Translation { + #[inline] + fn from(pt: Point) -> Self { + Translation { vector: pt.coords } + } +} + +impl From> for [T; D] { + #[inline] + fn from(t: Translation) -> Self { + t.vector.into() + } +} + +impl From<[Translation; 2]> + for Translation +where + T: From<[::Element; 2]>, + T::Element: Scalar, +{ + #[inline] + fn from(arr: [Translation; 2]) -> Self { + Self::from(OVector::from([ + arr[0].vector.clone(), + arr[1].vector.clone(), + ])) + } +} + +impl From<[Translation; 4]> + for Translation +where + T: From<[::Element; 4]>, + T::Element: Scalar, +{ + #[inline] + fn from(arr: [Translation; 4]) -> Self { + Self::from(OVector::from([ + arr[0].vector.clone(), + arr[1].vector.clone(), + arr[2].vector.clone(), + arr[3].vector.clone(), + ])) + } +} + +impl From<[Translation; 8]> + for Translation +where + T: From<[::Element; 8]>, + T::Element: Scalar, +{ + #[inline] + fn from(arr: [Translation; 8]) -> Self { + Self::from(OVector::from([ + arr[0].vector.clone(), + arr[1].vector.clone(), + arr[2].vector.clone(), + arr[3].vector.clone(), + arr[4].vector.clone(), + arr[5].vector.clone(), + arr[6].vector.clone(), + arr[7].vector.clone(), + ])) + } +} + +impl From<[Translation; 16]> + for Translation +where + T: From<[::Element; 16]>, + T::Element: Scalar, +{ + #[inline] + fn from(arr: [Translation; 16]) -> Self { + Self::from(OVector::from([ + arr[0].vector.clone(), + arr[1].vector.clone(), + arr[2].vector.clone(), + arr[3].vector.clone(), + arr[4].vector.clone(), + arr[5].vector.clone(), + arr[6].vector.clone(), + arr[7].vector.clone(), + arr[8].vector.clone(), + arr[9].vector.clone(), + arr[10].vector.clone(), + arr[11].vector.clone(), + arr[12].vector.clone(), + arr[13].vector.clone(), + arr[14].vector.clone(), + arr[15].vector.clone(), + ])) + } +} diff --git a/src/geometry/scale_coordinates.rs b/src/geometry/scale_coordinates.rs new file mode 100644 index 00000000..80267e06 --- /dev/null +++ b/src/geometry/scale_coordinates.rs @@ -0,0 +1,39 @@ +use std::ops::{Deref, DerefMut}; + +use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB}; +use crate::base::Scalar; + +use crate::geometry::Translation; + +/* + * + * Give coordinates to Translation{1 .. 6} + * + */ + +macro_rules! deref_impl( + ($D: expr, $Target: ident $(, $comps: ident)*) => { + impl Deref for Translation { + type Target = $Target; + + #[inline] + fn deref(&self) -> &Self::Target { + unsafe { &*(self as *const Translation as *const Self::Target) } + } + } + + impl DerefMut for Translation { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + unsafe { &mut *(self as *mut Translation as *mut Self::Target) } + } + } + } +); + +deref_impl!(1, X, x); +deref_impl!(2, XY, x, y); +deref_impl!(3, XYZ, x, y, z); +deref_impl!(4, XYZW, x, y, z, w); +deref_impl!(5, XYZWA, x, y, z, w, a); +deref_impl!(6, XYZWAB, x, y, z, w, a, b); diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs new file mode 100644 index 00000000..8851183a --- /dev/null +++ b/src/geometry/scale_ops.rs @@ -0,0 +1,119 @@ +use std::ops::{Div, DivAssign, Mul, MulAssign}; + +use simba::scalar::{ClosedAdd, ClosedSub}; + +use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; +use crate::base::dimension::U1; +use crate::base::{Const, Scalar}; + +use crate::geometry::{Point, Translation}; + +// Translation × Translation +add_sub_impl!(Mul, mul, ClosedAdd; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: &'a Translation, right: &'b Translation, Output = Translation; + #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + &right.vector) }; + 'a, 'b); + +add_sub_impl!(Mul, mul, ClosedAdd; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: &'a Translation, right: Translation, Output = Translation; + #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + right.vector) }; + 'a); + +add_sub_impl!(Mul, mul, ClosedAdd; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: Translation, right: &'b Translation, Output = Translation; + #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + &right.vector) }; + 'b); + +add_sub_impl!(Mul, mul, ClosedAdd; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: Translation, right: Translation, Output = Translation; + #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + right.vector) }; ); + +// Translation ÷ Translation +// TODO: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method? +add_sub_impl!(Div, div, ClosedSub; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: &'a Translation, right: &'b Translation, Output = Translation; + #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - &right.vector) }; + 'a, 'b); + +add_sub_impl!(Div, div, ClosedSub; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: &'a Translation, right: Translation, Output = Translation; + #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - right.vector) }; + 'a); + +add_sub_impl!(Div, div, ClosedSub; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: Translation, right: &'b Translation, Output = Translation; + #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - &right.vector) }; + 'b); + +add_sub_impl!(Div, div, ClosedSub; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: Translation, right: Translation, Output = Translation; + #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - right.vector) }; ); + +// Translation × Point +// TODO: we don't handle properly non-zero origins here. Do we want this to be the intended +// behavior? +add_sub_impl!(Mul, mul, ClosedAdd; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: &'a Translation, right: &'b Point, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector }; + 'a, 'b); + +add_sub_impl!(Mul, mul, ClosedAdd; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: &'a Translation, right: Point, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector }; + 'a); + +add_sub_impl!(Mul, mul, ClosedAdd; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: Translation, right: &'b Point, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; + 'b); + +add_sub_impl!(Mul, mul, ClosedAdd; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: Translation, right: Point, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; ); + +// Translation *= Translation +add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; + const D; + self: Translation, right: &'b Translation; + #[allow(clippy::suspicious_op_assign_impl)] { self.vector += &right.vector }; + 'b); + +add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; + const D; + self: Translation, right: Translation; + #[allow(clippy::suspicious_op_assign_impl)] { self.vector += right.vector }; ); + +add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; + const D; + self: Translation, right: &'b Translation; + #[allow(clippy::suspicious_op_assign_impl)] { self.vector -= &right.vector }; + 'b); + +add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; + const D; + self: Translation, right: Translation; + #[allow(clippy::suspicious_op_assign_impl)] { self.vector -= right.vector }; ); diff --git a/src/geometry/scale_simba.rs b/src/geometry/scale_simba.rs new file mode 100755 index 00000000..7f7f7ebf --- /dev/null +++ b/src/geometry/scale_simba.rs @@ -0,0 +1,49 @@ +use simba::simd::SimdValue; + +use crate::base::OVector; +use crate::Scalar; + +use crate::geometry::Translation; + +impl SimdValue for Translation +where + T::Element: Scalar, +{ + type Element = Translation; + type SimdBool = T::SimdBool; + + #[inline] + fn lanes() -> usize { + T::lanes() + } + + #[inline] + fn splat(val: Self::Element) -> Self { + OVector::splat(val.vector).into() + } + + #[inline] + fn extract(&self, i: usize) -> Self::Element { + self.vector.extract(i).into() + } + + #[inline] + unsafe fn extract_unchecked(&self, i: usize) -> Self::Element { + self.vector.extract_unchecked(i).into() + } + + #[inline] + fn replace(&mut self, i: usize, val: Self::Element) { + self.vector.replace(i, val.vector) + } + + #[inline] + unsafe fn replace_unchecked(&mut self, i: usize, val: Self::Element) { + self.vector.replace_unchecked(i, val.vector) + } + + #[inline] + fn select(self, cond: Self::SimdBool, other: Self) -> Self { + self.vector.select(cond, other.vector).into() + } +} From 1252fb00a053e761bf2f22f21941dfa2bde96f73 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 14:05:51 +0200 Subject: [PATCH 02/35] Added scale.rs --- src/geometry/scale.rs | 363 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100755 src/geometry/scale.rs diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs new file mode 100755 index 00000000..48656f9c --- /dev/null +++ b/src/geometry/scale.rs @@ -0,0 +1,363 @@ +use approx::{AbsDiffEq, RelativeEq, UlpsEq}; +use num::{One, Zero}; +use std::fmt; +use std::hash; +#[cfg(feature = "abomonation-serialize")] +use std::io::{Result as IOResult, Write}; + +#[cfg(feature = "serde-serialize-no-std")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[cfg(feature = "abomonation-serialize")] +use abomonation::Abomonation; + +use simba::scalar::{ClosedAdd, ClosedNeg, ClosedSub}; + +use crate::base::allocator::Allocator; +use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; +use crate::base::storage::Owned; +use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar}; + +use crate::geometry::Point; + +/// A translation. +#[repr(C)] +pub struct Translation { + /// The translation coordinates, i.e., how much is added to a point's coordinates when it is + /// translated. + pub vector: SVector, +} + +impl fmt::Debug for Translation { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + self.vector.as_slice().fmt(formatter) + } +} + +impl hash::Hash for Translation +where + Owned>: hash::Hash, +{ + fn hash(&self, state: &mut H) { + self.vector.hash(state) + } +} + +impl Copy for Translation {} + +impl Clone for Translation +where + Owned>: Clone, +{ + #[inline] + fn clone(&self) -> Self { + Translation::from(self.vector.clone()) + } +} + +#[cfg(feature = "bytemuck")] +unsafe impl bytemuck::Zeroable for Translation +where + T: Scalar + bytemuck::Zeroable, + SVector: bytemuck::Zeroable, +{ +} + +#[cfg(feature = "bytemuck")] +unsafe impl bytemuck::Pod for Translation +where + T: Scalar + bytemuck::Pod, + SVector: bytemuck::Pod, +{ +} + +#[cfg(feature = "abomonation-serialize")] +impl Abomonation for Translation +where + T: Scalar, + SVector: Abomonation, +{ + unsafe fn entomb(&self, writer: &mut W) -> IOResult<()> { + self.vector.entomb(writer) + } + + fn extent(&self) -> usize { + self.vector.extent() + } + + unsafe fn exhume<'a, 'b>(&'a mut self, bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { + self.vector.exhume(bytes) + } +} + +#[cfg(feature = "serde-serialize-no-std")] +impl Serialize for Translation +where + Owned>: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.vector.serialize(serializer) + } +} + +#[cfg(feature = "serde-serialize-no-std")] +impl<'a, T: Scalar, const D: usize> Deserialize<'a> for Translation +where + Owned>: Deserialize<'a>, +{ + fn deserialize(deserializer: Des) -> Result + where + Des: Deserializer<'a>, + { + let matrix = SVector::::deserialize(deserializer)?; + + Ok(Translation::from(matrix)) + } +} + +#[cfg(feature = "rkyv-serialize-no-std")] +mod rkyv_impl { + use super::Translation; + use crate::base::SVector; + use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; + + impl Archive for Translation { + type Archived = Translation; + type Resolver = as Archive>::Resolver; + + fn resolve( + &self, + pos: usize, + resolver: Self::Resolver, + out: &mut core::mem::MaybeUninit, + ) { + self.vector.resolve( + pos + offset_of!(Self::Archived, vector), + resolver, + project_struct!(out: Self::Archived => vector), + ); + } + } + + impl, S: Fallible + ?Sized, const D: usize> Serialize for Translation { + fn serialize(&self, serializer: &mut S) -> Result { + self.vector.serialize(serializer) + } + } + + impl Deserialize, _D> + for Translation + where + T::Archived: Deserialize, + { + fn deserialize(&self, deserializer: &mut _D) -> Result, _D::Error> { + Ok(Translation { + vector: self.vector.deserialize(deserializer)?, + }) + } + } +} + +impl Translation { + /// Creates a new translation from the given vector. + #[inline] + #[deprecated(note = "Use `::from` instead.")] + pub fn from_vector(vector: SVector) -> Translation { + Translation { vector } + } + + /// Inverts `self`. + /// + /// # Example + /// ``` + /// # use nalgebra::{Translation2, Translation3}; + /// let t = Translation3::new(1.0, 2.0, 3.0); + /// assert_eq!(t * t.inverse(), Translation3::identity()); + /// assert_eq!(t.inverse() * t, Translation3::identity()); + /// + /// // Work in all dimensions. + /// let t = Translation2::new(1.0, 2.0); + /// assert_eq!(t * t.inverse(), Translation2::identity()); + /// assert_eq!(t.inverse() * t, Translation2::identity()); + /// ``` + #[inline] + #[must_use = "Did you mean to use inverse_mut()?"] + pub fn inverse(&self) -> Translation + where + T: ClosedNeg, + { + Translation::from(-&self.vector) + } + + /// Converts this translation into its equivalent homogeneous transformation matrix. + /// + /// # Example + /// ``` + /// # use nalgebra::{Translation2, Translation3, Matrix3, Matrix4}; + /// let t = Translation3::new(10.0, 20.0, 30.0); + /// let expected = Matrix4::new(1.0, 0.0, 0.0, 10.0, + /// 0.0, 1.0, 0.0, 20.0, + /// 0.0, 0.0, 1.0, 30.0, + /// 0.0, 0.0, 0.0, 1.0); + /// assert_eq!(t.to_homogeneous(), expected); + /// + /// let t = Translation2::new(10.0, 20.0); + /// let expected = Matrix3::new(1.0, 0.0, 10.0, + /// 0.0, 1.0, 20.0, + /// 0.0, 0.0, 1.0); + /// assert_eq!(t.to_homogeneous(), expected); + /// ``` + #[inline] + #[must_use] + pub fn to_homogeneous(&self) -> OMatrix, U1>, DimNameSum, U1>> + where + T: Zero + One, + Const: DimNameAdd, + DefaultAllocator: Allocator, U1>, DimNameSum, U1>>, + { + let mut res = OMatrix::, U1>, DimNameSum, U1>>::identity(); + res.fixed_slice_mut::(0, D).copy_from(&self.vector); + + res + } + + /// Inverts `self` in-place. + /// + /// # Example + /// ``` + /// # use nalgebra::{Translation2, Translation3}; + /// let t = Translation3::new(1.0, 2.0, 3.0); + /// let mut inv_t = Translation3::new(1.0, 2.0, 3.0); + /// inv_t.inverse_mut(); + /// assert_eq!(t * inv_t, Translation3::identity()); + /// assert_eq!(inv_t * t, Translation3::identity()); + /// + /// // Work in all dimensions. + /// let t = Translation2::new(1.0, 2.0); + /// let mut inv_t = Translation2::new(1.0, 2.0); + /// inv_t.inverse_mut(); + /// assert_eq!(t * inv_t, Translation2::identity()); + /// assert_eq!(inv_t * t, Translation2::identity()); + /// ``` + #[inline] + pub fn inverse_mut(&mut self) + where + T: ClosedNeg, + { + self.vector.neg_mut() + } +} + +impl Translation { + /// Translate the given point. + /// + /// This is the same as the multiplication `self * pt`. + /// + /// # Example + /// ``` + /// # use nalgebra::{Translation3, Point3}; + /// let t = Translation3::new(1.0, 2.0, 3.0); + /// let transformed_point = t.transform_point(&Point3::new(4.0, 5.0, 6.0)); + /// assert_eq!(transformed_point, Point3::new(5.0, 7.0, 9.0)); + #[inline] + #[must_use] + pub fn transform_point(&self, pt: &Point) -> Point { + pt + &self.vector + } +} + +impl Translation { + /// Translate the given point by the inverse of this translation. + /// + /// # Example + /// ``` + /// # use nalgebra::{Translation3, Point3}; + /// let t = Translation3::new(1.0, 2.0, 3.0); + /// let transformed_point = t.inverse_transform_point(&Point3::new(4.0, 5.0, 6.0)); + /// assert_eq!(transformed_point, Point3::new(3.0, 3.0, 3.0)); + #[inline] + #[must_use] + pub fn inverse_transform_point(&self, pt: &Point) -> Point { + pt - &self.vector + } +} + +impl Eq for Translation {} + +impl PartialEq for Translation { + #[inline] + fn eq(&self, right: &Translation) -> bool { + self.vector == right.vector + } +} + +impl AbsDiffEq for Translation +where + T::Epsilon: Clone, +{ + type Epsilon = T::Epsilon; + + #[inline] + fn default_epsilon() -> Self::Epsilon { + T::default_epsilon() + } + + #[inline] + fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool { + self.vector.abs_diff_eq(&other.vector, epsilon) + } +} + +impl RelativeEq for Translation +where + T::Epsilon: Clone, +{ + #[inline] + fn default_max_relative() -> Self::Epsilon { + T::default_max_relative() + } + + #[inline] + fn relative_eq( + &self, + other: &Self, + epsilon: Self::Epsilon, + max_relative: Self::Epsilon, + ) -> bool { + self.vector + .relative_eq(&other.vector, epsilon, max_relative) + } +} + +impl UlpsEq for Translation +where + T::Epsilon: Clone, +{ + #[inline] + fn default_max_ulps() -> u32 { + T::default_max_ulps() + } + + #[inline] + fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { + self.vector.ulps_eq(&other.vector, epsilon, max_ulps) + } +} + +/* + * + * Display + * + */ +impl fmt::Display for Translation { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let precision = f.precision().unwrap_or(3); + + writeln!(f, "Translation {{")?; + write!(f, "{:.*}", precision, self.vector)?; + writeln!(f, "}}") + } +} From 9c506b18e1005c0115acfb1ac2f1e3db1200a8bd Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 14:21:26 +0200 Subject: [PATCH 03/35] Renamed all instances of Translation to Scale --- src/geometry/mod.rs | 10 +++ src/geometry/scale.rs | 139 ++++++++++++++-------------- src/geometry/scale_alias.rs | 26 +++--- src/geometry/scale_construction.rs | 54 +++++------ src/geometry/scale_conversion.rs | 140 +++++++---------------------- src/geometry/scale_coordinates.rs | 12 +-- src/geometry/scale_ops.rs | 74 +++++++-------- 7 files changed, 195 insertions(+), 260 deletions(-) diff --git a/src/geometry/mod.rs b/src/geometry/mod.rs index 37ca57f9..f79311e3 100644 --- a/src/geometry/mod.rs +++ b/src/geometry/mod.rs @@ -48,6 +48,13 @@ mod translation_coordinates; mod translation_ops; mod translation_simba; +mod scale; +mod scale_alias; +mod scale_construction; +mod scale_conversion; +mod scale_coordinates; +mod scale_ops; + mod isometry; mod isometry_alias; mod isometry_construction; @@ -95,6 +102,9 @@ pub use self::unit_complex::*; pub use self::translation::*; pub use self::translation_alias::*; +pub use self::scale::*; +pub use self::scale_alias::*; + pub use self::isometry::*; pub use self::isometry_alias::*; diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 48656f9c..aa83c63c 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -20,21 +20,21 @@ use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar}; use crate::geometry::Point; -/// A translation. +/// A scale which supports non-uniform scaling. #[repr(C)] -pub struct Translation { - /// The translation coordinates, i.e., how much is added to a point's coordinates when it is - /// translated. +pub struct Scale { + /// The scale coordinates, i.e., how much is multiplied to a point's coordinates when it is + /// scaled. pub vector: SVector, } -impl fmt::Debug for Translation { +impl fmt::Debug for Scale { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { self.vector.as_slice().fmt(formatter) } } -impl hash::Hash for Translation +impl hash::Hash for Scale where Owned>: hash::Hash, { @@ -43,20 +43,20 @@ where } } -impl Copy for Translation {} +impl Copy for Scale {} -impl Clone for Translation +impl Clone for Scale where Owned>: Clone, { #[inline] fn clone(&self) -> Self { - Translation::from(self.vector.clone()) + Scale::from(self.vector.clone()) } } #[cfg(feature = "bytemuck")] -unsafe impl bytemuck::Zeroable for Translation +unsafe impl bytemuck::Zeroable for Scale where T: Scalar + bytemuck::Zeroable, SVector: bytemuck::Zeroable, @@ -64,7 +64,7 @@ where } #[cfg(feature = "bytemuck")] -unsafe impl bytemuck::Pod for Translation +unsafe impl bytemuck::Pod for Scale where T: Scalar + bytemuck::Pod, SVector: bytemuck::Pod, @@ -72,7 +72,7 @@ where } #[cfg(feature = "abomonation-serialize")] -impl Abomonation for Translation +impl Abomonation for Scale where T: Scalar, SVector: Abomonation, @@ -91,7 +91,7 @@ where } #[cfg(feature = "serde-serialize-no-std")] -impl Serialize for Translation +impl Serialize for Scale where Owned>: Serialize, { @@ -104,7 +104,7 @@ where } #[cfg(feature = "serde-serialize-no-std")] -impl<'a, T: Scalar, const D: usize> Deserialize<'a> for Translation +impl<'a, T: Scalar, const D: usize> Deserialize<'a> for Scale where Owned>: Deserialize<'a>, { @@ -114,18 +114,18 @@ where { let matrix = SVector::::deserialize(deserializer)?; - Ok(Translation::from(matrix)) + Ok(Scale::from(matrix)) } } #[cfg(feature = "rkyv-serialize-no-std")] mod rkyv_impl { - use super::Translation; + use super::Scale; use crate::base::SVector; use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; - impl Archive for Translation { - type Archived = Translation; + impl Archive for Scale { + type Archived = Scale; type Resolver = as Archive>::Resolver; fn resolve( @@ -142,69 +142,69 @@ mod rkyv_impl { } } - impl, S: Fallible + ?Sized, const D: usize> Serialize for Translation { + impl, S: Fallible + ?Sized, const D: usize> Serialize for Scale { fn serialize(&self, serializer: &mut S) -> Result { self.vector.serialize(serializer) } } - impl Deserialize, _D> - for Translation + impl Deserialize, _D> + for Scale where T::Archived: Deserialize, { - fn deserialize(&self, deserializer: &mut _D) -> Result, _D::Error> { - Ok(Translation { + fn deserialize(&self, deserializer: &mut _D) -> Result, _D::Error> { + Ok(Scale { vector: self.vector.deserialize(deserializer)?, }) } } } -impl Translation { - /// Creates a new translation from the given vector. +impl Scale { + /// Creates a new Scale from the given vector. #[inline] #[deprecated(note = "Use `::from` instead.")] - pub fn from_vector(vector: SVector) -> Translation { - Translation { vector } + pub fn from_vector(vector: SVector) -> Scale { + Scale { vector } } /// Inverts `self`. /// /// # Example /// ``` - /// # use nalgebra::{Translation2, Translation3}; - /// let t = Translation3::new(1.0, 2.0, 3.0); - /// assert_eq!(t * t.inverse(), Translation3::identity()); - /// assert_eq!(t.inverse() * t, Translation3::identity()); + /// # use nalgebra::{Scale2, Scale3}; + /// let t = Scale3::new(1.0, 2.0, 3.0); + /// assert_eq!(t * t.inverse(), Scale3::identity()); + /// assert_eq!(t.inverse() * t, Scale3::identity()); /// /// // Work in all dimensions. - /// let t = Translation2::new(1.0, 2.0); - /// assert_eq!(t * t.inverse(), Translation2::identity()); - /// assert_eq!(t.inverse() * t, Translation2::identity()); + /// let t = Scale2::new(1.0, 2.0); + /// assert_eq!(t * t.inverse(), Scale2::identity()); + /// assert_eq!(t.inverse() * t, Scale2::identity()); /// ``` #[inline] #[must_use = "Did you mean to use inverse_mut()?"] - pub fn inverse(&self) -> Translation + pub fn inverse(&self) -> Scale where T: ClosedNeg, { - Translation::from(-&self.vector) + todo!(); } - /// Converts this translation into its equivalent homogeneous transformation matrix. + /// Converts this Scale into its equivalent homogeneous transformation matrix. /// /// # Example /// ``` - /// # use nalgebra::{Translation2, Translation3, Matrix3, Matrix4}; - /// let t = Translation3::new(10.0, 20.0, 30.0); + /// # use nalgebra::{Scale2, Scale3, Matrix3, Matrix4}; + /// let t = Scale3::new(10.0, 20.0, 30.0); /// let expected = Matrix4::new(1.0, 0.0, 0.0, 10.0, /// 0.0, 1.0, 0.0, 20.0, /// 0.0, 0.0, 1.0, 30.0, /// 0.0, 0.0, 0.0, 1.0); /// assert_eq!(t.to_homogeneous(), expected); /// - /// let t = Translation2::new(10.0, 20.0); + /// let t = Scale2::new(10.0, 20.0); /// let expected = Matrix3::new(1.0, 0.0, 10.0, /// 0.0, 1.0, 20.0, /// 0.0, 0.0, 1.0); @@ -218,83 +218,80 @@ impl Translation { Const: DimNameAdd, DefaultAllocator: Allocator, U1>, DimNameSum, U1>>, { - let mut res = OMatrix::, U1>, DimNameSum, U1>>::identity(); - res.fixed_slice_mut::(0, D).copy_from(&self.vector); - - res + todo!(); } /// Inverts `self` in-place. /// /// # Example /// ``` - /// # use nalgebra::{Translation2, Translation3}; - /// let t = Translation3::new(1.0, 2.0, 3.0); - /// let mut inv_t = Translation3::new(1.0, 2.0, 3.0); + /// # use nalgebra::{Scale2, Scale3}; + /// let t = Scale3::new(1.0, 2.0, 3.0); + /// let mut inv_t = Scale3::new(1.0, 2.0, 3.0); /// inv_t.inverse_mut(); - /// assert_eq!(t * inv_t, Translation3::identity()); - /// assert_eq!(inv_t * t, Translation3::identity()); + /// assert_eq!(t * inv_t, Scale3::identity()); + /// assert_eq!(inv_t * t, Scale3::identity()); /// /// // Work in all dimensions. - /// let t = Translation2::new(1.0, 2.0); - /// let mut inv_t = Translation2::new(1.0, 2.0); + /// let t = Scale2::new(1.0, 2.0); + /// let mut inv_t = Scale2::new(1.0, 2.0); /// inv_t.inverse_mut(); - /// assert_eq!(t * inv_t, Translation2::identity()); - /// assert_eq!(inv_t * t, Translation2::identity()); + /// assert_eq!(t * inv_t, Scale2::identity()); + /// assert_eq!(inv_t * t, Scale2::identity()); /// ``` #[inline] pub fn inverse_mut(&mut self) where T: ClosedNeg, { - self.vector.neg_mut() + todo!(); } } -impl Translation { +impl Scale { /// Translate the given point. /// /// This is the same as the multiplication `self * pt`. /// /// # Example /// ``` - /// # use nalgebra::{Translation3, Point3}; - /// let t = Translation3::new(1.0, 2.0, 3.0); + /// # use nalgebra::{Scale3, Point3}; + /// let t = Scale3::new(1.0, 2.0, 3.0); /// let transformed_point = t.transform_point(&Point3::new(4.0, 5.0, 6.0)); /// assert_eq!(transformed_point, Point3::new(5.0, 7.0, 9.0)); #[inline] #[must_use] pub fn transform_point(&self, pt: &Point) -> Point { - pt + &self.vector + todo!(); } } -impl Translation { - /// Translate the given point by the inverse of this translation. +impl Scale { + /// Translate the given point by the inverse of this Scale. /// /// # Example /// ``` - /// # use nalgebra::{Translation3, Point3}; - /// let t = Translation3::new(1.0, 2.0, 3.0); + /// # use nalgebra::{Scale3, Point3}; + /// let t = Scale3::new(1.0, 2.0, 3.0); /// let transformed_point = t.inverse_transform_point(&Point3::new(4.0, 5.0, 6.0)); /// assert_eq!(transformed_point, Point3::new(3.0, 3.0, 3.0)); #[inline] #[must_use] pub fn inverse_transform_point(&self, pt: &Point) -> Point { - pt - &self.vector + todo!(); } } -impl Eq for Translation {} +impl Eq for Scale {} -impl PartialEq for Translation { +impl PartialEq for Scale { #[inline] - fn eq(&self, right: &Translation) -> bool { + fn eq(&self, right: &Scale) -> bool { self.vector == right.vector } } -impl AbsDiffEq for Translation +impl AbsDiffEq for Scale where T::Epsilon: Clone, { @@ -311,7 +308,7 @@ where } } -impl RelativeEq for Translation +impl RelativeEq for Scale where T::Epsilon: Clone, { @@ -332,7 +329,7 @@ where } } -impl UlpsEq for Translation +impl UlpsEq for Scale where T::Epsilon: Clone, { @@ -352,11 +349,11 @@ where * Display * */ -impl fmt::Display for Translation { +impl fmt::Display for Scale { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let precision = f.precision().unwrap_or(3); - writeln!(f, "Translation {{")?; + writeln!(f, "Scale {{")?; write!(f, "{:.*}", precision, self.vector)?; writeln!(f, "}}") } diff --git a/src/geometry/scale_alias.rs b/src/geometry/scale_alias.rs index 06dc0794..87932442 100644 --- a/src/geometry/scale_alias.rs +++ b/src/geometry/scale_alias.rs @@ -1,19 +1,19 @@ -use crate::geometry::Translation; +use crate::geometry::Scale; -/// A 1-dimensional translation. -pub type Translation1 = Translation; +/// A 1-dimensional scale. +pub type Scale1 = Scale; -/// A 2-dimensional translation. -pub type Translation2 = Translation; +/// A 2-dimensional scale. +pub type Scale2 = Scale; -/// A 3-dimensional translation. -pub type Translation3 = Translation; +/// A 3-dimensional scale. +pub type Scale3 = Scale; -/// A 4-dimensional translation. -pub type Translation4 = Translation; +/// A 4-dimensional scale. +pub type Scale4 = Scale; -/// A 5-dimensional translation. -pub type Translation5 = Translation; +/// A 5-dimensional scale. +pub type Scale5 = Scale; -/// A 6-dimensional translation. -pub type Translation6 = Translation; +/// A 6-dimensional scale. +pub type Scale6 = Scale; diff --git a/src/geometry/scale_construction.rs b/src/geometry/scale_construction.rs index 5371b648..a3d9b151 100644 --- a/src/geometry/scale_construction.rs +++ b/src/geometry/scale_construction.rs @@ -13,49 +13,49 @@ use rand::{ use simba::scalar::{ClosedAdd, SupersetOf}; use crate::base::{SVector, Scalar}; -use crate::geometry::Translation; +use crate::geometry::Scale; -impl Translation { - /// Creates a new identity translation. +impl Scale { + /// Creates a new identity scale. /// /// # Example /// ``` - /// # use nalgebra::{Point2, Point3, Translation2, Translation3}; - /// let t = Translation2::identity(); + /// # use nalgebra::{Point2, Point3, Scale2, Scale3}; + /// let t = Scale2::identity(); /// let p = Point2::new(1.0, 2.0); /// assert_eq!(t * p, p); /// /// // Works in all dimensions. - /// let t = Translation3::identity(); + /// let t = Scale3::identity(); /// let p = Point3::new(1.0, 2.0, 3.0); /// assert_eq!(t * p, p); /// ``` #[inline] - pub fn identity() -> Translation + pub fn identity() -> Scale where T: Zero, { - Self::from(SVector::::from_element(T::zero())) + todo!(); } /// Cast the components of `self` to another type. /// /// # Example /// ``` - /// # use nalgebra::Translation2; - /// let tra = Translation2::new(1.0f64, 2.0); + /// # use nalgebra::Scale2; + /// let tra = Scale2::new(1.0f64, 2.0); /// let tra2 = tra.cast::(); - /// assert_eq!(tra2, Translation2::new(1.0f32, 2.0)); + /// assert_eq!(tra2, Scale2::new(1.0f32, 2.0)); /// ``` - pub fn cast(self) -> Translation + pub fn cast(self) -> Scale where - Translation: SupersetOf, + Scale: SupersetOf, { crate::convert(self) } } -impl One for Translation { +impl One for Scale { #[inline] fn one() -> Self { Self::identity() @@ -63,19 +63,19 @@ impl One for Translation { } #[cfg(feature = "rand-no-std")] -impl Distribution> for Standard +impl Distribution> for Standard where Standard: Distribution, { /// Generate an arbitrary random variate for testing purposes. #[inline] - fn sample(&self, rng: &mut G) -> Translation { - Translation::from(rng.gen::>()) + fn sample(&self, rng: &mut G) -> Scale { + Scale::from(rng.gen::>()) } } #[cfg(feature = "arbitrary")] -impl Arbitrary for Translation +impl Arbitrary for Scale where Owned>: Send, { @@ -88,14 +88,14 @@ where /* * - * Small translation construction from components. + * Small Scale construction from components. * */ macro_rules! componentwise_constructors_impl( ($($doc: expr; $D: expr, $($args: ident:$irow: expr),*);* $(;)*) => {$( - impl Translation + impl Scale { - #[doc = "Initializes this translation from its components."] + #[doc = "Initializes this Scale from its components."] #[doc = "# Example\n```"] #[doc = $doc] #[doc = "```"] @@ -108,16 +108,16 @@ macro_rules! componentwise_constructors_impl( ); componentwise_constructors_impl!( - "# use nalgebra::Translation1;\nlet t = Translation1::new(1.0);\nassert!(t.vector.x == 1.0);"; + "# use nalgebra::Scale1;\nlet t = Scale1::new(1.0);\nassert!(t.vector.x == 1.0);"; 1, x:0; - "# use nalgebra::Translation2;\nlet t = Translation2::new(1.0, 2.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0);"; + "# use nalgebra::Scale2;\nlet t = Scale2::new(1.0, 2.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0);"; 2, x:0, y:1; - "# use nalgebra::Translation3;\nlet t = Translation3::new(1.0, 2.0, 3.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0);"; + "# use nalgebra::Scale3;\nlet t = Scale3::new(1.0, 2.0, 3.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0);"; 3, x:0, y:1, z:2; - "# use nalgebra::Translation4;\nlet t = Translation4::new(1.0, 2.0, 3.0, 4.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0);"; + "# use nalgebra::Scale4;\nlet t = Scale4::new(1.0, 2.0, 3.0, 4.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0);"; 4, x:0, y:1, z:2, w:3; - "# use nalgebra::Translation5;\nlet t = Translation5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0);"; + "# use nalgebra::Scale5;\nlet t = Scale5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0);"; 5, x:0, y:1, z:2, w:3, a:4; - "# use nalgebra::Translation6;\nlet t = Translation6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0 && t.vector.b == 6.0);"; + "# use nalgebra::Scale6;\nlet t = Scale6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0 && t.vector.b == 6.0);"; 6, x:0, y:1, z:2, w:3, a:4, b:5; ); diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index 70000efb..ed8d4c7a 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -8,8 +8,7 @@ use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::{Const, DefaultAllocator, DimName, OMatrix, OVector, SVector, Scalar}; use crate::geometry::{ - AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, - Translation3, UnitDualQuaternion, UnitQuaternion, + SuperTCategoryOf, TAffine, Transform, Scale }; use crate::Point; @@ -17,106 +16,35 @@ use crate::Point; * This file provides the following conversions: * ============================================= * - * Translation -> Translation - * Translation -> Isometry - * Translation3 -> UnitDualQuaternion - * Translation -> Similarity - * Translation -> Transform - * Translation -> Matrix (homogeneous) + * Scale -> Scale + * Scale -> Transform + * Scale -> Matrix (homogeneous) */ -impl SubsetOf> for Translation +impl SubsetOf> for Scale where T1: Scalar, T2: Scalar + SupersetOf, { #[inline] - fn to_superset(&self) -> Translation { - Translation::from(self.vector.to_superset()) + fn to_superset(&self) -> Scale { + Scale::from(self.vector.to_superset()) } #[inline] - fn is_in_subset(rot: &Translation) -> bool { + fn is_in_subset(rot: &Scale) -> bool { crate::is_convertible::<_, SVector>(&rot.vector) } #[inline] - fn from_superset_unchecked(rot: &Translation) -> Self { - Translation { + fn from_superset_unchecked(rot: &Scale) -> Self { + Scale { vector: rot.vector.to_subset_unchecked(), } } } -impl SubsetOf> for Translation -where - T1: RealField, - T2: RealField + SupersetOf, - R: AbstractRotation, -{ - #[inline] - fn to_superset(&self) -> Isometry { - Isometry::from_parts(self.to_superset(), R::identity()) - } - - #[inline] - fn is_in_subset(iso: &Isometry) -> bool { - iso.rotation == R::identity() - } - - #[inline] - fn from_superset_unchecked(iso: &Isometry) -> Self { - Self::from_superset_unchecked(&iso.translation) - } -} - -impl SubsetOf> for Translation3 -where - T1: RealField, - T2: RealField + SupersetOf, -{ - #[inline] - fn to_superset(&self) -> UnitDualQuaternion { - let dq = UnitDualQuaternion::::from_parts(self.clone(), UnitQuaternion::identity()); - dq.to_superset() - } - - #[inline] - fn is_in_subset(dq: &UnitDualQuaternion) -> bool { - crate::is_convertible::<_, Translation>(&dq.translation()) - && dq.rotation() == UnitQuaternion::identity() - } - - #[inline] - fn from_superset_unchecked(dq: &UnitDualQuaternion) -> Self { - let dq: UnitDualQuaternion = crate::convert_ref_unchecked(dq); - dq.translation() - } -} - -impl SubsetOf> for Translation -where - T1: RealField, - T2: RealField + SupersetOf, - R: AbstractRotation, -{ - #[inline] - fn to_superset(&self) -> Similarity { - Similarity::from_parts(self.to_superset(), R::identity(), T2::one()) - } - - #[inline] - fn is_in_subset(sim: &Similarity) -> bool { - sim.isometry.rotation == R::identity() && sim.scaling() == T2::one() - } - - #[inline] - fn from_superset_unchecked(sim: &Similarity) -> Self { - Self::from_superset_unchecked(&sim.isometry.translation) - } -} - -impl SubsetOf> for Translation +impl SubsetOf> for Scale where T1: RealField, T2: RealField + SupersetOf, @@ -142,7 +70,7 @@ where } impl - SubsetOf, U1>, DimNameSum, U1>>> for Translation + SubsetOf, U1>, DimNameSum, U1>>> for Scale where T1: RealField, T2: RealField + SupersetOf, @@ -180,7 +108,7 @@ where } } -impl From> +impl From> for OMatrix, U1>, DimNameSum, U1>> where Const: DimNameAdd, @@ -188,49 +116,49 @@ where Allocator, U1>, DimNameSum, U1>> + Allocator>, { #[inline] - fn from(t: Translation) -> Self { + fn from(t: Scale) -> Self { t.to_homogeneous() } } -impl From>> for Translation { +impl From>> for Scale { #[inline] fn from(vector: OVector>) -> Self { - Translation { vector } + Scale { vector } } } -impl From<[T; D]> for Translation { +impl From<[T; D]> for Scale { #[inline] fn from(coords: [T; D]) -> Self { - Translation { + Scale { vector: coords.into(), } } } -impl From> for Translation { +impl From> for Scale { #[inline] fn from(pt: Point) -> Self { - Translation { vector: pt.coords } + Scale { vector: pt.coords } } } -impl From> for [T; D] { +impl From> for [T; D] { #[inline] - fn from(t: Translation) -> Self { + fn from(t: Scale) -> Self { t.vector.into() } } -impl From<[Translation; 2]> - for Translation +impl From<[Scale; 2]> + for Scale where T: From<[::Element; 2]>, T::Element: Scalar, { #[inline] - fn from(arr: [Translation; 2]) -> Self { + fn from(arr: [Scale; 2]) -> Self { Self::from(OVector::from([ arr[0].vector.clone(), arr[1].vector.clone(), @@ -238,14 +166,14 @@ where } } -impl From<[Translation; 4]> - for Translation +impl From<[Scale; 4]> + for Scale where T: From<[::Element; 4]>, T::Element: Scalar, { #[inline] - fn from(arr: [Translation; 4]) -> Self { + fn from(arr: [Scale; 4]) -> Self { Self::from(OVector::from([ arr[0].vector.clone(), arr[1].vector.clone(), @@ -255,14 +183,14 @@ where } } -impl From<[Translation; 8]> - for Translation +impl From<[Scale; 8]> + for Scale where T: From<[::Element; 8]>, T::Element: Scalar, { #[inline] - fn from(arr: [Translation; 8]) -> Self { + fn from(arr: [Scale; 8]) -> Self { Self::from(OVector::from([ arr[0].vector.clone(), arr[1].vector.clone(), @@ -276,14 +204,14 @@ where } } -impl From<[Translation; 16]> - for Translation +impl From<[Scale; 16]> + for Scale where T: From<[::Element; 16]>, T::Element: Scalar, { #[inline] - fn from(arr: [Translation; 16]) -> Self { + fn from(arr: [Scale; 16]) -> Self { Self::from(OVector::from([ arr[0].vector.clone(), arr[1].vector.clone(), diff --git a/src/geometry/scale_coordinates.rs b/src/geometry/scale_coordinates.rs index 80267e06..2f3fb5bc 100644 --- a/src/geometry/scale_coordinates.rs +++ b/src/geometry/scale_coordinates.rs @@ -3,29 +3,29 @@ use std::ops::{Deref, DerefMut}; use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB}; use crate::base::Scalar; -use crate::geometry::Translation; +use crate::geometry::Scale; /* * - * Give coordinates to Translation{1 .. 6} + * Give coordinates to Scale{1 .. 6} * */ macro_rules! deref_impl( ($D: expr, $Target: ident $(, $comps: ident)*) => { - impl Deref for Translation { + impl Deref for Scale { type Target = $Target; #[inline] fn deref(&self) -> &Self::Target { - unsafe { &*(self as *const Translation as *const Self::Target) } + unsafe { &*(self as *const Scale as *const Self::Target) } } } - impl DerefMut for Translation { + impl DerefMut for Scale { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *(self as *mut Translation as *mut Self::Target) } + unsafe { &mut *(self as *mut Scale as *mut Self::Target) } } } } diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs index 8851183a..3bb04c83 100644 --- a/src/geometry/scale_ops.rs +++ b/src/geometry/scale_ops.rs @@ -6,114 +6,114 @@ use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstr use crate::base::dimension::U1; use crate::base::{Const, Scalar}; -use crate::geometry::{Point, Translation}; +use crate::geometry::{Point, Scale}; -// Translation × Translation +// Scale × Scale add_sub_impl!(Mul, mul, ClosedAdd; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Translation, right: &'b Translation, Output = Translation; - #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + &right.vector) }; + self: &'a Scale, right: &'b Scale, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'a, 'b); add_sub_impl!(Mul, mul, ClosedAdd; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Translation, right: Translation, Output = Translation; - #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + right.vector) }; + self: &'a Scale, right: Scale, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'a); add_sub_impl!(Mul, mul, ClosedAdd; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Translation, right: &'b Translation, Output = Translation; - #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + &right.vector) }; + self: Scale, right: &'b Scale, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'b); add_sub_impl!(Mul, mul, ClosedAdd; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Translation, right: Translation, Output = Translation; - #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + right.vector) }; ); + self: Scale, right: Scale, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; ); -// Translation ÷ Translation +// Scale ÷ Scale // TODO: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method? add_sub_impl!(Div, div, ClosedSub; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Translation, right: &'b Translation, Output = Translation; - #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - &right.vector) }; + self: &'a Scale, right: &'b Scale, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'a, 'b); add_sub_impl!(Div, div, ClosedSub; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Translation, right: Translation, Output = Translation; - #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - right.vector) }; + self: &'a Scale, right: Scale, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'a); add_sub_impl!(Div, div, ClosedSub; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Translation, right: &'b Translation, Output = Translation; - #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - &right.vector) }; + self: Scale, right: &'b Scale, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'b); add_sub_impl!(Div, div, ClosedSub; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Translation, right: Translation, Output = Translation; - #[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - right.vector) }; ); + self: Scale, right: Scale, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; ); -// Translation × Point +// Scale × Point // TODO: we don't handle properly non-zero origins here. Do we want this to be the intended // behavior? add_sub_impl!(Mul, mul, ClosedAdd; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Translation, right: &'b Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector }; + self: &'a Scale, right: &'b Point, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'a, 'b); add_sub_impl!(Mul, mul, ClosedAdd; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Translation, right: Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector }; + self: &'a Scale, right: Point, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'a); add_sub_impl!(Mul, mul, ClosedAdd; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Translation, right: &'b Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; + self: Scale, right: &'b Point, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; 'b); add_sub_impl!(Mul, mul, ClosedAdd; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Translation, right: Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; ); + self: Scale, right: Point, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; ); -// Translation *= Translation +// Scale *= Scale add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; const D; - self: Translation, right: &'b Translation; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector += &right.vector }; + self: Scale, right: &'b Scale; + #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; 'b); add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; const D; - self: Translation, right: Translation; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector += right.vector }; ); + self: Scale, right: Scale; + #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; ); add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; const D; - self: Translation, right: &'b Translation; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector -= &right.vector }; + self: Scale, right: &'b Scale; + #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; 'b); add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; const D; - self: Translation, right: Translation; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector -= right.vector }; ); + self: Scale, right: Scale; + #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; ); From bfb4aceede39bc807b3b2cc969faf64511787b74 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 14:31:20 +0200 Subject: [PATCH 04/35] Updated operator overloads + fixed scale_construction --- src/geometry/scale_construction.rs | 4 +-- src/geometry/scale_ops.rs | 52 +++++++++++++++--------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/geometry/scale_construction.rs b/src/geometry/scale_construction.rs index a3d9b151..1f2acf03 100644 --- a/src/geometry/scale_construction.rs +++ b/src/geometry/scale_construction.rs @@ -10,7 +10,7 @@ use rand::{ Rng, }; -use simba::scalar::{ClosedAdd, SupersetOf}; +use simba::scalar::{ClosedMul, SupersetOf}; use crate::base::{SVector, Scalar}; use crate::geometry::Scale; @@ -55,7 +55,7 @@ impl Scale { } } -impl One for Scale { +impl One for Scale { #[inline] fn one() -> Self { Self::identity() diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs index 3bb04c83..80927557 100644 --- a/src/geometry/scale_ops.rs +++ b/src/geometry/scale_ops.rs @@ -1,6 +1,6 @@ -use std::ops::{Div, DivAssign, Mul, MulAssign}; +use std::ops::{Mul, MulAssign}; -use simba::scalar::{ClosedAdd, ClosedSub}; +use simba::scalar::{ClosedMul}; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::dimension::U1; @@ -9,36 +9,36 @@ use crate::base::{Const, Scalar}; use crate::geometry::{Point, Scale}; // Scale × Scale -add_sub_impl!(Mul, mul, ClosedAdd; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: &'b Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; + #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; 'a, 'b); -add_sub_impl!(Mul, mul, ClosedAdd; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; + #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; 'a); -add_sub_impl!(Mul, mul, ClosedAdd; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: &'b Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; + #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; 'b); -add_sub_impl!(Mul, mul, ClosedAdd; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; ); + #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; ); // Scale ÷ Scale // TODO: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method? -add_sub_impl!(Div, div, ClosedSub; +/*add_sub_impl!(Div, div, ClosedSub; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: &'b Scale, Output = Scale; @@ -63,51 +63,51 @@ add_sub_impl!(Div, div, ClosedSub; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; ); + #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; );*/ // Scale × Point // TODO: we don't handle properly non-zero origins here. Do we want this to be the intended // behavior? -add_sub_impl!(Mul, mul, ClosedAdd; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: &'b Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; + #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; 'a, 'b); -add_sub_impl!(Mul, mul, ClosedAdd; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; + #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; 'a); -add_sub_impl!(Mul, mul, ClosedAdd; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: &'b Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; + #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; 'b); -add_sub_impl!(Mul, mul, ClosedAdd; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; ); + #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; ); // Scale *= Scale -add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; +add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; const D; self: Scale, right: &'b Scale; - #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; + #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; 'b); -add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; +add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; const D; self: Scale, right: Scale; - #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; ); + #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; ); -add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; +/*add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; const D; self: Scale, right: &'b Scale; #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; @@ -116,4 +116,4 @@ add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; const D; self: Scale, right: Scale; - #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; ); + #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; );*/ From cf811abb92481fc61eaa964a31f6132eeb0ae141 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 14:47:46 +0200 Subject: [PATCH 05/35] Added identity() --- src/geometry/scale_construction.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/geometry/scale_construction.rs b/src/geometry/scale_construction.rs index 1f2acf03..cade72c2 100644 --- a/src/geometry/scale_construction.rs +++ b/src/geometry/scale_construction.rs @@ -3,7 +3,7 @@ use crate::base::storage::Owned; #[cfg(feature = "arbitrary")] use quickcheck::{Arbitrary, Gen}; -use num::{One, Zero}; +use num::{One}; #[cfg(feature = "rand-no-std")] use rand::{ distributions::{Distribution, Standard}, @@ -33,9 +33,9 @@ impl Scale { #[inline] pub fn identity() -> Scale where - T: Zero, + T: One, { - todo!(); + Scale::from(SVector::from_element(T::one())) } /// Cast the components of `self` to another type. @@ -55,7 +55,7 @@ impl Scale { } } -impl One for Scale { +impl One for Scale { #[inline] fn one() -> Self { Self::identity() From c249cc76b055b1cdc33a7fa63ee11d09460e65a6 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 15:02:50 +0200 Subject: [PATCH 06/35] Added inverse, inverse_mut inverse_transform_point and transform_point --- src/geometry/scale.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index aa83c63c..5fe36602 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -11,12 +11,12 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; -use simba::scalar::{ClosedAdd, ClosedNeg, ClosedSub}; - use crate::base::allocator::Allocator; use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::storage::Owned; use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar}; +use crate::ClosedDiv; +use crate::ClosedMul; use crate::geometry::Point; @@ -162,13 +162,6 @@ mod rkyv_impl { } impl Scale { - /// Creates a new Scale from the given vector. - #[inline] - #[deprecated(note = "Use `::from` instead.")] - pub fn from_vector(vector: SVector) -> Scale { - Scale { vector } - } - /// Inverts `self`. /// /// # Example @@ -187,9 +180,10 @@ impl Scale { #[must_use = "Did you mean to use inverse_mut()?"] pub fn inverse(&self) -> Scale where - T: ClosedNeg, + T: ClosedDiv + One, { - todo!(); + let useless: SVector = SVector::from_element(T::one()); + return useless.component_div(&self.vector).into(); } /// Converts this Scale into its equivalent homogeneous transformation matrix. @@ -242,13 +236,13 @@ impl Scale { #[inline] pub fn inverse_mut(&mut self) where - T: ClosedNeg, + T: ClosedDiv + One, { - todo!(); + self.vector = self.inverse().vector; } } -impl Scale { +impl Scale { /// Translate the given point. /// /// This is the same as the multiplication `self * pt`. @@ -262,11 +256,11 @@ impl Scale { #[inline] #[must_use] pub fn transform_point(&self, pt: &Point) -> Point { - todo!(); + return self * pt; } } -impl Scale { +impl Scale { /// Translate the given point by the inverse of this Scale. /// /// # Example @@ -278,7 +272,7 @@ impl Scale { #[inline] #[must_use] pub fn inverse_transform_point(&self, pt: &Point) -> Point { - todo!(); + return self.inverse() * pt; } } From f1f947b9248a3449c6c70d47b45797d48f1249bf Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 15:55:06 +0200 Subject: [PATCH 07/35] Added to_homogeneous --- src/geometry/scale.rs | 15 ++++++++++----- src/geometry/scale_conversion.rs | 16 +++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 5fe36602..deb0116b 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -14,8 +14,8 @@ use abomonation::Abomonation; use crate::base::allocator::Allocator; use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::storage::Owned; -use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar}; -use crate::ClosedDiv; +use crate::base::{Const, DefaultAllocator, OMatrix, OVector, SVector, Scalar}; +use crate::{ClosedAdd, ClosedDiv}; use crate::ClosedMul; use crate::geometry::Point; @@ -208,11 +208,16 @@ impl Scale { #[must_use] pub fn to_homogeneous(&self) -> OMatrix, U1>, DimNameSum, U1>> where - T: Zero + One, + T: Zero + One + ClosedAdd + Clone, Const: DimNameAdd, - DefaultAllocator: Allocator, U1>, DimNameSum, U1>>, + DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + Allocator, U1>, U1>, { - todo!(); + let mut v = OVector::, U1>>::zero(); + for i in 0..D { + v[(i, 0)] = self.vector[(i, 0)].clone(); + } + v[(D, 0)] = T::one(); + return OMatrix::, U1>, DimNameSum, U1>>::from_diagonal(&v); } /// Inverts `self` in-place. diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index ed8d4c7a..e6f8573b 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -10,7 +10,7 @@ use crate::base::{Const, DefaultAllocator, DimName, OMatrix, OVector, SVector, S use crate::geometry::{ SuperTCategoryOf, TAffine, Transform, Scale }; -use crate::Point; +use crate::{ClosedAdd, Point}; /* * This file provides the following conversions: @@ -50,7 +50,9 @@ where T2: RealField + SupersetOf, C: SuperTCategoryOf, Const: DimNameAdd, - DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + DefaultAllocator: + Allocator, U1>, DimNameSum, U1>> + + Allocator, U1>, U1> + Allocator, U1>, DimNameSum, U1>>, { #[inline] @@ -75,7 +77,9 @@ where T1: RealField, T2: RealField + SupersetOf, Const: DimNameAdd, - DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + DefaultAllocator: + Allocator, U1>, DimNameSum, U1>> + + Allocator, U1>, U1> + Allocator, U1>, DimNameSum, U1>>, // + Allocator // + Allocator @@ -108,12 +112,14 @@ where } } -impl From> +impl From> for OMatrix, U1>, DimNameSum, U1>> where Const: DimNameAdd, DefaultAllocator: - Allocator, U1>, DimNameSum, U1>> + Allocator>, + Allocator, U1>, DimNameSum, U1>> + + Allocator, U1>, U1> + + Allocator>, { #[inline] fn from(t: Scale) -> Self { From d82b39ca9af5aab057db157fdce2f9c78a2cf477 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 16:01:02 +0200 Subject: [PATCH 08/35] Added to_homogeneous --- src/geometry/scale.rs | 12 ++++++++---- src/geometry/scale_conversion.rs | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index deb0116b..ead932b1 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -15,7 +15,7 @@ use crate::base::allocator::Allocator; use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::storage::Owned; use crate::base::{Const, DefaultAllocator, OMatrix, OVector, SVector, Scalar}; -use crate::{ClosedAdd, ClosedDiv}; +use crate::ClosedDiv; use crate::ClosedMul; use crate::geometry::Point; @@ -208,15 +208,19 @@ impl Scale { #[must_use] pub fn to_homogeneous(&self) -> OMatrix, U1>, DimNameSum, U1>> where - T: Zero + One + ClosedAdd + Clone, + T: Zero + One + Clone, Const: DimNameAdd, DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + Allocator, U1>, U1>, { - let mut v = OVector::, U1>>::zero(); + // Unfortunately rust refuses at all costs to allow calling .to_homogeneous on a SVector + // (self.vector) so I had to do a manual copy in a new OVector + // The exact error is that to_homogeneous when called on a SVector requires DimAdd on Const + // not DimNameAdd which will strangely bring rust into thinking that DimNameAdd is a + // trait object and no longer a generic parameter. + let mut v = OVector::, U1>>::from_element(T::one()); for i in 0..D { v[(i, 0)] = self.vector[(i, 0)].clone(); } - v[(D, 0)] = T::one(); return OMatrix::, U1>, DimNameSum, U1>>::from_diagonal(&v); } diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index e6f8573b..4b627e5c 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -10,7 +10,7 @@ use crate::base::{Const, DefaultAllocator, DimName, OMatrix, OVector, SVector, S use crate::geometry::{ SuperTCategoryOf, TAffine, Transform, Scale }; -use crate::{ClosedAdd, Point}; +use crate::Point; /* * This file provides the following conversions: @@ -112,7 +112,7 @@ where } } -impl From> +impl From> for OMatrix, U1>, DimNameSum, U1>> where Const: DimNameAdd, From 0e2865085e608a5504b67a6a236d6ea7b8fbd9cc Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 16:09:06 +0200 Subject: [PATCH 09/35] Updated doc tests --- src/geometry/scale.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index ead932b1..67210720 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -192,15 +192,15 @@ impl Scale { /// ``` /// # use nalgebra::{Scale2, Scale3, Matrix3, Matrix4}; /// let t = Scale3::new(10.0, 20.0, 30.0); - /// let expected = Matrix4::new(1.0, 0.0, 0.0, 10.0, - /// 0.0, 1.0, 0.0, 20.0, - /// 0.0, 0.0, 1.0, 30.0, + /// let expected = Matrix4::new(10.0, 0.0, 0.0, 0.0, + /// 0.0, 20.0, 0.0, 0.0, + /// 0.0, 0.0, 30.0, 0.0, /// 0.0, 0.0, 0.0, 1.0); /// assert_eq!(t.to_homogeneous(), expected); /// /// let t = Scale2::new(10.0, 20.0); - /// let expected = Matrix3::new(1.0, 0.0, 10.0, - /// 0.0, 1.0, 20.0, + /// let expected = Matrix3::new(10.0, 0.0, 0.0, + /// 0.0, 20.0, 0.0, /// 0.0, 0.0, 1.0); /// assert_eq!(t.to_homogeneous(), expected); /// ``` @@ -261,7 +261,7 @@ impl Scale { /// # use nalgebra::{Scale3, Point3}; /// let t = Scale3::new(1.0, 2.0, 3.0); /// let transformed_point = t.transform_point(&Point3::new(4.0, 5.0, 6.0)); - /// assert_eq!(transformed_point, Point3::new(5.0, 7.0, 9.0)); + /// assert_eq!(transformed_point, Point3::new(4.0, 10.0, 18.0)); #[inline] #[must_use] pub fn transform_point(&self, pt: &Point) -> Point { @@ -276,8 +276,8 @@ impl Scale { /// ``` /// # use nalgebra::{Scale3, Point3}; /// let t = Scale3::new(1.0, 2.0, 3.0); - /// let transformed_point = t.inverse_transform_point(&Point3::new(4.0, 5.0, 6.0)); - /// assert_eq!(transformed_point, Point3::new(3.0, 3.0, 3.0)); + /// let transformed_point = t.inverse_transform_point(&Point3::new(4.0, 6.0, 6.0)); + /// assert_eq!(transformed_point, Point3::new(4.0, 3.0, 2.0)); #[inline] #[must_use] pub fn inverse_transform_point(&self, pt: &Point) -> Point { From 94ef916f4925d24cdde0fcf7fb99ee47a83e3a3d Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 16:18:25 +0200 Subject: [PATCH 10/35] Fixed cargo fmt --- src/geometry/scale.rs | 3 ++- src/geometry/scale_construction.rs | 2 +- src/geometry/scale_conversion.rs | 22 +++++++--------------- src/geometry/scale_ops.rs | 2 +- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 67210720..5c55e5f4 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -210,7 +210,8 @@ impl Scale { where T: Zero + One + Clone, Const: DimNameAdd, - DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + Allocator, U1>, U1>, + DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + + Allocator, U1>, U1>, { // Unfortunately rust refuses at all costs to allow calling .to_homogeneous on a SVector // (self.vector) so I had to do a manual copy in a new OVector diff --git a/src/geometry/scale_construction.rs b/src/geometry/scale_construction.rs index cade72c2..02cce69c 100644 --- a/src/geometry/scale_construction.rs +++ b/src/geometry/scale_construction.rs @@ -3,7 +3,7 @@ use crate::base::storage::Owned; #[cfg(feature = "arbitrary")] use quickcheck::{Arbitrary, Gen}; -use num::{One}; +use num::One; #[cfg(feature = "rand-no-std")] use rand::{ distributions::{Distribution, Standard}, diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index 4b627e5c..1dbf3033 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -7,9 +7,7 @@ use crate::base::allocator::Allocator; use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::{Const, DefaultAllocator, DimName, OMatrix, OVector, SVector, Scalar}; -use crate::geometry::{ - SuperTCategoryOf, TAffine, Transform, Scale -}; +use crate::geometry::{Scale, SuperTCategoryOf, TAffine, Transform}; use crate::Point; /* @@ -50,8 +48,7 @@ where T2: RealField + SupersetOf, C: SuperTCategoryOf, Const: DimNameAdd, - DefaultAllocator: - Allocator, U1>, DimNameSum, U1>> + DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + Allocator, U1>, U1> + Allocator, U1>, DimNameSum, U1>>, { @@ -77,8 +74,7 @@ where T1: RealField, T2: RealField + SupersetOf, Const: DimNameAdd, - DefaultAllocator: - Allocator, U1>, DimNameSum, U1>> + DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + Allocator, U1>, U1> + Allocator, U1>, DimNameSum, U1>>, // + Allocator @@ -116,8 +112,7 @@ impl From> for OMatrix, U1>, DimNameSum, U1>> where Const: DimNameAdd, - DefaultAllocator: - Allocator, U1>, DimNameSum, U1>> + DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + Allocator, U1>, U1> + Allocator>, { @@ -157,8 +152,7 @@ impl From> for [T; D] { } } -impl From<[Scale; 2]> - for Scale +impl From<[Scale; 2]> for Scale where T: From<[::Element; 2]>, T::Element: Scalar, @@ -172,8 +166,7 @@ where } } -impl From<[Scale; 4]> - for Scale +impl From<[Scale; 4]> for Scale where T: From<[::Element; 4]>, T::Element: Scalar, @@ -189,8 +182,7 @@ where } } -impl From<[Scale; 8]> - for Scale +impl From<[Scale; 8]> for Scale where T: From<[::Element; 8]>, T::Element: Scalar, diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs index 80927557..4d8b5f41 100644 --- a/src/geometry/scale_ops.rs +++ b/src/geometry/scale_ops.rs @@ -1,6 +1,6 @@ use std::ops::{Mul, MulAssign}; -use simba::scalar::{ClosedMul}; +use simba::scalar::ClosedMul; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::dimension::U1; From 865ac001d39c26c06d628f902ce9226e4167bf0c Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 16:20:25 +0200 Subject: [PATCH 11/35] Re-armed scale_simba --- src/geometry/mod.rs | 1 + src/geometry/scale_simba.rs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/geometry/mod.rs b/src/geometry/mod.rs index f79311e3..e7ff7304 100644 --- a/src/geometry/mod.rs +++ b/src/geometry/mod.rs @@ -54,6 +54,7 @@ mod scale_construction; mod scale_conversion; mod scale_coordinates; mod scale_ops; +mod scale_simba; mod isometry; mod isometry_alias; diff --git a/src/geometry/scale_simba.rs b/src/geometry/scale_simba.rs index 7f7f7ebf..cb42b715 100755 --- a/src/geometry/scale_simba.rs +++ b/src/geometry/scale_simba.rs @@ -3,13 +3,13 @@ use simba::simd::SimdValue; use crate::base::OVector; use crate::Scalar; -use crate::geometry::Translation; +use crate::geometry::Scale; -impl SimdValue for Translation +impl SimdValue for Scale where T::Element: Scalar, { - type Element = Translation; + type Element = Scale; type SimdBool = T::SimdBool; #[inline] From 1341801c56bb5bfb9412798c99387d3c63a2ac25 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Tue, 19 Oct 2021 16:33:12 +0200 Subject: [PATCH 12/35] Added scale * scalar + Cleanup scale_ops --- src/geometry/scale_ops.rs | 40 +++++++-------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs index 4d8b5f41..6a55cf40 100644 --- a/src/geometry/scale_ops.rs +++ b/src/geometry/scale_ops.rs @@ -36,34 +36,19 @@ add_sub_impl!(Mul, mul, ClosedMul; self: Scale, right: Scale, Output = Scale; #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; ); -// Scale ÷ Scale -// TODO: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method? -/*add_sub_impl!(Div, div, ClosedSub; +// Scale × scalar +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Scale, right: &'b Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; - 'a, 'b); - -add_sub_impl!(Div, div, ClosedSub; - (Const, U1), (Const, U1) -> (Const, U1) - const D; for; where; - self: &'a Scale, right: Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; + self: &'a Scale, right: T, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(&self.vector * right) }; 'a); -add_sub_impl!(Div, div, ClosedSub; +add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Scale, right: &'b Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; - 'b); - -add_sub_impl!(Div, div, ClosedSub; - (Const, U1), (Const, U1) -> (Const, U1) - const D; for; where; - self: Scale, right: Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; );*/ + self: Scale, right: T, Output = Scale; + #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector * right) }; ); // Scale × Point // TODO: we don't handle properly non-zero origins here. Do we want this to be the intended @@ -106,14 +91,3 @@ add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; const D; self: Scale, right: Scale; #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; ); - -/*add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; - const D; - self: Scale, right: &'b Scale; - #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; - 'b); - -add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; - const D; - self: Scale, right: Scale; - #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; );*/ From a64417870b5964fedb38382d55fd16efdd8aab5b Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Thu, 21 Oct 2021 15:06:25 +0200 Subject: [PATCH 13/35] Changed inverse API to pseudo_inverse, try_inverse, try_inverse_mut, try_inverse_transform_point, inverse_unchecked. --- src/geometry/scale.rs | 85 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 11 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 5c55e5f4..7f9f3f78 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -177,13 +177,69 @@ impl Scale { /// assert_eq!(t.inverse() * t, Scale2::identity()); /// ``` #[inline] - #[must_use = "Did you mean to use inverse_mut()?"] - pub fn inverse(&self) -> Scale + #[must_use = "Did you mean to use try_inverse_mut()?"] + pub fn try_inverse(&self) -> Option> where - T: ClosedDiv + One, + T: ClosedDiv + One + Zero, { - let useless: SVector = SVector::from_element(T::one()); - return useless.component_div(&self.vector).into(); + for i in 0..D { + if self.vector[(i, 0)] == T::zero() { + return None; + } + } + return Some(self.vector.map(|e| T::one() / e).into()); + } + + /// Inverts `self`. + /// + /// # Example + /// ``` + /// # use nalgebra::{Scale2, Scale3}; + /// let t = Scale3::new(1.0, 2.0, 3.0); + /// assert_eq!(t * t.inverse(), Scale3::identity()); + /// assert_eq!(t.inverse() * t, Scale3::identity()); + /// + /// // Work in all dimensions. + /// let t = Scale2::new(1.0, 2.0); + /// assert_eq!(t * t.inverse(), Scale2::identity()); + /// assert_eq!(t.inverse() * t, Scale2::identity()); + /// ``` + #[inline] + #[must_use] + pub unsafe fn inverse_unchecked(&self) -> Scale + where + T: ClosedDiv + One, + { + return self.vector.map(|e| T::one() / e).into(); + } + + /// Inverts `self`. + /// + /// # Example + /// ``` + /// # use nalgebra::{Scale2, Scale3}; + /// let t = Scale3::new(1.0, 2.0, 3.0); + /// assert_eq!(t * t.inverse(), Scale3::identity()); + /// assert_eq!(t.inverse() * t, Scale3::identity()); + /// + /// // Work in all dimensions. + /// let t = Scale2::new(1.0, 2.0); + /// assert_eq!(t * t.inverse(), Scale2::identity()); + /// assert_eq!(t.inverse() * t, Scale2::identity()); + /// ``` + #[inline] + #[must_use] + pub fn pseudo_inverse(&self) -> Scale + where + T: ClosedDiv + One + Zero, + { + return self.vector.map(|e| { + if e != T::zero() { + return T::one() / e; + } else { + return T::zero(); + } + }).into(); } /// Converts this Scale into its equivalent homogeneous transformation matrix. @@ -244,11 +300,15 @@ impl Scale { /// assert_eq!(inv_t * t, Scale2::identity()); /// ``` #[inline] - pub fn inverse_mut(&mut self) + pub fn try_inverse_mut(&mut self) -> bool where - T: ClosedDiv + One, + T: ClosedDiv + One + Zero { - self.vector = self.inverse().vector; + if let Some(v) = self.try_inverse() { + self.vector = v.vector; + return true; + } + return false; } } @@ -270,7 +330,7 @@ impl Scale { } } -impl Scale { +impl Scale { /// Translate the given point by the inverse of this Scale. /// /// # Example @@ -281,8 +341,11 @@ impl Scale { /// assert_eq!(transformed_point, Point3::new(4.0, 3.0, 2.0)); #[inline] #[must_use] - pub fn inverse_transform_point(&self, pt: &Point) -> Point { - return self.inverse() * pt; + pub fn try_inverse_transform_point(&self, pt: &Point) -> Option> { + if let Some(s) = self.try_inverse() { + return Some(s * pt); + } + return None; } } From 82b8ac84a0bb601542a662f97ae540ac5d0405c0 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Thu, 21 Oct 2021 15:10:26 +0200 Subject: [PATCH 14/35] Fixed code formatting --- src/geometry/scale.rs | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 7f9f3f78..05870e64 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -207,8 +207,8 @@ impl Scale { #[inline] #[must_use] pub unsafe fn inverse_unchecked(&self) -> Scale - where - T: ClosedDiv + One, + where + T: ClosedDiv + One, { return self.vector.map(|e| T::one() / e).into(); } @@ -230,16 +230,19 @@ impl Scale { #[inline] #[must_use] pub fn pseudo_inverse(&self) -> Scale - where - T: ClosedDiv + One + Zero, + where + T: ClosedDiv + One + Zero, { - return self.vector.map(|e| { - if e != T::zero() { - return T::one() / e; - } else { - return T::zero(); - } - }).into(); + return self + .vector + .map(|e| { + if e != T::zero() { + return T::one() / e; + } else { + return T::zero(); + } + }) + .into(); } /// Converts this Scale into its equivalent homogeneous transformation matrix. @@ -302,7 +305,7 @@ impl Scale { #[inline] pub fn try_inverse_mut(&mut self) -> bool where - T: ClosedDiv + One + Zero + T: ClosedDiv + One + Zero, { if let Some(v) = self.try_inverse() { self.vector = v.vector; From 99704a0ea1c9df31791ff405097e0e518290ffb3 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Thu, 21 Oct 2021 15:22:18 +0200 Subject: [PATCH 15/35] Updated all examples related to inversion API --- src/geometry/scale.rs | 59 ++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 05870e64..f626174d 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -168,13 +168,17 @@ impl Scale { /// ``` /// # use nalgebra::{Scale2, Scale3}; /// let t = Scale3::new(1.0, 2.0, 3.0); - /// assert_eq!(t * t.inverse(), Scale3::identity()); - /// assert_eq!(t.inverse() * t, Scale3::identity()); + /// assert_eq!(t * t.try_inverse().unwrap(), Scale3::identity()); + /// assert_eq!(t.try_inverse().unwrap() * t, Scale3::identity()); /// /// // Work in all dimensions. /// let t = Scale2::new(1.0, 2.0); - /// assert_eq!(t * t.inverse(), Scale2::identity()); - /// assert_eq!(t.inverse() * t, Scale2::identity()); + /// assert_eq!(t * t.try_inverse().unwrap(), Scale2::identity()); + /// assert_eq!(t.try_inverse().unwrap() * t, Scale2::identity()); + /// + /// // Returns None if any coordinate is 0. + /// let t = Scale2::new(0.0, 2.0); + /// assert_eq!(t.try_inverse(), None); /// ``` #[inline] #[must_use = "Did you mean to use try_inverse_mut()?"] @@ -195,14 +199,17 @@ impl Scale { /// # Example /// ``` /// # use nalgebra::{Scale2, Scale3}; - /// let t = Scale3::new(1.0, 2.0, 3.0); - /// assert_eq!(t * t.inverse(), Scale3::identity()); - /// assert_eq!(t.inverse() * t, Scale3::identity()); /// - /// // Work in all dimensions. - /// let t = Scale2::new(1.0, 2.0); - /// assert_eq!(t * t.inverse(), Scale2::identity()); - /// assert_eq!(t.inverse() * t, Scale2::identity()); + /// unsafe { + /// let t = Scale3::new(1.0, 2.0, 3.0); + /// assert_eq!(t * t.inverse_unchecked(), Scale3::identity()); + /// assert_eq!(t.inverse_unchecked() * t, Scale3::identity()); + /// + /// // Work in all dimensions. + /// let t = Scale2::new(1.0, 2.0); + /// assert_eq!(t * t.inverse_unchecked(), Scale2::identity()); + /// assert_eq!(t.inverse_unchecked() * t, Scale2::identity()); + /// } /// ``` #[inline] #[must_use] @@ -219,13 +226,18 @@ impl Scale { /// ``` /// # use nalgebra::{Scale2, Scale3}; /// let t = Scale3::new(1.0, 2.0, 3.0); - /// assert_eq!(t * t.inverse(), Scale3::identity()); - /// assert_eq!(t.inverse() * t, Scale3::identity()); + /// assert_eq!(t * t.pseudo_inverse(), Scale3::identity()); + /// assert_eq!(t.pseudo_inverse() * t, Scale3::identity()); /// /// // Work in all dimensions. /// let t = Scale2::new(1.0, 2.0); - /// assert_eq!(t * t.inverse(), Scale2::identity()); - /// assert_eq!(t.inverse() * t, Scale2::identity()); + /// assert_eq!(t * t.pseudo_inverse(), Scale2::identity()); + /// assert_eq!(t.pseudo_inverse() * t, Scale2::identity()); + /// + /// // Inverts only non-zero coordinates. + /// let t = Scale2::new(0.0, 2.0); + /// assert_eq!(t * t.pseudo_inverse(), Scale2::new(0.0, 1.0)); + /// assert_eq!(t.pseudo_inverse() * t, Scale2::new(0.0, 1.0)); /// ``` #[inline] #[must_use] @@ -291,16 +303,20 @@ impl Scale { /// # use nalgebra::{Scale2, Scale3}; /// let t = Scale3::new(1.0, 2.0, 3.0); /// let mut inv_t = Scale3::new(1.0, 2.0, 3.0); - /// inv_t.inverse_mut(); + /// assert!(inv_t.try_inverse_mut()); /// assert_eq!(t * inv_t, Scale3::identity()); /// assert_eq!(inv_t * t, Scale3::identity()); /// /// // Work in all dimensions. /// let t = Scale2::new(1.0, 2.0); /// let mut inv_t = Scale2::new(1.0, 2.0); - /// inv_t.inverse_mut(); + /// assert!(inv_t.try_inverse_mut()); /// assert_eq!(t * inv_t, Scale2::identity()); /// assert_eq!(inv_t * t, Scale2::identity()); + /// + /// // Does not perform any operation if a coordinate is 0. + /// let mut t = Scale2::new(0.0, 2.0); + /// assert!(!t.try_inverse_mut()); /// ``` #[inline] pub fn try_inverse_mut(&mut self) -> bool @@ -326,6 +342,7 @@ impl Scale { /// let t = Scale3::new(1.0, 2.0, 3.0); /// let transformed_point = t.transform_point(&Point3::new(4.0, 5.0, 6.0)); /// assert_eq!(transformed_point, Point3::new(4.0, 10.0, 18.0)); + /// ``` #[inline] #[must_use] pub fn transform_point(&self, pt: &Point) -> Point { @@ -340,8 +357,14 @@ impl Scale /// ``` /// # use nalgebra::{Scale3, Point3}; /// let t = Scale3::new(1.0, 2.0, 3.0); - /// let transformed_point = t.inverse_transform_point(&Point3::new(4.0, 6.0, 6.0)); + /// let transformed_point = t.try_inverse_transform_point(&Point3::new(4.0, 6.0, 6.0)).unwrap(); /// assert_eq!(transformed_point, Point3::new(4.0, 3.0, 2.0)); + /// + /// // Returns None if the inverse doesn't exist. + /// let t = Scale3::new(1.0, 0.0, 3.0); + /// let transformed_point = t.try_inverse_transform_point(&Point3::new(4.0, 6.0, 6.0)); + /// assert_eq!(transformed_point, None); + /// ``` #[inline] #[must_use] pub fn try_inverse_transform_point(&self, pt: &Point) -> Option> { From 4466fb25148654a5dfbcec9e32f76503f7d25a0f Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Thu, 21 Oct 2021 15:47:00 +0200 Subject: [PATCH 16/35] Added point * vector --- src/geometry/scale_ops.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs index 6a55cf40..df42e9bc 100644 --- a/src/geometry/scale_ops.rs +++ b/src/geometry/scale_ops.rs @@ -4,7 +4,7 @@ use simba::scalar::ClosedMul; use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstraint}; use crate::base::dimension::U1; -use crate::base::{Const, Scalar}; +use crate::base::{Const, SVector, Scalar}; use crate::geometry::{Point, Scale}; @@ -51,8 +51,6 @@ add_sub_impl!(Mul, mul, ClosedMul; #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector * right) }; ); // Scale × Point -// TODO: we don't handle properly non-zero origins here. Do we want this to be the intended -// behavior? add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; @@ -91,3 +89,31 @@ add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; const D; self: Scale, right: Scale; #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; ); + +// Point * Vector +add_sub_impl!(Mul, mul, ClosedMul; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: &'a Point, right: &'b SVector, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.coords.component_mul(&right)) }; + 'a, 'b); + +add_sub_impl!(Mul, mul, ClosedMul; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: &'a Point, right: SVector, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.coords.component_mul(&right)) }; + 'a); + +add_sub_impl!(Mul, mul, ClosedMul; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: Point, right: &'b SVector, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.coords.component_mul(&right)) }; + 'b); + +add_sub_impl!(Mul, mul, ClosedMul; + (Const, U1), (Const, U1) -> (Const, U1) + const D; for; where; + self: Point, right: SVector, Output = Point; + #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.coords.component_mul(&right)) }; ); From b91ead7971477b2cffd24484d0345bb2fef7a303 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Thu, 21 Oct 2021 15:56:07 +0200 Subject: [PATCH 17/35] Fixed Subset for Matrix --- src/geometry/scale_conversion.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index 1dbf3033..750a4b34 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -5,7 +5,7 @@ use simba::simd::PrimitiveSimdValue; use crate::base::allocator::Allocator; use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; -use crate::base::{Const, DefaultAllocator, DimName, OMatrix, OVector, SVector, Scalar}; +use crate::base::{Const, DefaultAllocator, OMatrix, OVector, SVector, Scalar}; use crate::geometry::{Scale, SuperTCategoryOf, TAffine, Transform}; use crate::Point; @@ -77,8 +77,6 @@ where DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + Allocator, U1>, U1> + Allocator, U1>, DimNameSum, U1>>, - // + Allocator - // + Allocator { #[inline] fn to_superset(&self) -> OMatrix, U1>, DimNameSum, U1>> { @@ -87,14 +85,17 @@ where #[inline] fn is_in_subset(m: &OMatrix, U1>, DimNameSum, U1>>) -> bool { - let id = m.generic_slice((0, 0), (DimNameSum::, U1>::name(), Const::)); - - // Scalar types agree. - m.iter().all(|e| SupersetOf::::is_in_subset(e)) && - // The block part does nothing. - id.is_identity(T2::zero()) && - // The normalization factor is one. - m[(D, D)] == T2::one() + if m[(D, D)] != T2::one() { + return false; + } + for i in 0..D + 1 { + for j in 0..D + 1 { + if i != j && m[(i, j)] != T2::zero() { + return false; + } + } + } + return true; } #[inline] From de41c42af7ff08262c24c9cc82f3b084edb2daad Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:20:13 +0200 Subject: [PATCH 18/35] Update src/geometry/scale.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplified code Co-authored-by: Sébastien Crozet --- src/geometry/scale.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index f626174d..fc966013 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -187,7 +187,7 @@ impl Scale { T: ClosedDiv + One + Zero, { for i in 0..D { - if self.vector[(i, 0)] == T::zero() { + if self.vector[i] == T::zero() { return None; } } From 91b8424a860eb8d0756aebd735d908319db8e246 Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:21:07 +0200 Subject: [PATCH 19/35] Update src/geometry/scale.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed return Co-authored-by: Sébastien Crozet --- src/geometry/scale.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index fc966013..773d9979 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -249,9 +249,9 @@ impl Scale { .vector .map(|e| { if e != T::zero() { - return T::one() / e; + T::one() / e } else { - return T::zero(); + T::zero() } }) .into(); From 6123c86f9e3cbbb609b6340407b26e2b7bfedf62 Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:24:16 +0200 Subject: [PATCH 20/35] Update src/geometry/scale.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed return Co-authored-by: Sébastien Crozet --- src/geometry/scale.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 773d9979..8a41c663 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -346,7 +346,7 @@ impl Scale { #[inline] #[must_use] pub fn transform_point(&self, pt: &Point) -> Point { - return self * pt; + self * pt } } From 26e36c15ba3aa86f007c418413d6d7c59a05cd1b Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:25:48 +0200 Subject: [PATCH 21/35] Update src/geometry/scale.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed return Co-authored-by: Sébastien Crozet --- src/geometry/scale.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 8a41c663..23e46373 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -325,9 +325,10 @@ impl Scale { { if let Some(v) = self.try_inverse() { self.vector = v.vector; - return true; + true + } else { + false } - return false; } } From 5b44502632a849cd59ca0f63d4545ba4ff1492b0 Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:27:38 +0200 Subject: [PATCH 22/35] Update src/geometry/scale.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplified code. Co-authored-by: Sébastien Crozet --- src/geometry/scale.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 23e46373..33a6bf3a 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -369,10 +369,7 @@ impl Scale #[inline] #[must_use] pub fn try_inverse_transform_point(&self, pt: &Point) -> Option> { - if let Some(s) = self.try_inverse() { - return Some(s * pt); - } - return None; + self.try_inverse().map(|s| s * pt) } } From f7eec7317cfee6c950f5362b94499725fc1c74eb Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:27:54 +0200 Subject: [PATCH 23/35] Update src/geometry/scale_conversion.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed return. Co-authored-by: Sébastien Crozet --- src/geometry/scale_conversion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index 750a4b34..96ddb2ec 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -95,7 +95,7 @@ where } } } - return true; + true } #[inline] From ded853757c9c4d677ae1040793833878702a637c Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:31:35 +0200 Subject: [PATCH 24/35] Update src/geometry/scale.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Crozet --- src/geometry/scale.rs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 33a6bf3a..2f677d95 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -284,17 +284,15 @@ impl Scale { DefaultAllocator: Allocator, U1>, DimNameSum, U1>> + Allocator, U1>, U1>, { - // Unfortunately rust refuses at all costs to allow calling .to_homogeneous on a SVector - // (self.vector) so I had to do a manual copy in a new OVector - // The exact error is that to_homogeneous when called on a SVector requires DimAdd on Const - // not DimNameAdd which will strangely bring rust into thinking that DimNameAdd is a - // trait object and no longer a generic parameter. - let mut v = OVector::, U1>>::from_element(T::one()); + // TODO: use self.vector.push() instead. We can’t right now because + // that would require the DimAdd bound (but here we use DimNameAdd). + // This should be fixable once Rust gets a more complete support of + // const-generics. + let mut v = OVector::from_element(T::one()); for i in 0..D { - v[(i, 0)] = self.vector[(i, 0)].clone(); + v[i] = self.vector[i].clone(); } - return OMatrix::, U1>, DimNameSum, U1>>::from_diagonal(&v); - } + return OMatrix::from_diagonal(&v); /// Inverts `self` in-place. /// From c11e1ffb4dffd394e2eaebd800caed343db71805 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Sun, 24 Oct 2021 20:40:02 +0200 Subject: [PATCH 25/35] Fixed missing curly bracket --- src/geometry/scale.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 2f677d95..9f3e778c 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -293,6 +293,7 @@ impl Scale { v[i] = self.vector[i].clone(); } return OMatrix::from_diagonal(&v); + } /// Inverts `self` in-place. /// From 510ffcbb18eb840236d6a0c81ce76652c6a5fefe Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:41:21 +0200 Subject: [PATCH 26/35] Update src/geometry/scale_coordinates.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Crozet --- src/geometry/scale_coordinates.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry/scale_coordinates.rs b/src/geometry/scale_coordinates.rs index 2f3fb5bc..73ad815f 100644 --- a/src/geometry/scale_coordinates.rs +++ b/src/geometry/scale_coordinates.rs @@ -18,7 +18,7 @@ macro_rules! deref_impl( #[inline] fn deref(&self) -> &Self::Target { - unsafe { &*(self as *const Scale as *const Self::Target) } + self.vector.deref() } } From 8efa9f76b7429aff3ce95f11905af31f52fb23b2 Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 20:41:27 +0200 Subject: [PATCH 27/35] Update src/geometry/scale_coordinates.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Crozet --- src/geometry/scale_coordinates.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry/scale_coordinates.rs b/src/geometry/scale_coordinates.rs index 73ad815f..5158c62d 100644 --- a/src/geometry/scale_coordinates.rs +++ b/src/geometry/scale_coordinates.rs @@ -25,7 +25,7 @@ macro_rules! deref_impl( impl DerefMut for Scale { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { - unsafe { &mut *(self as *mut Scale as *mut Self::Target) } + self.vector.deref_mut() } } } From 0aba533556d386ca9366ea73fc6c8328ff377598 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Sun, 24 Oct 2021 20:45:40 +0200 Subject: [PATCH 28/35] Added Scale * Vector --- src/geometry/scale_ops.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs index df42e9bc..1572018d 100644 --- a/src/geometry/scale_ops.rs +++ b/src/geometry/scale_ops.rs @@ -90,30 +90,30 @@ add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; self: Scale, right: Scale; #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; ); -// Point * Vector +// Scale * Vector add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Point, right: &'b SVector, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.coords.component_mul(&right)) }; + self: &'a Scale, right: &'b SVector, Output = SVector; + #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; 'a, 'b); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: &'a Point, right: SVector, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.coords.component_mul(&right)) }; + self: &'a Scale, right: SVector, Output = SVector; + #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; 'a); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Point, right: &'b SVector, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.coords.component_mul(&right)) }; + self: Scale, right: &'b SVector, Output = SVector; + #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; 'b); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; - self: Point, right: SVector, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.coords.component_mul(&right)) }; ); + self: Scale, right: SVector, Output = SVector; + #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; ); From 6d3978b21279f3a563ef4d7c2daeb93fedab4c00 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Sun, 24 Oct 2021 20:55:10 +0200 Subject: [PATCH 29/35] Added Scale *= scalar + reordered ops --- src/geometry/scale_ops.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs index 1572018d..92510b86 100644 --- a/src/geometry/scale_ops.rs +++ b/src/geometry/scale_ops.rs @@ -78,18 +78,6 @@ add_sub_impl!(Mul, mul, ClosedMul; self: Scale, right: Point, Output = Point; #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; ); -// Scale *= Scale -add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; - const D; - self: Scale, right: &'b Scale; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; - 'b); - -add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; - const D; - self: Scale, right: Scale; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; ); - // Scale * Vector add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) @@ -117,3 +105,21 @@ add_sub_impl!(Mul, mul, ClosedMul; const D; for; where; self: Scale, right: SVector, Output = SVector; #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; ); + +// Scale *= Scale +add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; + const D; + self: Scale, right: &'b Scale; + #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; + 'b); + +add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; + const D; + self: Scale, right: Scale; + #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; ); + +// Scale ×= scalar +add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; + const D; + self: Scale, right: T; + #[allow(clippy::suspicious_op_assign_impl)] { self.vector *= right }; ); From 9d2639b74269aecbeeaa6fccd2d6e83e5e5f6f7a Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Sun, 24 Oct 2021 21:51:36 +0200 Subject: [PATCH 30/35] Removed clippy suspicious_arithmetic_impl allow --- src/geometry/scale_ops.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/geometry/scale_ops.rs b/src/geometry/scale_ops.rs index 92510b86..c056a301 100644 --- a/src/geometry/scale_ops.rs +++ b/src/geometry/scale_ops.rs @@ -13,113 +13,113 @@ add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: &'b Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; + Scale::from(self.vector.component_mul(&right.vector)); 'a, 'b); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; + Scale::from(self.vector.component_mul(&right.vector)); 'a); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: &'b Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; + Scale::from(self.vector.component_mul(&right.vector)); 'b); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: Scale, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector.component_mul(&right.vector)) }; ); + Scale::from(self.vector.component_mul(&right.vector)); ); // Scale × scalar add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: T, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(&self.vector * right) }; + Scale::from(&self.vector * right); 'a); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: T, Output = Scale; - #[allow(clippy::suspicious_arithmetic_impl)] { Scale::from(self.vector * right) }; ); + Scale::from(self.vector * right); ); // Scale × Point add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: &'b Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; + Point::from(self.vector.component_mul(&right.coords)); 'a, 'b); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; + Point::from(self.vector.component_mul(&right.coords)); 'a); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: &'b Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; + Point::from(self.vector.component_mul(&right.coords)); 'b); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: Point, Output = Point; - #[allow(clippy::suspicious_arithmetic_impl)] { Point::from(self.vector.component_mul(&right.coords)) }; ); + Point::from(self.vector.component_mul(&right.coords)); ); // Scale * Vector add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: &'b SVector, Output = SVector; - #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; + SVector::from(self.vector.component_mul(&right)); 'a, 'b); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: &'a Scale, right: SVector, Output = SVector; - #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; + SVector::from(self.vector.component_mul(&right)); 'a); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: &'b SVector, Output = SVector; - #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; + SVector::from(self.vector.component_mul(&right)); 'b); add_sub_impl!(Mul, mul, ClosedMul; (Const, U1), (Const, U1) -> (Const, U1) const D; for; where; self: Scale, right: SVector, Output = SVector; - #[allow(clippy::suspicious_arithmetic_impl)] { SVector::from(self.vector.component_mul(&right)) }; ); + SVector::from(self.vector.component_mul(&right)); ); // Scale *= Scale add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; const D; self: Scale, right: &'b Scale; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; + self.vector.component_mul_assign(&right.vector); 'b); add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; const D; self: Scale, right: Scale; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector.component_mul_assign(&right.vector); }; ); + self.vector.component_mul_assign(&right.vector); ); // Scale ×= scalar add_sub_assign_impl!(MulAssign, mul_assign, ClosedMul; const D; self: Scale, right: T; - #[allow(clippy::suspicious_op_assign_impl)] { self.vector *= right }; ); + self.vector *= right; ); From b8800ccd15c76e78a80cfc83f53f96f3dbbb58a9 Mon Sep 17 00:00:00 2001 From: Yuri6037 Date: Sun, 24 Oct 2021 21:52:35 +0200 Subject: [PATCH 31/35] Update src/geometry/scale_conversion.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Sébastien Crozet --- src/geometry/scale_conversion.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index 96ddb2ec..cce0c6f1 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -102,9 +102,9 @@ where fn from_superset_unchecked( m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { - let t = m.fixed_slice::(0, D); + let t = m.column().fixed_slice::(0, D).into_owned(); Self { - vector: crate::convert_unchecked(t.into_owned()), + vector: crate::convert_unchecked(t), } } } From 54b8a5b900e5ac255d8a4f9cf7ac6ae4fe962940 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Sun, 24 Oct 2021 21:55:11 +0200 Subject: [PATCH 32/35] Rollbacked buggy update --- src/geometry/scale_conversion.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index cce0c6f1..fda15cfe 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -102,9 +102,9 @@ where fn from_superset_unchecked( m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { - let t = m.column().fixed_slice::(0, D).into_owned(); + let t = m.fixed_slice::(0, D).into_owned(); Self { - vector: crate::convert_unchecked(t), + vector: crate::convert_unchecked(t.into_owned()), } } } From 25dba521978bb7a75ebe8544a8845a95467bd9a3 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Sun, 24 Oct 2021 21:58:05 +0200 Subject: [PATCH 33/35] Removed additional into_owned call --- src/geometry/scale_conversion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index fda15cfe..893983a4 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -104,7 +104,7 @@ where ) -> Self { let t = m.fixed_slice::(0, D).into_owned(); Self { - vector: crate::convert_unchecked(t.into_owned()), + vector: crate::convert_unchecked(t), } } } From 209f77ccaf786f094714091474c98249fafccf83 Mon Sep 17 00:00:00 2001 From: Yuri Edward Date: Sun, 24 Oct 2021 22:26:01 +0200 Subject: [PATCH 34/35] Fixed from_superset_unchecked --- src/geometry/scale_conversion.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index 893983a4..68b69da5 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -102,9 +102,9 @@ where fn from_superset_unchecked( m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { - let t = m.fixed_slice::(0, D).into_owned(); + let v = m.fixed_slice::(0, 0).into_owned().diagonal(); Self { - vector: crate::convert_unchecked(t), + vector: crate::convert_unchecked(v), } } } From 4be7db36fd26f88cd3b96c7952aad6f2d528c5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Crozet?= Date: Mon, 25 Oct 2021 09:57:58 +0200 Subject: [PATCH 35/35] Remove useless `into_owned`. --- src/geometry/scale_conversion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/geometry/scale_conversion.rs b/src/geometry/scale_conversion.rs index 68b69da5..2dc670a1 100644 --- a/src/geometry/scale_conversion.rs +++ b/src/geometry/scale_conversion.rs @@ -102,7 +102,7 @@ where fn from_superset_unchecked( m: &OMatrix, U1>, DimNameSum, U1>>, ) -> Self { - let v = m.fixed_slice::(0, 0).into_owned().diagonal(); + let v = m.fixed_slice::(0, 0).diagonal(); Self { vector: crate::convert_unchecked(v), }