#[cfg(feature = "abomonation-serialize")] use std::io::{Result as IOResult, Write}; use std::ops::Deref; #[cfg(feature = "serde-serialize-no-std")] use serde::{Deserialize, Deserializer, Serialize, Serializer}; #[cfg(feature = "abomonation-serialize")] use abomonation::Abomonation; use crate::allocator::Allocator; use crate::base::DefaultAllocator; use crate::storage::Storage; use crate::{Dim, Matrix, OMatrix, RealField, Scalar, SimdComplexField, SimdRealField}; /// A wrapper that ensures the underlying algebraic entity has a unit norm. /// /// **It is likely that the only piece of documentation that you need in this page are:** /// - **[The construction with normalization](#construction-with-normalization)** /// - **[Data extraction and construction without normalization](#data-extraction-and-construction-without-normalization)** /// - **[Interpolation between two unit vectors](#interpolation-between-two-unit-vectors)** /// /// All the other impl blocks you will see in this page are about [`UnitComplex`](crate::UnitComplex) /// and [`UnitQuaternion`](crate::UnitQuaternion); both built on top of `Unit`. If you are interested /// in their documentation, read their dedicated pages directly. #[repr(transparent)] #[derive(Clone, Hash, Debug, Copy)] pub struct Unit { pub(crate) value: T, } #[cfg(feature = "bytemuck")] unsafe impl bytemuck::Zeroable for Unit where T: bytemuck::Zeroable {} #[cfg(feature = "bytemuck")] unsafe impl bytemuck::Pod for Unit where T: bytemuck::Pod {} #[cfg(feature = "serde-serialize-no-std")] impl Serialize for Unit { fn serialize(&self, serializer: S) -> Result where S: Serializer, { self.value.serialize(serializer) } } #[cfg(feature = "serde-serialize-no-std")] impl<'de, T: Deserialize<'de>> Deserialize<'de> for Unit { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { T::deserialize(deserializer).map(|x| Unit { value: x }) } } #[cfg(feature = "abomonation-serialize")] impl Abomonation for Unit { unsafe fn entomb(&self, writer: &mut W) -> IOResult<()> { self.value.entomb(writer) } fn extent(&self) -> usize { self.value.extent() } unsafe fn exhume<'a, 'b>(&'a mut self, bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { self.value.exhume(bytes) } } #[cfg(feature = "rkyv-serialize-no-std")] mod rkyv_impl { use super::Unit; use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; impl Archive for Unit { type Archived = Unit; type Resolver = T::Resolver; fn resolve( &self, pos: usize, resolver: Self::Resolver, out: &mut ::core::mem::MaybeUninit, ) { self.value.resolve( pos + offset_of!(Self::Archived, value), resolver, project_struct!(out: Self::Archived => value), ); } } impl, S: Fallible + ?Sized> Serialize for Unit { fn serialize(&self, serializer: &mut S) -> Result { self.value.serialize(serializer) } } impl Deserialize, D> for Unit where T::Archived: Deserialize, { fn deserialize(&self, deserializer: &mut D) -> Result, D::Error> { Ok(Unit { value: self.value.deserialize(deserializer)?, }) } } } impl PartialEq for Unit> where T: Scalar + PartialEq, R: Dim, C: Dim, S: Storage, { #[inline] fn eq(&self, rhs: &Self) -> bool { self.value.eq(&rhs.value) } } impl Eq for Unit> where T: Scalar + Eq, R: Dim, C: Dim, S: Storage, { } /// Trait implemented by entities scan be be normalized and put in an `Unit` struct. pub trait Normed { /// The type of the norm. type Norm: SimdRealField; /// Computes the norm. fn norm(&self) -> Self::Norm; /// Computes the squared norm. fn norm_squared(&self) -> Self::Norm; /// Multiply `self` by n. fn scale_mut(&mut self, n: Self::Norm); /// Divides `self` by n. fn unscale_mut(&mut self, n: Self::Norm); } /// # Construction with normalization impl Unit { /// Normalize the given vector and return it wrapped on a `Unit` structure. #[inline] pub fn new_normalize(value: T) -> Self { Self::new_and_get(value).0 } /// Attempts to normalize the given vector and return it wrapped on a `Unit` structure. /// /// Returns `None` if the norm was smaller or equal to `min_norm`. #[inline] pub fn try_new(value: T, min_norm: T::Norm) -> Option where T::Norm: RealField, { Self::try_new_and_get(value, min_norm).map(|res| res.0) } /// Normalize the given vector and return it wrapped on a `Unit` structure and its norm. #[inline] pub fn new_and_get(mut value: T) -> (Self, T::Norm) { let n = value.norm(); value.unscale_mut(n); (Unit { value }, n) } /// Normalize the given vector and return it wrapped on a `Unit` structure and its norm. /// /// Returns `None` if the norm was smaller or equal to `min_norm`. #[inline] pub fn try_new_and_get(mut value: T, min_norm: T::Norm) -> Option<(Self, T::Norm)> where T::Norm: RealField, { let sq_norm = value.norm_squared(); if sq_norm > min_norm * min_norm { let n = sq_norm.simd_sqrt(); value.unscale_mut(n); Some((Unit { value }, n)) } else { None } } /// Normalizes this vector again. This is useful when repeated computations /// might cause a drift in the norm because of float inaccuracies. /// /// Returns the norm before re-normalization. See `.renormalize_fast` for a faster alternative /// that may be slightly less accurate if `self` drifted significantly from having a unit length. #[inline] pub fn renormalize(&mut self) -> T::Norm { let n = self.norm(); self.value.unscale_mut(n); n } /// Normalizes this vector again using a first-order Taylor approximation. /// This is useful when repeated computations might cause a drift in the norm /// because of float inaccuracies. #[inline] pub fn renormalize_fast(&mut self) { let sq_norm = self.value.norm_squared(); let three: T::Norm = crate::convert(3.0); let half: T::Norm = crate::convert(0.5); self.value.scale_mut(half * (three - sq_norm)); } } /// # Data extraction and construction without normalization impl Unit { /// Wraps the given value, assuming it is already normalized. #[inline] pub const fn new_unchecked(value: T) -> Self { Unit { value } } /// Wraps the given reference, assuming it is already normalized. #[inline] pub fn from_ref_unchecked(value: &T) -> &Self { unsafe { &*(value as *const T as *const Self) } } /// Retrieves the underlying value. #[inline] pub fn into_inner(self) -> T { self.value } /// Retrieves the underlying value. /// Deprecated: use [Unit::into_inner] instead. #[deprecated(note = "use `.into_inner()` instead")] #[inline] pub fn unwrap(self) -> T { self.value } /// Returns a mutable reference to the underlying value. This is `_unchecked` because modifying /// the underlying value in such a way that it no longer has unit length may lead to unexpected /// results. #[inline] pub fn as_mut_unchecked(&mut self) -> &mut T { &mut self.value } } impl AsRef for Unit { #[inline] fn as_ref(&self) -> &T { &self.value } } /* /* * * Conversions. * */ impl SubsetOf for Unit where T::RealField: RelativeEq { #[inline] fn to_superset(&self) -> T { self.clone().into_inner() } #[inline] fn is_in_subset(value: &T) -> bool { relative_eq!(value.norm_squared(), crate::one()) } #[inline] fn from_superset_unchecked(value: &T) -> Self { Unit::new_normalize(value.clone()) // We still need to re-normalize because the condition is inexact. } } // impl RelativeEq for Unit { // type Epsilon = T::Epsilon; // // #[inline] // fn default_epsilon() -> Self::Epsilon { // T::default_epsilon() // } // // #[inline] // fn default_max_relative() -> Self::Epsilon { // T::default_max_relative() // } // // #[inline] // fn default_max_ulps() -> u32 { // T::default_max_ulps() // } // // #[inline] // fn relative_eq(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool { // self.value.relative_eq(&other.value, epsilon, max_relative) // } // // #[inline] // fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool { // self.value.ulps_eq(&other.value, epsilon, max_ulps) // } // } */ // TODO:re-enable this impl when specialization is possible. // Currently, it is disabled so that we can have a nice output for the `UnitQuaternion` display. /* impl fmt::Display for Unit { // XXX: will not always work correctly due to rounding errors. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.value.fmt(f) } } */ impl Deref for Unit { type Target = T; #[inline] fn deref(&self) -> &T { unsafe { &*(self as *const Self as *const T) } } } // NOTE: we can't use a generic implementation for `Unit` because // num_complex::Complex does not implement `From[Complex<...>...]` (and can't // because of the orphan rules). impl From<[Unit>; 2]> for Unit> where T: From<[::Element; 2]>, T::Element: Scalar, DefaultAllocator: Allocator + Allocator, { #[inline] fn from(arr: [Unit>; 2]) -> Self { Self::new_unchecked(OMatrix::from([ arr[0].clone().into_inner(), arr[1].clone().into_inner(), ])) } } impl From<[Unit>; 4]> for Unit> where T: From<[::Element; 4]>, T::Element: Scalar, DefaultAllocator: Allocator + Allocator, { #[inline] fn from(arr: [Unit>; 4]) -> Self { Self::new_unchecked(OMatrix::from([ arr[0].clone().into_inner(), arr[1].clone().into_inner(), arr[2].clone().into_inner(), arr[3].clone().into_inner(), ])) } } impl From<[Unit>; 8]> for Unit> where T: From<[::Element; 8]>, T::Element: Scalar, DefaultAllocator: Allocator + Allocator, { #[inline] fn from(arr: [Unit>; 8]) -> Self { Self::new_unchecked(OMatrix::from([ arr[0].clone().into_inner(), arr[1].clone().into_inner(), arr[2].clone().into_inner(), arr[3].clone().into_inner(), arr[4].clone().into_inner(), arr[5].clone().into_inner(), arr[6].clone().into_inner(), arr[7].clone().into_inner(), ])) } } impl From<[Unit>; 16]> for Unit> where T: From<[::Element; 16]>, T::Element: Scalar, DefaultAllocator: Allocator + Allocator, { #[inline] fn from(arr: [Unit>; 16]) -> Self { Self::new_unchecked(OMatrix::from([ arr[0].clone().into_inner(), arr[1].clone().into_inner(), arr[2].clone().into_inner(), arr[3].clone().into_inner(), arr[4].clone().into_inner(), arr[5].clone().into_inner(), arr[6].clone().into_inner(), arr[7].clone().into_inner(), arr[8].clone().into_inner(), arr[9].clone().into_inner(), arr[10].clone().into_inner(), arr[11].clone().into_inner(), arr[12].clone().into_inner(), arr[13].clone().into_inner(), arr[14].clone().into_inner(), arr[15].clone().into_inner(), ])) } }