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
13impl<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}