nalgebra/base/
unit.rs

1use std::fmt;
2use std::ops::Deref;
3
4#[cfg(feature = "serde-serialize-no-std")]
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6
7use crate::allocator::Allocator;
8use crate::base::DefaultAllocator;
9use crate::storage::RawStorage;
10use crate::{Dim, Matrix, OMatrix, RealField, Scalar, SimdComplexField, SimdRealField};
11
12#[cfg(feature = "rkyv-serialize")]
13use rkyv::bytecheck;
14
15/// A wrapper that ensures the underlying algebraic entity has a unit norm.
16///
17/// **It is likely that the only piece of documentation that you need in this page are:**
18/// - **[The construction with normalization](#construction-with-normalization)**
19/// - **[Data extraction and construction without normalization](#data-extraction-and-construction-without-normalization)**
20/// - **[Interpolation between two unit vectors](#interpolation-between-two-unit-vectors)**
21///
22/// All the other impl blocks you will see in this page are about [`UnitComplex`](crate::UnitComplex)
23/// and [`UnitQuaternion`](crate::UnitQuaternion); both built on top of `Unit`.  If you are interested
24/// in their documentation, read their dedicated pages directly.
25#[repr(transparent)]
26#[derive(Clone, Hash, Copy)]
27#[cfg_attr(
28    feature = "rkyv-serialize-no-std",
29    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize),
30    archive(
31        as = "Unit<T::Archived>",
32        bound(archive = "
33        T: rkyv::Archive,
34    ")
35    )
36)]
37#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))]
38pub struct Unit<T> {
39    pub(crate) value: T,
40}
41
42impl<T: fmt::Debug> fmt::Debug for Unit<T> {
43    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
44        self.value.fmt(formatter)
45    }
46}
47
48#[cfg(feature = "bytemuck")]
49unsafe impl<T> bytemuck::Zeroable for Unit<T> where T: bytemuck::Zeroable {}
50
51#[cfg(feature = "bytemuck")]
52unsafe impl<T> bytemuck::Pod for Unit<T> where T: bytemuck::Pod {}
53
54#[cfg(feature = "serde-serialize-no-std")]
55impl<T: Serialize> Serialize for Unit<T> {
56    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
57    where
58        S: Serializer,
59    {
60        self.value.serialize(serializer)
61    }
62}
63
64#[cfg(feature = "serde-serialize-no-std")]
65impl<'de, T: Deserialize<'de>> Deserialize<'de> for Unit<T> {
66    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
67    where
68        D: Deserializer<'de>,
69    {
70        T::deserialize(deserializer).map(|x| Unit { value: x })
71    }
72}
73
74impl<T, R, C, S> PartialEq for Unit<Matrix<T, R, C, S>>
75where
76    T: Scalar + PartialEq,
77    R: Dim,
78    C: Dim,
79    S: RawStorage<T, R, C>,
80{
81    #[inline]
82    fn eq(&self, rhs: &Self) -> bool {
83        self.value.eq(&rhs.value)
84    }
85}
86
87impl<T, R, C, S> Eq for Unit<Matrix<T, R, C, S>>
88where
89    T: Scalar + Eq,
90    R: Dim,
91    C: Dim,
92    S: RawStorage<T, R, C>,
93{
94}
95
96/// Trait implemented by entities scan be be normalized and put in an `Unit` struct.
97pub trait Normed {
98    /// The type of the norm.
99    type Norm: SimdRealField;
100    /// Computes the norm.
101    fn norm(&self) -> Self::Norm;
102    /// Computes the squared norm.
103    fn norm_squared(&self) -> Self::Norm;
104    /// Multiply `self` by n.
105    fn scale_mut(&mut self, n: Self::Norm);
106    /// Divides `self` by n.
107    fn unscale_mut(&mut self, n: Self::Norm);
108}
109
110/// # Construction with normalization
111impl<T: Normed> Unit<T> {
112    /// Normalize the given vector and return it wrapped on a `Unit` structure.
113    #[inline]
114    pub fn new_normalize(value: T) -> Self {
115        Self::new_and_get(value).0
116    }
117
118    /// Attempts to normalize the given vector and return it wrapped on a `Unit` structure.
119    ///
120    /// Returns `None` if the norm was smaller or equal to `min_norm`.
121    #[inline]
122    pub fn try_new(value: T, min_norm: T::Norm) -> Option<Self>
123    where
124        T::Norm: RealField,
125    {
126        Self::try_new_and_get(value, min_norm).map(|res| res.0)
127    }
128
129    /// Normalize the given vector and return it wrapped on a `Unit` structure and its norm.
130    #[inline]
131    pub fn new_and_get(mut value: T) -> (Self, T::Norm) {
132        let n = value.norm();
133        value.unscale_mut(n.clone());
134        (Unit { value }, n)
135    }
136
137    /// Normalize the given vector and return it wrapped on a `Unit` structure and its norm.
138    ///
139    /// Returns `None` if the norm was smaller or equal to `min_norm`.
140    #[inline]
141    pub fn try_new_and_get(mut value: T, min_norm: T::Norm) -> Option<(Self, T::Norm)>
142    where
143        T::Norm: RealField,
144    {
145        let sq_norm = value.norm_squared();
146
147        if sq_norm > min_norm.clone() * min_norm {
148            let n = sq_norm.simd_sqrt();
149            value.unscale_mut(n.clone());
150            Some((Unit { value }, n))
151        } else {
152            None
153        }
154    }
155
156    /// Normalizes this vector again. This is useful when repeated computations
157    /// might cause a drift in the norm because of float inaccuracies.
158    ///
159    /// Returns the norm before re-normalization. See `.renormalize_fast` for a faster alternative
160    /// that may be slightly less accurate if `self` drifted significantly from having a unit length.
161    #[inline]
162    pub fn renormalize(&mut self) -> T::Norm {
163        let n = self.norm();
164        self.value.unscale_mut(n.clone());
165        n
166    }
167
168    /// Normalizes this vector again using a first-order Taylor approximation.
169    /// This is useful when repeated computations might cause a drift in the norm
170    /// because of float inaccuracies.
171    #[inline]
172    pub fn renormalize_fast(&mut self) {
173        let sq_norm = self.value.norm_squared();
174        let three: T::Norm = crate::convert(3.0);
175        let half: T::Norm = crate::convert(0.5);
176        self.value.scale_mut(half * (three - sq_norm));
177    }
178}
179
180/// # Data extraction and construction without normalization
181impl<T> Unit<T> {
182    /// Wraps the given value, assuming it is already normalized.
183    #[inline]
184    pub const fn new_unchecked(value: T) -> Self {
185        Unit { value }
186    }
187
188    /// Wraps the given reference, assuming it is already normalized.
189    #[inline]
190    pub fn from_ref_unchecked(value: &T) -> &Self {
191        unsafe { &*(value as *const T as *const Self) }
192    }
193
194    /// Retrieves the underlying value.
195    #[inline]
196    pub fn into_inner(self) -> T {
197        self.value
198    }
199
200    /// Retrieves the underlying value.
201    /// Deprecated: use [`Unit::into_inner`] instead.
202    #[deprecated(note = "use `.into_inner()` instead")]
203    #[inline]
204    pub fn unwrap(self) -> T {
205        self.value
206    }
207
208    /// Returns a mutable reference to the underlying value. This is `_unchecked` because modifying
209    /// the underlying value in such a way that it no longer has unit length may lead to unexpected
210    /// results.
211    #[inline]
212    pub fn as_mut_unchecked(&mut self) -> &mut T {
213        &mut self.value
214    }
215}
216
217impl<T> AsRef<T> for Unit<T> {
218    #[inline]
219    fn as_ref(&self) -> &T {
220        &self.value
221    }
222}
223
224/*
225/*
226 *
227 * Conversions.
228 *
229 */
230impl<T: NormedSpace> SubsetOf<T> for Unit<T>
231where T::RealField: RelativeEq
232{
233    #[inline]
234    fn to_superset(&self) -> T {
235        self.clone().into_inner()
236    }
237
238    #[inline]
239    fn is_in_subset(value: &T) -> bool {
240        relative_eq!(value.norm_squared(), crate::one())
241    }
242
243    #[inline]
244    fn from_superset_unchecked(value: &T) -> Self {
245        Unit::new_normalize(value.clone()) // We still need to re-normalize because the condition is inexact.
246    }
247}
248
249// impl<T: RelativeEq> RelativeEq for Unit<T> {
250//     type Epsilon = T::Epsilon;
251//
252//     #[inline]
253//     fn default_epsilon() -> Self::Epsilon {
254//         T::default_epsilon()
255//     }
256//
257//     #[inline]
258//     fn default_max_relative() -> Self::Epsilon {
259//         T::default_max_relative()
260//     }
261//
262//     #[inline]
263//     fn default_max_ulps() -> u32 {
264//         T::default_max_ulps()
265//     }
266//
267//     #[inline]
268//     fn relative_eq(&self, other: &Self, epsilon: Self::Epsilon, max_relative: Self::Epsilon) -> bool {
269//         self.value.relative_eq(&other.value, epsilon, max_relative)
270//     }
271//
272//     #[inline]
273//     fn ulps_eq(&self, other: &Self, epsilon: Self::Epsilon, max_ulps: u32) -> bool {
274//         self.value.ulps_eq(&other.value, epsilon, max_ulps)
275//     }
276// }
277*/
278// TODO:re-enable this impl when specialization is possible.
279// Currently, it is disabled so that we can have a nice output for the `UnitQuaternion` display.
280/*
281impl<T: fmt::Display> fmt::Display for Unit<T> {
282    // XXX: will not always work correctly due to rounding errors.
283    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
284        self.value.fmt(f)
285    }
286}
287*/
288
289impl<T> Deref for Unit<T> {
290    type Target = T;
291
292    #[inline]
293    fn deref(&self) -> &T {
294        unsafe { &*(self as *const Self as *const T) }
295    }
296}
297
298// NOTE: we can't use a generic implementation for `Unit<T>` because
299// num_complex::Complex does not implement `From[Complex<...>...]` (and can't
300// because of the orphan rules).
301impl<T: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim>
302    From<[Unit<OMatrix<T::Element, R, C>>; 2]> for Unit<OMatrix<T, R, C>>
303where
304    T: From<[<T as simba::simd::SimdValue>::Element; 2]>,
305    T::Element: Scalar,
306    DefaultAllocator: Allocator<R, C>,
307{
308    #[inline]
309    fn from(arr: [Unit<OMatrix<T::Element, R, C>>; 2]) -> Self {
310        Self::new_unchecked(OMatrix::from([
311            arr[0].clone().into_inner(),
312            arr[1].clone().into_inner(),
313        ]))
314    }
315}
316
317impl<T: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim>
318    From<[Unit<OMatrix<T::Element, R, C>>; 4]> for Unit<OMatrix<T, R, C>>
319where
320    T: From<[<T as simba::simd::SimdValue>::Element; 4]>,
321    T::Element: Scalar,
322    DefaultAllocator: Allocator<R, C>,
323{
324    #[inline]
325    fn from(arr: [Unit<OMatrix<T::Element, R, C>>; 4]) -> Self {
326        Self::new_unchecked(OMatrix::from([
327            arr[0].clone().into_inner(),
328            arr[1].clone().into_inner(),
329            arr[2].clone().into_inner(),
330            arr[3].clone().into_inner(),
331        ]))
332    }
333}
334
335impl<T: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim>
336    From<[Unit<OMatrix<T::Element, R, C>>; 8]> for Unit<OMatrix<T, R, C>>
337where
338    T: From<[<T as simba::simd::SimdValue>::Element; 8]>,
339    T::Element: Scalar,
340    DefaultAllocator: Allocator<R, C>,
341{
342    #[inline]
343    fn from(arr: [Unit<OMatrix<T::Element, R, C>>; 8]) -> Self {
344        Self::new_unchecked(OMatrix::from([
345            arr[0].clone().into_inner(),
346            arr[1].clone().into_inner(),
347            arr[2].clone().into_inner(),
348            arr[3].clone().into_inner(),
349            arr[4].clone().into_inner(),
350            arr[5].clone().into_inner(),
351            arr[6].clone().into_inner(),
352            arr[7].clone().into_inner(),
353        ]))
354    }
355}
356
357impl<T: Scalar + simba::simd::PrimitiveSimdValue, R: Dim, C: Dim>
358    From<[Unit<OMatrix<T::Element, R, C>>; 16]> for Unit<OMatrix<T, R, C>>
359where
360    T: From<[<T as simba::simd::SimdValue>::Element; 16]>,
361    T::Element: Scalar,
362    DefaultAllocator: Allocator<R, C>,
363{
364    #[inline]
365    fn from(arr: [Unit<OMatrix<T::Element, R, C>>; 16]) -> Self {
366        Self::new_unchecked(OMatrix::from([
367            arr[0].clone().into_inner(),
368            arr[1].clone().into_inner(),
369            arr[2].clone().into_inner(),
370            arr[3].clone().into_inner(),
371            arr[4].clone().into_inner(),
372            arr[5].clone().into_inner(),
373            arr[6].clone().into_inner(),
374            arr[7].clone().into_inner(),
375            arr[8].clone().into_inner(),
376            arr[9].clone().into_inner(),
377            arr[10].clone().into_inner(),
378            arr[11].clone().into_inner(),
379            arr[12].clone().into_inner(),
380            arr[13].clone().into_inner(),
381            arr[14].clone().into_inner(),
382            arr[15].clone().into_inner(),
383        ]))
384    }
385}