Changed inverse API to pseudo_inverse, try_inverse, try_inverse_mut, try_inverse_transform_point, inverse_unchecked.

This commit is contained in:
Yuri Edward 2021-10-21 15:06:25 +02:00
parent 1341801c56
commit a64417870b
1 changed files with 74 additions and 11 deletions

View File

@ -177,13 +177,69 @@ impl<T: Scalar, const D: usize> Scale<T, D> {
/// assert_eq!(t.inverse() * t, Scale2::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 try_inverse_mut()?"]
pub fn inverse(&self) -> Scale<T, D> pub fn try_inverse(&self) -> Option<Scale<T, D>>
where
T: ClosedDiv + One + Zero,
{
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<T, D>
where where
T: ClosedDiv + One, T: ClosedDiv + One,
{ {
let useless: SVector<T, D> = SVector::from_element(T::one()); return self.vector.map(|e| T::one() / e).into();
return useless.component_div(&self.vector).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<T, D>
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. /// Converts this Scale into its equivalent homogeneous transformation matrix.
@ -244,11 +300,15 @@ impl<T: Scalar, const D: usize> Scale<T, D> {
/// assert_eq!(inv_t * t, Scale2::identity()); /// assert_eq!(inv_t * t, Scale2::identity());
/// ``` /// ```
#[inline] #[inline]
pub fn inverse_mut(&mut self) pub fn try_inverse_mut(&mut self) -> bool
where 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<T: Scalar + ClosedMul, const D: usize> Scale<T, D> {
} }
} }
impl<T: Scalar + ClosedDiv + ClosedMul + One, const D: usize> Scale<T, D> { impl<T: Scalar + ClosedDiv + ClosedMul + One + Zero, const D: usize> Scale<T, D> {
/// Translate the given point by the inverse of this Scale. /// Translate the given point by the inverse of this Scale.
/// ///
/// # Example /// # Example
@ -281,8 +341,11 @@ impl<T: Scalar + ClosedDiv + ClosedMul + One, const D: usize> Scale<T, D> {
/// assert_eq!(transformed_point, Point3::new(4.0, 3.0, 2.0)); /// assert_eq!(transformed_point, Point3::new(4.0, 3.0, 2.0));
#[inline] #[inline]
#[must_use] #[must_use]
pub fn inverse_transform_point(&self, pt: &Point<T, D>) -> Point<T, D> { pub fn try_inverse_transform_point(&self, pt: &Point<T, D>) -> Option<Point<T, D>> {
return self.inverse() * pt; if let Some(s) = self.try_inverse() {
return Some(s * pt);
}
return None;
} }
} }