Renamed all instances of Translation to Scale

This commit is contained in:
Yuri Edward 2021-10-19 14:21:26 +02:00
parent 1252fb00a0
commit 9c506b18e1
7 changed files with 195 additions and 260 deletions

View File

@ -48,6 +48,13 @@ mod translation_coordinates;
mod translation_ops; mod translation_ops;
mod translation_simba; mod translation_simba;
mod scale;
mod scale_alias;
mod scale_construction;
mod scale_conversion;
mod scale_coordinates;
mod scale_ops;
mod isometry; mod isometry;
mod isometry_alias; mod isometry_alias;
mod isometry_construction; mod isometry_construction;
@ -95,6 +102,9 @@ pub use self::unit_complex::*;
pub use self::translation::*; pub use self::translation::*;
pub use self::translation_alias::*; pub use self::translation_alias::*;
pub use self::scale::*;
pub use self::scale_alias::*;
pub use self::isometry::*; pub use self::isometry::*;
pub use self::isometry_alias::*; pub use self::isometry_alias::*;

View File

@ -20,21 +20,21 @@ use crate::base::{Const, DefaultAllocator, OMatrix, SVector, Scalar};
use crate::geometry::Point; use crate::geometry::Point;
/// A translation. /// A scale which supports non-uniform scaling.
#[repr(C)] #[repr(C)]
pub struct Translation<T, const D: usize> { pub struct Scale<T, const D: usize> {
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is /// The scale coordinates, i.e., how much is multiplied to a point's coordinates when it is
/// translated. /// scaled.
pub vector: SVector<T, D>, pub vector: SVector<T, D>,
} }
impl<T: fmt::Debug, const D: usize> fmt::Debug for Translation<T, D> { impl<T: fmt::Debug, const D: usize> fmt::Debug for Scale<T, D> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.vector.as_slice().fmt(formatter) self.vector.as_slice().fmt(formatter)
} }
} }
impl<T: Scalar + hash::Hash, const D: usize> hash::Hash for Translation<T, D> impl<T: Scalar + hash::Hash, const D: usize> hash::Hash for Scale<T, D>
where where
Owned<T, Const<D>>: hash::Hash, Owned<T, Const<D>>: hash::Hash,
{ {
@ -43,20 +43,20 @@ where
} }
} }
impl<T: Scalar + Copy, const D: usize> Copy for Translation<T, D> {} impl<T: Scalar + Copy, const D: usize> Copy for Scale<T, D> {}
impl<T: Scalar, const D: usize> Clone for Translation<T, D> impl<T: Scalar, const D: usize> Clone for Scale<T, D>
where where
Owned<T, Const<D>>: Clone, Owned<T, Const<D>>: Clone,
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
Translation::from(self.vector.clone()) Scale::from(self.vector.clone())
} }
} }
#[cfg(feature = "bytemuck")] #[cfg(feature = "bytemuck")]
unsafe impl<T, const D: usize> bytemuck::Zeroable for Translation<T, D> unsafe impl<T, const D: usize> bytemuck::Zeroable for Scale<T, D>
where where
T: Scalar + bytemuck::Zeroable, T: Scalar + bytemuck::Zeroable,
SVector<T, D>: bytemuck::Zeroable, SVector<T, D>: bytemuck::Zeroable,
@ -64,7 +64,7 @@ where
} }
#[cfg(feature = "bytemuck")] #[cfg(feature = "bytemuck")]
unsafe impl<T, const D: usize> bytemuck::Pod for Translation<T, D> unsafe impl<T, const D: usize> bytemuck::Pod for Scale<T, D>
where where
T: Scalar + bytemuck::Pod, T: Scalar + bytemuck::Pod,
SVector<T, D>: bytemuck::Pod, SVector<T, D>: bytemuck::Pod,
@ -72,7 +72,7 @@ where
} }
#[cfg(feature = "abomonation-serialize")] #[cfg(feature = "abomonation-serialize")]
impl<T, const D: usize> Abomonation for Translation<T, D> impl<T, const D: usize> Abomonation for Scale<T, D>
where where
T: Scalar, T: Scalar,
SVector<T, D>: Abomonation, SVector<T, D>: Abomonation,
@ -91,7 +91,7 @@ where
} }
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
impl<T: Scalar, const D: usize> Serialize for Translation<T, D> impl<T: Scalar, const D: usize> Serialize for Scale<T, D>
where where
Owned<T, Const<D>>: Serialize, Owned<T, Const<D>>: Serialize,
{ {
@ -104,7 +104,7 @@ where
} }
#[cfg(feature = "serde-serialize-no-std")] #[cfg(feature = "serde-serialize-no-std")]
impl<'a, T: Scalar, const D: usize> Deserialize<'a> for Translation<T, D> impl<'a, T: Scalar, const D: usize> Deserialize<'a> for Scale<T, D>
where where
Owned<T, Const<D>>: Deserialize<'a>, Owned<T, Const<D>>: Deserialize<'a>,
{ {
@ -114,18 +114,18 @@ where
{ {
let matrix = SVector::<T, D>::deserialize(deserializer)?; let matrix = SVector::<T, D>::deserialize(deserializer)?;
Ok(Translation::from(matrix)) Ok(Scale::from(matrix))
} }
} }
#[cfg(feature = "rkyv-serialize-no-std")] #[cfg(feature = "rkyv-serialize-no-std")]
mod rkyv_impl { mod rkyv_impl {
use super::Translation; use super::Scale;
use crate::base::SVector; use crate::base::SVector;
use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize};
impl<T: Archive, const D: usize> Archive for Translation<T, D> { impl<T: Archive, const D: usize> Archive for Scale<T, D> {
type Archived = Translation<T::Archived, D>; type Archived = Scale<T::Archived, D>;
type Resolver = <SVector<T, D> as Archive>::Resolver; type Resolver = <SVector<T, D> as Archive>::Resolver;
fn resolve( fn resolve(
@ -142,69 +142,69 @@ mod rkyv_impl {
} }
} }
impl<T: Serialize<S>, S: Fallible + ?Sized, const D: usize> Serialize<S> for Translation<T, D> { impl<T: Serialize<S>, S: Fallible + ?Sized, const D: usize> Serialize<S> for Scale<T, D> {
fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> { fn serialize(&self, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
self.vector.serialize(serializer) self.vector.serialize(serializer)
} }
} }
impl<T: Archive, _D: Fallible + ?Sized, const D: usize> Deserialize<Translation<T, D>, _D> impl<T: Archive, _D: Fallible + ?Sized, const D: usize> Deserialize<Scale<T, D>, _D>
for Translation<T::Archived, D> for Scale<T::Archived, D>
where where
T::Archived: Deserialize<T, _D>, T::Archived: Deserialize<T, _D>,
{ {
fn deserialize(&self, deserializer: &mut _D) -> Result<Translation<T, D>, _D::Error> { fn deserialize(&self, deserializer: &mut _D) -> Result<Scale<T, D>, _D::Error> {
Ok(Translation { Ok(Scale {
vector: self.vector.deserialize(deserializer)?, vector: self.vector.deserialize(deserializer)?,
}) })
} }
} }
} }
impl<T: Scalar, const D: usize> Translation<T, D> { impl<T: Scalar, const D: usize> Scale<T, D> {
/// Creates a new translation from the given vector. /// Creates a new Scale from the given vector.
#[inline] #[inline]
#[deprecated(note = "Use `::from` instead.")] #[deprecated(note = "Use `::from` instead.")]
pub fn from_vector(vector: SVector<T, D>) -> Translation<T, D> { pub fn from_vector(vector: SVector<T, D>) -> Scale<T, D> {
Translation { vector } Scale { vector }
} }
/// Inverts `self`. /// Inverts `self`.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::{Translation2, Translation3}; /// # use nalgebra::{Scale2, Scale3};
/// let t = Translation3::new(1.0, 2.0, 3.0); /// let t = Scale3::new(1.0, 2.0, 3.0);
/// assert_eq!(t * t.inverse(), Translation3::identity()); /// assert_eq!(t * t.inverse(), Scale3::identity());
/// assert_eq!(t.inverse() * t, Translation3::identity()); /// assert_eq!(t.inverse() * t, Scale3::identity());
/// ///
/// // Work in all dimensions. /// // Work in all dimensions.
/// let t = Translation2::new(1.0, 2.0); /// let t = Scale2::new(1.0, 2.0);
/// assert_eq!(t * t.inverse(), Translation2::identity()); /// assert_eq!(t * t.inverse(), Scale2::identity());
/// assert_eq!(t.inverse() * t, Translation2::identity()); /// assert_eq!(t.inverse() * t, Scale2::identity());
/// ``` /// ```
#[inline] #[inline]
#[must_use = "Did you mean to use inverse_mut()?"] #[must_use = "Did you mean to use inverse_mut()?"]
pub fn inverse(&self) -> Translation<T, D> pub fn inverse(&self) -> Scale<T, D>
where where
T: ClosedNeg, 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 /// # Example
/// ``` /// ```
/// # use nalgebra::{Translation2, Translation3, Matrix3, Matrix4}; /// # use nalgebra::{Scale2, Scale3, Matrix3, Matrix4};
/// let t = Translation3::new(10.0, 20.0, 30.0); /// let t = Scale3::new(10.0, 20.0, 30.0);
/// let expected = Matrix4::new(1.0, 0.0, 0.0, 10.0, /// let expected = Matrix4::new(1.0, 0.0, 0.0, 10.0,
/// 0.0, 1.0, 0.0, 20.0, /// 0.0, 1.0, 0.0, 20.0,
/// 0.0, 0.0, 1.0, 30.0, /// 0.0, 0.0, 1.0, 30.0,
/// 0.0, 0.0, 0.0, 1.0); /// 0.0, 0.0, 0.0, 1.0);
/// assert_eq!(t.to_homogeneous(), expected); /// 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, /// let expected = Matrix3::new(1.0, 0.0, 10.0,
/// 0.0, 1.0, 20.0, /// 0.0, 1.0, 20.0,
/// 0.0, 0.0, 1.0); /// 0.0, 0.0, 1.0);
@ -218,83 +218,80 @@ impl<T: Scalar, const D: usize> Translation<T, D> {
Const<D>: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>, DefaultAllocator: Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>,
{ {
let mut res = OMatrix::<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>::identity(); todo!();
res.fixed_slice_mut::<D, 1>(0, D).copy_from(&self.vector);
res
} }
/// Inverts `self` in-place. /// Inverts `self` in-place.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::{Translation2, Translation3}; /// # use nalgebra::{Scale2, Scale3};
/// let t = Translation3::new(1.0, 2.0, 3.0); /// let t = Scale3::new(1.0, 2.0, 3.0);
/// let mut inv_t = Translation3::new(1.0, 2.0, 3.0); /// let mut inv_t = Scale3::new(1.0, 2.0, 3.0);
/// inv_t.inverse_mut(); /// inv_t.inverse_mut();
/// assert_eq!(t * inv_t, Translation3::identity()); /// assert_eq!(t * inv_t, Scale3::identity());
/// assert_eq!(inv_t * t, Translation3::identity()); /// assert_eq!(inv_t * t, Scale3::identity());
/// ///
/// // Work in all dimensions. /// // Work in all dimensions.
/// let t = Translation2::new(1.0, 2.0); /// let t = Scale2::new(1.0, 2.0);
/// let mut inv_t = Translation2::new(1.0, 2.0); /// let mut inv_t = Scale2::new(1.0, 2.0);
/// inv_t.inverse_mut(); /// inv_t.inverse_mut();
/// assert_eq!(t * inv_t, Translation2::identity()); /// assert_eq!(t * inv_t, Scale2::identity());
/// assert_eq!(inv_t * t, Translation2::identity()); /// assert_eq!(inv_t * t, Scale2::identity());
/// ``` /// ```
#[inline] #[inline]
pub fn inverse_mut(&mut self) pub fn inverse_mut(&mut self)
where where
T: ClosedNeg, T: ClosedNeg,
{ {
self.vector.neg_mut() todo!();
} }
} }
impl<T: Scalar + ClosedAdd, const D: usize> Translation<T, D> { impl<T: Scalar + ClosedAdd, const D: usize> Scale<T, D> {
/// Translate the given point. /// Translate the given point.
/// ///
/// This is the same as the multiplication `self * pt`. /// This is the same as the multiplication `self * pt`.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::{Translation3, Point3}; /// # use nalgebra::{Scale3, Point3};
/// let t = Translation3::new(1.0, 2.0, 3.0); /// let t = Scale3::new(1.0, 2.0, 3.0);
/// let transformed_point = t.transform_point(&Point3::new(4.0, 5.0, 6.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(5.0, 7.0, 9.0));
#[inline] #[inline]
#[must_use] #[must_use]
pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> { pub fn transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
pt + &self.vector todo!();
} }
} }
impl<T: Scalar + ClosedSub, const D: usize> Translation<T, D> { impl<T: Scalar + ClosedSub, const D: usize> Scale<T, D> {
/// Translate the given point by the inverse of this translation. /// Translate the given point by the inverse of this Scale.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::{Translation3, Point3}; /// # use nalgebra::{Scale3, Point3};
/// let t = Translation3::new(1.0, 2.0, 3.0); /// 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)); /// 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)); /// assert_eq!(transformed_point, Point3::new(3.0, 3.0, 3.0));
#[inline] #[inline]
#[must_use] #[must_use]
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> { pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> {
pt - &self.vector todo!();
} }
} }
impl<T: Scalar + Eq, const D: usize> Eq for Translation<T, D> {} impl<T: Scalar + Eq, const D: usize> Eq for Scale<T, D> {}
impl<T: Scalar + PartialEq, const D: usize> PartialEq for Translation<T, D> { impl<T: Scalar + PartialEq, const D: usize> PartialEq for Scale<T, D> {
#[inline] #[inline]
fn eq(&self, right: &Translation<T, D>) -> bool { fn eq(&self, right: &Scale<T, D>) -> bool {
self.vector == right.vector self.vector == right.vector
} }
} }
impl<T: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Translation<T, D> impl<T: Scalar + AbsDiffEq, const D: usize> AbsDiffEq for Scale<T, D>
where where
T::Epsilon: Clone, T::Epsilon: Clone,
{ {
@ -311,7 +308,7 @@ where
} }
} }
impl<T: Scalar + RelativeEq, const D: usize> RelativeEq for Translation<T, D> impl<T: Scalar + RelativeEq, const D: usize> RelativeEq for Scale<T, D>
where where
T::Epsilon: Clone, T::Epsilon: Clone,
{ {
@ -332,7 +329,7 @@ where
} }
} }
impl<T: Scalar + UlpsEq, const D: usize> UlpsEq for Translation<T, D> impl<T: Scalar + UlpsEq, const D: usize> UlpsEq for Scale<T, D>
where where
T::Epsilon: Clone, T::Epsilon: Clone,
{ {
@ -352,11 +349,11 @@ where
* Display * Display
* *
*/ */
impl<T: Scalar + fmt::Display, const D: usize> fmt::Display for Translation<T, D> { impl<T: Scalar + fmt::Display, const D: usize> fmt::Display for Scale<T, D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let precision = f.precision().unwrap_or(3); let precision = f.precision().unwrap_or(3);
writeln!(f, "Translation {{")?; writeln!(f, "Scale {{")?;
write!(f, "{:.*}", precision, self.vector)?; write!(f, "{:.*}", precision, self.vector)?;
writeln!(f, "}}") writeln!(f, "}}")
} }

View File

@ -1,19 +1,19 @@
use crate::geometry::Translation; use crate::geometry::Scale;
/// A 1-dimensional translation. /// A 1-dimensional scale.
pub type Translation1<T> = Translation<T, 1>; pub type Scale1<T> = Scale<T, 1>;
/// A 2-dimensional translation. /// A 2-dimensional scale.
pub type Translation2<T> = Translation<T, 2>; pub type Scale2<T> = Scale<T, 2>;
/// A 3-dimensional translation. /// A 3-dimensional scale.
pub type Translation3<T> = Translation<T, 3>; pub type Scale3<T> = Scale<T, 3>;
/// A 4-dimensional translation. /// A 4-dimensional scale.
pub type Translation4<T> = Translation<T, 4>; pub type Scale4<T> = Scale<T, 4>;
/// A 5-dimensional translation. /// A 5-dimensional scale.
pub type Translation5<T> = Translation<T, 5>; pub type Scale5<T> = Scale<T, 5>;
/// A 6-dimensional translation. /// A 6-dimensional scale.
pub type Translation6<T> = Translation<T, 6>; pub type Scale6<T> = Scale<T, 6>;

View File

@ -13,49 +13,49 @@ use rand::{
use simba::scalar::{ClosedAdd, SupersetOf}; use simba::scalar::{ClosedAdd, SupersetOf};
use crate::base::{SVector, Scalar}; use crate::base::{SVector, Scalar};
use crate::geometry::Translation; use crate::geometry::Scale;
impl<T: Scalar, const D: usize> Translation<T, D> { impl<T: Scalar, const D: usize> Scale<T, D> {
/// Creates a new identity translation. /// Creates a new identity scale.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::{Point2, Point3, Translation2, Translation3}; /// # use nalgebra::{Point2, Point3, Scale2, Scale3};
/// let t = Translation2::identity(); /// let t = Scale2::identity();
/// let p = Point2::new(1.0, 2.0); /// let p = Point2::new(1.0, 2.0);
/// assert_eq!(t * p, p); /// assert_eq!(t * p, p);
/// ///
/// // Works in all dimensions. /// // Works in all dimensions.
/// let t = Translation3::identity(); /// let t = Scale3::identity();
/// let p = Point3::new(1.0, 2.0, 3.0); /// let p = Point3::new(1.0, 2.0, 3.0);
/// assert_eq!(t * p, p); /// assert_eq!(t * p, p);
/// ``` /// ```
#[inline] #[inline]
pub fn identity() -> Translation<T, D> pub fn identity() -> Scale<T, D>
where where
T: Zero, T: Zero,
{ {
Self::from(SVector::<T, D>::from_element(T::zero())) todo!();
} }
/// Cast the components of `self` to another type. /// Cast the components of `self` to another type.
/// ///
/// # Example /// # Example
/// ``` /// ```
/// # use nalgebra::Translation2; /// # use nalgebra::Scale2;
/// let tra = Translation2::new(1.0f64, 2.0); /// let tra = Scale2::new(1.0f64, 2.0);
/// let tra2 = tra.cast::<f32>(); /// let tra2 = tra.cast::<f32>();
/// assert_eq!(tra2, Translation2::new(1.0f32, 2.0)); /// assert_eq!(tra2, Scale2::new(1.0f32, 2.0));
/// ``` /// ```
pub fn cast<To: Scalar>(self) -> Translation<To, D> pub fn cast<To: Scalar>(self) -> Scale<To, D>
where where
Translation<To, D>: SupersetOf<Self>, Scale<To, D>: SupersetOf<Self>,
{ {
crate::convert(self) crate::convert(self)
} }
} }
impl<T: Scalar + Zero + ClosedAdd, const D: usize> One for Translation<T, D> { impl<T: Scalar + Zero + ClosedAdd, const D: usize> One for Scale<T, D> {
#[inline] #[inline]
fn one() -> Self { fn one() -> Self {
Self::identity() Self::identity()
@ -63,19 +63,19 @@ impl<T: Scalar + Zero + ClosedAdd, const D: usize> One for Translation<T, D> {
} }
#[cfg(feature = "rand-no-std")] #[cfg(feature = "rand-no-std")]
impl<T: Scalar, const D: usize> Distribution<Translation<T, D>> for Standard impl<T: Scalar, const D: usize> Distribution<Scale<T, D>> for Standard
where where
Standard: Distribution<T>, Standard: Distribution<T>,
{ {
/// Generate an arbitrary random variate for testing purposes. /// Generate an arbitrary random variate for testing purposes.
#[inline] #[inline]
fn sample<G: Rng + ?Sized>(&self, rng: &mut G) -> Translation<T, D> { fn sample<G: Rng + ?Sized>(&self, rng: &mut G) -> Scale<T, D> {
Translation::from(rng.gen::<SVector<T, D>>()) Scale::from(rng.gen::<SVector<T, D>>())
} }
} }
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<T: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Translation<T, D> impl<T: Scalar + Arbitrary + Send, const D: usize> Arbitrary for Scale<T, D>
where where
Owned<T, crate::Const<D>>: Send, Owned<T, crate::Const<D>>: Send,
{ {
@ -88,14 +88,14 @@ where
/* /*
* *
* Small translation construction from components. * Small Scale construction from components.
* *
*/ */
macro_rules! componentwise_constructors_impl( macro_rules! componentwise_constructors_impl(
($($doc: expr; $D: expr, $($args: ident:$irow: expr),*);* $(;)*) => {$( ($($doc: expr; $D: expr, $($args: ident:$irow: expr),*);* $(;)*) => {$(
impl<T> Translation<T, $D> impl<T> Scale<T, $D>
{ {
#[doc = "Initializes this translation from its components."] #[doc = "Initializes this Scale from its components."]
#[doc = "# Example\n```"] #[doc = "# Example\n```"]
#[doc = $doc] #[doc = $doc]
#[doc = "```"] #[doc = "```"]
@ -108,16 +108,16 @@ macro_rules! componentwise_constructors_impl(
); );
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; 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; 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; 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; 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; 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; 6, x:0, y:1, z:2, w:3, a:4, b:5;
); );

View File

@ -8,8 +8,7 @@ use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
use crate::base::{Const, DefaultAllocator, DimName, OMatrix, OVector, SVector, Scalar}; use crate::base::{Const, DefaultAllocator, DimName, OMatrix, OVector, SVector, Scalar};
use crate::geometry::{ use crate::geometry::{
AbstractRotation, Isometry, Similarity, SuperTCategoryOf, TAffine, Transform, Translation, SuperTCategoryOf, TAffine, Transform, Scale
Translation3, UnitDualQuaternion, UnitQuaternion,
}; };
use crate::Point; use crate::Point;
@ -17,106 +16,35 @@ use crate::Point;
* This file provides the following conversions: * This file provides the following conversions:
* ============================================= * =============================================
* *
* Translation -> Translation * Scale -> Scale
* Translation -> Isometry * Scale -> Transform
* Translation3 -> UnitDualQuaternion * Scale -> Matrix (homogeneous)
* Translation -> Similarity
* Translation -> Transform
* Translation -> Matrix (homogeneous)
*/ */
impl<T1, T2, const D: usize> SubsetOf<Translation<T2, D>> for Translation<T1, D> impl<T1, T2, const D: usize> SubsetOf<Scale<T2, D>> for Scale<T1, D>
where where
T1: Scalar, T1: Scalar,
T2: Scalar + SupersetOf<T1>, T2: Scalar + SupersetOf<T1>,
{ {
#[inline] #[inline]
fn to_superset(&self) -> Translation<T2, D> { fn to_superset(&self) -> Scale<T2, D> {
Translation::from(self.vector.to_superset()) Scale::from(self.vector.to_superset())
} }
#[inline] #[inline]
fn is_in_subset(rot: &Translation<T2, D>) -> bool { fn is_in_subset(rot: &Scale<T2, D>) -> bool {
crate::is_convertible::<_, SVector<T1, D>>(&rot.vector) crate::is_convertible::<_, SVector<T1, D>>(&rot.vector)
} }
#[inline] #[inline]
fn from_superset_unchecked(rot: &Translation<T2, D>) -> Self { fn from_superset_unchecked(rot: &Scale<T2, D>) -> Self {
Translation { Scale {
vector: rot.vector.to_subset_unchecked(), vector: rot.vector.to_subset_unchecked(),
} }
} }
} }
impl<T1, T2, R, const D: usize> SubsetOf<Isometry<T2, R, D>> for Translation<T1, D> impl<T1, T2, C, const D: usize> SubsetOf<Transform<T2, C, D>> for Scale<T1, D>
where
T1: RealField,
T2: RealField + SupersetOf<T1>,
R: AbstractRotation<T2, D>,
{
#[inline]
fn to_superset(&self) -> Isometry<T2, R, D> {
Isometry::from_parts(self.to_superset(), R::identity())
}
#[inline]
fn is_in_subset(iso: &Isometry<T2, R, D>) -> bool {
iso.rotation == R::identity()
}
#[inline]
fn from_superset_unchecked(iso: &Isometry<T2, R, D>) -> Self {
Self::from_superset_unchecked(&iso.translation)
}
}
impl<T1, T2> SubsetOf<UnitDualQuaternion<T2>> for Translation3<T1>
where
T1: RealField,
T2: RealField + SupersetOf<T1>,
{
#[inline]
fn to_superset(&self) -> UnitDualQuaternion<T2> {
let dq = UnitDualQuaternion::<T1>::from_parts(self.clone(), UnitQuaternion::identity());
dq.to_superset()
}
#[inline]
fn is_in_subset(dq: &UnitDualQuaternion<T2>) -> bool {
crate::is_convertible::<_, Translation<T1, 3>>(&dq.translation())
&& dq.rotation() == UnitQuaternion::identity()
}
#[inline]
fn from_superset_unchecked(dq: &UnitDualQuaternion<T2>) -> Self {
let dq: UnitDualQuaternion<T1> = crate::convert_ref_unchecked(dq);
dq.translation()
}
}
impl<T1, T2, R, const D: usize> SubsetOf<Similarity<T2, R, D>> for Translation<T1, D>
where
T1: RealField,
T2: RealField + SupersetOf<T1>,
R: AbstractRotation<T2, D>,
{
#[inline]
fn to_superset(&self) -> Similarity<T2, R, D> {
Similarity::from_parts(self.to_superset(), R::identity(), T2::one())
}
#[inline]
fn is_in_subset(sim: &Similarity<T2, R, D>) -> bool {
sim.isometry.rotation == R::identity() && sim.scaling() == T2::one()
}
#[inline]
fn from_superset_unchecked(sim: &Similarity<T2, R, D>) -> Self {
Self::from_superset_unchecked(&sim.isometry.translation)
}
}
impl<T1, T2, C, const D: usize> SubsetOf<Transform<T2, C, D>> for Translation<T1, D>
where where
T1: RealField, T1: RealField,
T2: RealField + SupersetOf<T1>, T2: RealField + SupersetOf<T1>,
@ -142,7 +70,7 @@ where
} }
impl<T1, T2, const D: usize> impl<T1, T2, const D: usize>
SubsetOf<OMatrix<T2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>> for Translation<T1, D> SubsetOf<OMatrix<T2, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>> for Scale<T1, D>
where where
T1: RealField, T1: RealField,
T2: RealField + SupersetOf<T1>, T2: RealField + SupersetOf<T1>,
@ -180,7 +108,7 @@ where
} }
} }
impl<T: Scalar + Zero + One, const D: usize> From<Translation<T, D>> impl<T: Scalar + Zero + One, const D: usize> From<Scale<T, D>>
for OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> for OMatrix<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>>
where where
Const<D>: DimNameAdd<U1>, Const<D>: DimNameAdd<U1>,
@ -188,49 +116,49 @@ where
Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> + Allocator<T, Const<D>>, Allocator<T, DimNameSum<Const<D>, U1>, DimNameSum<Const<D>, U1>> + Allocator<T, Const<D>>,
{ {
#[inline] #[inline]
fn from(t: Translation<T, D>) -> Self { fn from(t: Scale<T, D>) -> Self {
t.to_homogeneous() t.to_homogeneous()
} }
} }
impl<T: Scalar, const D: usize> From<OVector<T, Const<D>>> for Translation<T, D> { impl<T: Scalar, const D: usize> From<OVector<T, Const<D>>> for Scale<T, D> {
#[inline] #[inline]
fn from(vector: OVector<T, Const<D>>) -> Self { fn from(vector: OVector<T, Const<D>>) -> Self {
Translation { vector } Scale { vector }
} }
} }
impl<T: Scalar, const D: usize> From<[T; D]> for Translation<T, D> { impl<T: Scalar, const D: usize> From<[T; D]> for Scale<T, D> {
#[inline] #[inline]
fn from(coords: [T; D]) -> Self { fn from(coords: [T; D]) -> Self {
Translation { Scale {
vector: coords.into(), vector: coords.into(),
} }
} }
} }
impl<T: Scalar, const D: usize> From<Point<T, D>> for Translation<T, D> { impl<T: Scalar, const D: usize> From<Point<T, D>> for Scale<T, D> {
#[inline] #[inline]
fn from(pt: Point<T, D>) -> Self { fn from(pt: Point<T, D>) -> Self {
Translation { vector: pt.coords } Scale { vector: pt.coords }
} }
} }
impl<T: Scalar, const D: usize> From<Translation<T, D>> for [T; D] { impl<T: Scalar, const D: usize> From<Scale<T, D>> for [T; D] {
#[inline] #[inline]
fn from(t: Translation<T, D>) -> Self { fn from(t: Scale<T, D>) -> Self {
t.vector.into() t.vector.into()
} }
} }
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<T::Element, D>; 2]> impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Scale<T::Element, D>; 2]>
for Translation<T, D> for Scale<T, D>
where where
T: From<[<T as simba::simd::SimdValue>::Element; 2]>, T: From<[<T as simba::simd::SimdValue>::Element; 2]>,
T::Element: Scalar, T::Element: Scalar,
{ {
#[inline] #[inline]
fn from(arr: [Translation<T::Element, D>; 2]) -> Self { fn from(arr: [Scale<T::Element, D>; 2]) -> Self {
Self::from(OVector::from([ Self::from(OVector::from([
arr[0].vector.clone(), arr[0].vector.clone(),
arr[1].vector.clone(), arr[1].vector.clone(),
@ -238,14 +166,14 @@ where
} }
} }
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<T::Element, D>; 4]> impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Scale<T::Element, D>; 4]>
for Translation<T, D> for Scale<T, D>
where where
T: From<[<T as simba::simd::SimdValue>::Element; 4]>, T: From<[<T as simba::simd::SimdValue>::Element; 4]>,
T::Element: Scalar, T::Element: Scalar,
{ {
#[inline] #[inline]
fn from(arr: [Translation<T::Element, D>; 4]) -> Self { fn from(arr: [Scale<T::Element, D>; 4]) -> Self {
Self::from(OVector::from([ Self::from(OVector::from([
arr[0].vector.clone(), arr[0].vector.clone(),
arr[1].vector.clone(), arr[1].vector.clone(),
@ -255,14 +183,14 @@ where
} }
} }
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<T::Element, D>; 8]> impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Scale<T::Element, D>; 8]>
for Translation<T, D> for Scale<T, D>
where where
T: From<[<T as simba::simd::SimdValue>::Element; 8]>, T: From<[<T as simba::simd::SimdValue>::Element; 8]>,
T::Element: Scalar, T::Element: Scalar,
{ {
#[inline] #[inline]
fn from(arr: [Translation<T::Element, D>; 8]) -> Self { fn from(arr: [Scale<T::Element, D>; 8]) -> Self {
Self::from(OVector::from([ Self::from(OVector::from([
arr[0].vector.clone(), arr[0].vector.clone(),
arr[1].vector.clone(), arr[1].vector.clone(),
@ -276,14 +204,14 @@ where
} }
} }
impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Translation<T::Element, D>; 16]> impl<T: Scalar + PrimitiveSimdValue, const D: usize> From<[Scale<T::Element, D>; 16]>
for Translation<T, D> for Scale<T, D>
where where
T: From<[<T as simba::simd::SimdValue>::Element; 16]>, T: From<[<T as simba::simd::SimdValue>::Element; 16]>,
T::Element: Scalar, T::Element: Scalar,
{ {
#[inline] #[inline]
fn from(arr: [Translation<T::Element, D>; 16]) -> Self { fn from(arr: [Scale<T::Element, D>; 16]) -> Self {
Self::from(OVector::from([ Self::from(OVector::from([
arr[0].vector.clone(), arr[0].vector.clone(),
arr[1].vector.clone(), arr[1].vector.clone(),

View File

@ -3,29 +3,29 @@ use std::ops::{Deref, DerefMut};
use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB}; use crate::base::coordinates::{X, XY, XYZ, XYZW, XYZWA, XYZWAB};
use crate::base::Scalar; 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( macro_rules! deref_impl(
($D: expr, $Target: ident $(, $comps: ident)*) => { ($D: expr, $Target: ident $(, $comps: ident)*) => {
impl<T: Scalar> Deref for Translation<T, $D> { impl<T: Scalar> Deref for Scale<T, $D> {
type Target = $Target<T>; type Target = $Target<T>;
#[inline] #[inline]
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const Translation<T, $D> as *const Self::Target) } unsafe { &*(self as *const Scale<T, $D> as *const Self::Target) }
} }
} }
impl<T: Scalar> DerefMut for Translation<T, $D> { impl<T: Scalar> DerefMut for Scale<T, $D> {
#[inline] #[inline]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(self as *mut Translation<T, $D> as *mut Self::Target) } unsafe { &mut *(self as *mut Scale<T, $D> as *mut Self::Target) }
} }
} }
} }

View File

@ -6,114 +6,114 @@ use crate::base::constraint::{SameNumberOfColumns, SameNumberOfRows, ShapeConstr
use crate::base::dimension::U1; use crate::base::dimension::U1;
use crate::base::{Const, Scalar}; 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; add_sub_impl!(Mul, mul, ClosedAdd;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: &'a Translation<T, D>, right: &'b Translation<T, D>, Output = Translation<T, D>; self: &'a Scale<T, D>, right: &'b Scale<T, D>, Output = Scale<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + &right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'a, 'b); 'a, 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: &'a Translation<T, D>, right: Translation<T, D>, Output = Translation<T, D>; self: &'a Scale<T, D>, right: Scale<T, D>, Output = Scale<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector + right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'a); 'a);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: Translation<T, D>, right: &'b Translation<T, D>, Output = Translation<T, D>; self: Scale<T, D>, right: &'b Scale<T, D>, Output = Scale<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + &right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'b); 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: Translation<T, D>, right: Translation<T, D>, Output = Translation<T, D>; self: Scale<T, D>, right: Scale<T, D>, Output = Scale<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector + right.vector) }; ); #[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? // 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<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: &'a Translation<T, D>, right: &'b Translation<T, D>, Output = Translation<T, D>; self: &'a Scale<T, D>, right: &'b Scale<T, D>, Output = Scale<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - &right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'a, 'b); 'a, 'b);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: &'a Translation<T, D>, right: Translation<T, D>, Output = Translation<T, D>; self: &'a Scale<T, D>, right: Scale<T, D>, Output = Scale<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(&self.vector - right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'a); 'a);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: Translation<T, D>, right: &'b Translation<T, D>, Output = Translation<T, D>; self: Scale<T, D>, right: &'b Scale<T, D>, Output = Scale<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - &right.vector) }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'b); 'b);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: Translation<T, D>, right: Translation<T, D>, Output = Translation<T, D>; self: Scale<T, D>, right: Scale<T, D>, Output = Scale<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { Translation::from(self.vector - right.vector) }; ); #[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 // TODO: we don't handle properly non-zero origins here. Do we want this to be the intended
// behavior? // behavior?
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: &'a Translation<T, D>, right: &'b Point<T, D>, Output = Point<T, D>; self: &'a Scale<T, D>, right: &'b Point<T, D>, Output = Point<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'a, 'b); 'a, 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: &'a Translation<T, D>, right: Point<T, D>, Output = Point<T, D>; self: &'a Scale<T, D>, right: Point<T, D>, Output = Point<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { right + &self.vector }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'a); 'a);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: Translation<T, D>, right: &'b Point<T, D>, Output = Point<T, D>; self: Scale<T, D>, right: &'b Point<T, D>, Output = Point<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); };
'b); 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1) (Const<D>, U1), (Const<D>, U1) -> (Const<D>, U1)
const D; for; where; const D; for; where;
self: Translation<T, D>, right: Point<T, D>, Output = Point<T, D>; self: Scale<T, D>, right: Point<T, D>, Output = Point<T, D>;
#[allow(clippy::suspicious_arithmetic_impl)] { right + self.vector }; ); #[allow(clippy::suspicious_arithmetic_impl)] { todo!(); }; );
// Translation *= Translation // Scale *= Scale
add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd;
const D; const D;
self: Translation<T, D>, right: &'b Translation<T, D>; self: Scale<T, D>, right: &'b Scale<T, D>;
#[allow(clippy::suspicious_op_assign_impl)] { self.vector += &right.vector }; #[allow(clippy::suspicious_op_assign_impl)] { todo!(); };
'b); 'b);
add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd; add_sub_assign_impl!(MulAssign, mul_assign, ClosedAdd;
const D; const D;
self: Translation<T, D>, right: Translation<T, D>; self: Scale<T, D>, right: Scale<T, D>;
#[allow(clippy::suspicious_op_assign_impl)] { self.vector += right.vector }; ); #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; );
add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; add_sub_assign_impl!(DivAssign, div_assign, ClosedSub;
const D; const D;
self: Translation<T, D>, right: &'b Translation<T, D>; self: Scale<T, D>, right: &'b Scale<T, D>;
#[allow(clippy::suspicious_op_assign_impl)] { self.vector -= &right.vector }; #[allow(clippy::suspicious_op_assign_impl)] { todo!(); };
'b); 'b);
add_sub_assign_impl!(DivAssign, div_assign, ClosedSub; add_sub_assign_impl!(DivAssign, div_assign, ClosedSub;
const D; const D;
self: Translation<T, D>, right: Translation<T, D>; self: Scale<T, D>, right: Scale<T, D>;
#[allow(clippy::suspicious_op_assign_impl)] { self.vector -= right.vector }; ); #[allow(clippy::suspicious_op_assign_impl)] { todo!(); }; );