nalgebra/geometry/
unit_complex_conversion.rs

1use num::Zero;
2use num_complex::Complex;
3
4use simba::scalar::{RealField, SubsetOf, SupersetOf};
5use simba::simd::{PrimitiveSimdValue, SimdRealField};
6
7use crate::base::{Matrix2, Matrix3, Scalar};
8use crate::geometry::{
9    AbstractRotation, Isometry, Rotation2, Similarity, SuperTCategoryOf, TAffine, Transform,
10    Translation, UnitComplex,
11};
12
13/*
14 * This file provides the following conversions:
15 * =============================================
16 *
17 * UnitComplex -> UnitComplex
18 * UnitComplex -> Rotation<U1>
19 * UnitComplex -> Isometry<2>
20 * UnitComplex -> Similarity<2>
21 * UnitComplex -> Transform<2>
22 * UnitComplex -> Matrix<U3> (homogeneous)
23 *
24 * NOTE:
25 * UnitComplex -> Complex is already provided by: Unit<T> -> T
26 */
27
28impl<T1, T2> SubsetOf<UnitComplex<T2>> for UnitComplex<T1>
29where
30    T1: RealField,
31    T2: RealField + SupersetOf<T1>,
32{
33    #[inline]
34    fn to_superset(&self) -> UnitComplex<T2> {
35        UnitComplex::new_unchecked(self.as_ref().to_superset())
36    }
37
38    #[inline]
39    fn is_in_subset(uq: &UnitComplex<T2>) -> bool {
40        crate::is_convertible::<_, Complex<T1>>(uq.as_ref())
41    }
42
43    #[inline]
44    fn from_superset_unchecked(uq: &UnitComplex<T2>) -> Self {
45        Self::new_unchecked(crate::convert_ref_unchecked(uq.as_ref()))
46    }
47}
48
49impl<T1, T2> SubsetOf<Rotation2<T2>> for UnitComplex<T1>
50where
51    T1: RealField,
52    T2: RealField + SupersetOf<T1>,
53{
54    #[inline]
55    fn to_superset(&self) -> Rotation2<T2> {
56        let q: UnitComplex<T2> = self.to_superset();
57        q.to_rotation_matrix().to_superset()
58    }
59
60    #[inline]
61    fn is_in_subset(rot: &Rotation2<T2>) -> bool {
62        crate::is_convertible::<_, Rotation2<T1>>(rot)
63    }
64
65    #[inline]
66    fn from_superset_unchecked(rot: &Rotation2<T2>) -> Self {
67        let q = UnitComplex::<T2>::from_rotation_matrix(rot);
68        crate::convert_unchecked(q)
69    }
70}
71
72impl<T1, T2, R> SubsetOf<Isometry<T2, R, 2>> for UnitComplex<T1>
73where
74    T1: RealField,
75    T2: RealField + SupersetOf<T1>,
76    R: AbstractRotation<T2, 2> + SupersetOf<Self>,
77{
78    #[inline]
79    fn to_superset(&self) -> Isometry<T2, R, 2> {
80        Isometry::from_parts(Translation::identity(), crate::convert_ref(self))
81    }
82
83    #[inline]
84    fn is_in_subset(iso: &Isometry<T2, R, 2>) -> bool {
85        iso.translation.vector.is_zero()
86    }
87
88    #[inline]
89    fn from_superset_unchecked(iso: &Isometry<T2, R, 2>) -> Self {
90        crate::convert_ref_unchecked(&iso.rotation)
91    }
92}
93
94impl<T1, T2, R> SubsetOf<Similarity<T2, R, 2>> for UnitComplex<T1>
95where
96    T1: RealField,
97    T2: RealField + SupersetOf<T1>,
98    R: AbstractRotation<T2, 2> + SupersetOf<Self>,
99{
100    #[inline]
101    fn to_superset(&self) -> Similarity<T2, R, 2> {
102        Similarity::from_isometry(crate::convert_ref(self), T2::one())
103    }
104
105    #[inline]
106    fn is_in_subset(sim: &Similarity<T2, R, 2>) -> bool {
107        sim.isometry.translation.vector.is_zero() && sim.scaling() == T2::one()
108    }
109
110    #[inline]
111    fn from_superset_unchecked(sim: &Similarity<T2, R, 2>) -> Self {
112        crate::convert_ref_unchecked(&sim.isometry)
113    }
114}
115
116impl<T1, T2, C> SubsetOf<Transform<T2, C, 2>> for UnitComplex<T1>
117where
118    T1: RealField,
119    T2: RealField + SupersetOf<T1>,
120    C: SuperTCategoryOf<TAffine>,
121{
122    #[inline]
123    fn to_superset(&self) -> Transform<T2, C, 2> {
124        Transform::from_matrix_unchecked(self.clone().to_homogeneous().to_superset())
125    }
126
127    #[inline]
128    fn is_in_subset(t: &Transform<T2, C, 2>) -> bool {
129        <Self as SubsetOf<_>>::is_in_subset(t.matrix())
130    }
131
132    #[inline]
133    fn from_superset_unchecked(t: &Transform<T2, C, 2>) -> Self {
134        Self::from_superset_unchecked(t.matrix())
135    }
136}
137
138impl<T1: RealField, T2: RealField + SupersetOf<T1>> SubsetOf<Matrix3<T2>> for UnitComplex<T1> {
139    #[inline]
140    fn to_superset(&self) -> Matrix3<T2> {
141        self.clone().to_homogeneous().to_superset()
142    }
143
144    #[inline]
145    fn is_in_subset(m: &Matrix3<T2>) -> bool {
146        crate::is_convertible::<_, Rotation2<T1>>(m)
147    }
148
149    #[inline]
150    fn from_superset_unchecked(m: &Matrix3<T2>) -> Self {
151        let rot: Rotation2<T1> = crate::convert_ref_unchecked(m);
152        Self::from_rotation_matrix(&rot)
153    }
154}
155
156impl<T: SimdRealField> From<UnitComplex<T>> for Rotation2<T>
157where
158    T::Element: SimdRealField,
159{
160    #[inline]
161    fn from(q: UnitComplex<T>) -> Self {
162        q.to_rotation_matrix()
163    }
164}
165
166impl<T: SimdRealField> From<Rotation2<T>> for UnitComplex<T>
167where
168    T::Element: SimdRealField,
169{
170    #[inline]
171    fn from(q: Rotation2<T>) -> Self {
172        Self::from_rotation_matrix(&q)
173    }
174}
175
176impl<T: SimdRealField> From<UnitComplex<T>> for Matrix3<T>
177where
178    T::Element: SimdRealField,
179{
180    #[inline]
181    fn from(q: UnitComplex<T>) -> Matrix3<T> {
182        q.to_homogeneous()
183    }
184}
185
186impl<T: SimdRealField> From<UnitComplex<T>> for Matrix2<T>
187where
188    T::Element: SimdRealField,
189{
190    #[inline]
191    fn from(q: UnitComplex<T>) -> Self {
192        q.to_rotation_matrix().into_inner()
193    }
194}
195
196impl<T: Scalar + Copy + PrimitiveSimdValue> From<[UnitComplex<T::Element>; 2]> for UnitComplex<T>
197where
198    T: From<[<T as simba::simd::SimdValue>::Element; 2]>,
199    T::Element: Scalar + Copy,
200{
201    #[inline]
202    fn from(arr: [UnitComplex<T::Element>; 2]) -> Self {
203        Self::new_unchecked(Complex {
204            re: T::from([arr[0].re, arr[1].re]),
205            im: T::from([arr[0].im, arr[1].im]),
206        })
207    }
208}
209
210impl<T: Scalar + Copy + PrimitiveSimdValue> From<[UnitComplex<T::Element>; 4]> for UnitComplex<T>
211where
212    T: From<[<T as simba::simd::SimdValue>::Element; 4]>,
213    T::Element: Scalar + Copy,
214{
215    #[inline]
216    fn from(arr: [UnitComplex<T::Element>; 4]) -> Self {
217        Self::new_unchecked(Complex {
218            re: T::from([arr[0].re, arr[1].re, arr[2].re, arr[3].re]),
219            im: T::from([arr[0].im, arr[1].im, arr[2].im, arr[3].im]),
220        })
221    }
222}
223
224impl<T: Scalar + Copy + PrimitiveSimdValue> From<[UnitComplex<T::Element>; 8]> for UnitComplex<T>
225where
226    T: From<[<T as simba::simd::SimdValue>::Element; 8]>,
227    T::Element: Scalar + Copy,
228{
229    #[inline]
230    fn from(arr: [UnitComplex<T::Element>; 8]) -> Self {
231        Self::new_unchecked(Complex {
232            re: T::from([
233                arr[0].re, arr[1].re, arr[2].re, arr[3].re, arr[4].re, arr[5].re, arr[6].re,
234                arr[7].re,
235            ]),
236            im: T::from([
237                arr[0].im, arr[1].im, arr[2].im, arr[3].im, arr[4].im, arr[5].im, arr[6].im,
238                arr[7].im,
239            ]),
240        })
241    }
242}
243
244impl<T: Scalar + Copy + PrimitiveSimdValue> From<[UnitComplex<T::Element>; 16]> for UnitComplex<T>
245where
246    T: From<[<T as simba::simd::SimdValue>::Element; 16]>,
247    T::Element: Scalar + Copy,
248{
249    #[inline]
250    fn from(arr: [UnitComplex<T::Element>; 16]) -> Self {
251        Self::new_unchecked(Complex {
252            re: T::from([
253                arr[0].re, arr[1].re, arr[2].re, arr[3].re, arr[4].re, arr[5].re, arr[6].re,
254                arr[7].re, arr[8].re, arr[9].re, arr[10].re, arr[11].re, arr[12].re, arr[13].re,
255                arr[14].re, arr[15].re,
256            ]),
257            im: T::from([
258                arr[0].im, arr[1].im, arr[2].im, arr[3].im, arr[4].im, arr[5].im, arr[6].im,
259                arr[7].im, arr[8].im, arr[9].im, arr[10].im, arr[11].im, arr[12].im, arr[13].im,
260                arr[14].im, arr[15].im,
261            ]),
262        })
263    }
264}