1use num::{One, Zero};
2use simba::scalar::{ClosedDivAssign, SubsetOf, SupersetOf};
3use simba::simd::PrimitiveSimdValue;
4
5use crate::base::allocator::Allocator;
6use crate::base::dimension::{DimNameAdd, DimNameSum, U1};
7use crate::base::{Const, DefaultAllocator, Matrix, OVector, Scalar};
8
9use crate::geometry::Point;
10use crate::{DimName, OPoint};
11
12impl<T1, T2, D: DimName> SubsetOf<OPoint<T2, D>> for OPoint<T1, D>
21where
22 T1: Scalar,
23 T2: Scalar + SupersetOf<T1>,
24 DefaultAllocator: Allocator<D>,
25{
26 #[inline]
27 fn to_superset(&self) -> OPoint<T2, D> {
28 OPoint::from(self.coords.to_superset())
29 }
30
31 #[inline]
32 fn is_in_subset(m: &OPoint<T2, D>) -> bool {
33 m.iter().all(|e| e.is_in_subset())
36 }
37
38 #[inline]
39 fn from_superset_unchecked(m: &OPoint<T2, D>) -> Self {
40 Self::from(Matrix::from_superset_unchecked(&m.coords))
41 }
42}
43
44impl<T1, T2, D> SubsetOf<OVector<T2, DimNameSum<D, U1>>> for OPoint<T1, D>
45where
46 D: DimNameAdd<U1>,
47 T1: Scalar,
48 T2: Scalar + Zero + One + ClosedDivAssign + SupersetOf<T1>,
49 DefaultAllocator: Allocator<D> + Allocator<DimNameSum<D, U1>>,
50 {
53 #[inline]
54 fn to_superset(&self) -> OVector<T2, DimNameSum<D, U1>> {
55 let p: OPoint<T2, D> = self.to_superset();
56 p.to_homogeneous()
57 }
58
59 #[inline]
60 fn is_in_subset(v: &OVector<T2, DimNameSum<D, U1>>) -> bool {
61 crate::is_convertible::<_, OVector<T1, DimNameSum<D, U1>>>(v) && !v[D::dim()].is_zero()
62 }
63
64 #[inline]
65 fn from_superset_unchecked(v: &OVector<T2, DimNameSum<D, U1>>) -> Self {
66 let coords = v.generic_view((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone();
67 Self {
68 coords: crate::convert_unchecked(coords),
69 }
70 }
71}
72
73impl<T: Scalar + Zero + One, D: DimName> From<OPoint<T, D>> for OVector<T, DimNameSum<D, U1>>
74where
75 D: DimNameAdd<U1>,
76 DefaultAllocator: Allocator<DimNameSum<D, U1>> + Allocator<D>,
77{
78 #[inline]
79 fn from(t: OPoint<T, D>) -> Self {
80 t.to_homogeneous()
81 }
82}
83
84impl<T: Scalar, const D: usize> From<[T; D]> for Point<T, D> {
85 #[inline]
86 fn from(coords: [T; D]) -> Self {
87 Point {
88 coords: coords.into(),
89 }
90 }
91}
92
93impl<T: Scalar, const D: usize> From<Point<T, D>> for [T; D] {
94 #[inline]
95 fn from(p: Point<T, D>) -> Self {
96 p.coords.into()
97 }
98}
99
100impl<T: Scalar, D: DimName> From<OVector<T, D>> for OPoint<T, D>
101where
102 DefaultAllocator: Allocator<D>,
103{
104 #[inline]
105 fn from(coords: OVector<T, D>) -> Self {
106 OPoint { coords }
107 }
108}
109
110impl<T: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 2]>
111 for Point<T, D>
112where
113 T: From<[<T as simba::simd::SimdValue>::Element; 2]>,
114 T::Element: Scalar + Copy,
115 <DefaultAllocator as Allocator<Const<D>>>::Buffer<T::Element>: Copy,
116{
117 #[inline]
118 fn from(arr: [Point<T::Element, D>; 2]) -> Self {
119 Self::from(OVector::from([arr[0].coords, arr[1].coords]))
120 }
121}
122
123impl<T: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 4]>
124 for Point<T, D>
125where
126 T: From<[<T as simba::simd::SimdValue>::Element; 4]>,
127 T::Element: Scalar + Copy,
128 <DefaultAllocator as Allocator<Const<D>>>::Buffer<T::Element>: Copy,
129{
130 #[inline]
131 fn from(arr: [Point<T::Element, D>; 4]) -> Self {
132 Self::from(OVector::from([
133 arr[0].coords,
134 arr[1].coords,
135 arr[2].coords,
136 arr[3].coords,
137 ]))
138 }
139}
140
141impl<T: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 8]>
142 for Point<T, D>
143where
144 T: From<[<T as simba::simd::SimdValue>::Element; 8]>,
145 T::Element: Scalar + Copy,
146 <DefaultAllocator as Allocator<Const<D>>>::Buffer<T::Element>: Copy,
147{
148 #[inline]
149 fn from(arr: [Point<T::Element, D>; 8]) -> Self {
150 Self::from(OVector::from([
151 arr[0].coords,
152 arr[1].coords,
153 arr[2].coords,
154 arr[3].coords,
155 arr[4].coords,
156 arr[5].coords,
157 arr[6].coords,
158 arr[7].coords,
159 ]))
160 }
161}
162
163impl<T: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 16]>
164 for Point<T, D>
165where
166 T: From<[<T as simba::simd::SimdValue>::Element; 16]>,
167 T::Element: Scalar + Copy,
168 <DefaultAllocator as Allocator<Const<D>>>::Buffer<T::Element>: Copy,
169{
170 #[inline]
171 fn from(arr: [Point<T::Element, D>; 16]) -> Self {
172 Self::from(OVector::from([
173 arr[0].coords,
174 arr[1].coords,
175 arr[2].coords,
176 arr[3].coords,
177 arr[4].coords,
178 arr[5].coords,
179 arr[6].coords,
180 arr[7].coords,
181 arr[8].coords,
182 arr[9].coords,
183 arr[10].coords,
184 arr[11].coords,
185 arr[12].coords,
186 arr[13].coords,
187 arr[14].coords,
188 arr[15].coords,
189 ]))
190 }
191}