nalgebra/geometry/
point_conversion.rs

1use num::{One, Zero};
2use simba::scalar::{ClosedDiv, 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
12/*
13 * This file provides the following conversions:
14 * =============================================
15 *
16 * Point -> Point
17 * Point -> Vector (homogeneous)
18 */
19
20impl<T1, T2, D: DimName> SubsetOf<OPoint<T2, D>> for OPoint<T1, D>
21where
22    T1: Scalar,
23    T2: Scalar + SupersetOf<T1>,
24    DefaultAllocator: Allocator<T1, D> + Allocator<T2, 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        // TODO: is there a way to reuse the `.is_in_subset` from the matrix implementation of
34        // SubsetOf?
35        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 + ClosedDiv + SupersetOf<T1>,
49    DefaultAllocator: Allocator<T1, D>
50        + Allocator<T2, D>
51        + Allocator<T1, DimNameSum<D, U1>>
52        + Allocator<T2, DimNameSum<D, U1>>,
53    // + Allocator<T1, D>
54    // + Allocator<T2, D>,
55{
56    #[inline]
57    fn to_superset(&self) -> OVector<T2, DimNameSum<D, U1>> {
58        let p: OPoint<T2, D> = self.to_superset();
59        p.to_homogeneous()
60    }
61
62    #[inline]
63    fn is_in_subset(v: &OVector<T2, DimNameSum<D, U1>>) -> bool {
64        crate::is_convertible::<_, OVector<T1, DimNameSum<D, U1>>>(v) && !v[D::dim()].is_zero()
65    }
66
67    #[inline]
68    fn from_superset_unchecked(v: &OVector<T2, DimNameSum<D, U1>>) -> Self {
69        let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone();
70        Self {
71            coords: crate::convert_unchecked(coords),
72        }
73    }
74}
75
76impl<T: Scalar + Zero + One, D: DimName> From<OPoint<T, D>> for OVector<T, DimNameSum<D, U1>>
77where
78    D: DimNameAdd<U1>,
79    DefaultAllocator: Allocator<T, DimNameSum<D, U1>> + Allocator<T, D>,
80{
81    #[inline]
82    fn from(t: OPoint<T, D>) -> Self {
83        t.to_homogeneous()
84    }
85}
86
87impl<T: Scalar, const D: usize> From<[T; D]> for Point<T, D> {
88    #[inline]
89    fn from(coords: [T; D]) -> Self {
90        Point {
91            coords: coords.into(),
92        }
93    }
94}
95
96impl<T: Scalar, const D: usize> From<Point<T, D>> for [T; D] {
97    #[inline]
98    fn from(p: Point<T, D>) -> Self {
99        p.coords.into()
100    }
101}
102
103impl<T: Scalar, D: DimName> From<OVector<T, D>> for OPoint<T, D>
104where
105    DefaultAllocator: Allocator<T, D>,
106{
107    #[inline]
108    fn from(coords: OVector<T, D>) -> Self {
109        OPoint { coords }
110    }
111}
112
113impl<T: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 2]>
114    for Point<T, D>
115where
116    T: From<[<T as simba::simd::SimdValue>::Element; 2]>,
117    T::Element: Scalar + Copy,
118    <DefaultAllocator as Allocator<T::Element, Const<D>>>::Buffer: Copy,
119{
120    #[inline]
121    fn from(arr: [Point<T::Element, D>; 2]) -> Self {
122        Self::from(OVector::from([arr[0].coords, arr[1].coords]))
123    }
124}
125
126impl<T: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 4]>
127    for Point<T, D>
128where
129    T: From<[<T as simba::simd::SimdValue>::Element; 4]>,
130    T::Element: Scalar + Copy,
131    <DefaultAllocator as Allocator<T::Element, Const<D>>>::Buffer: Copy,
132{
133    #[inline]
134    fn from(arr: [Point<T::Element, D>; 4]) -> Self {
135        Self::from(OVector::from([
136            arr[0].coords,
137            arr[1].coords,
138            arr[2].coords,
139            arr[3].coords,
140        ]))
141    }
142}
143
144impl<T: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 8]>
145    for Point<T, D>
146where
147    T: From<[<T as simba::simd::SimdValue>::Element; 8]>,
148    T::Element: Scalar + Copy,
149    <DefaultAllocator as Allocator<T::Element, Const<D>>>::Buffer: Copy,
150{
151    #[inline]
152    fn from(arr: [Point<T::Element, D>; 8]) -> Self {
153        Self::from(OVector::from([
154            arr[0].coords,
155            arr[1].coords,
156            arr[2].coords,
157            arr[3].coords,
158            arr[4].coords,
159            arr[5].coords,
160            arr[6].coords,
161            arr[7].coords,
162        ]))
163    }
164}
165
166impl<T: Scalar + Copy + PrimitiveSimdValue, const D: usize> From<[Point<T::Element, D>; 16]>
167    for Point<T, D>
168where
169    T: From<[<T as simba::simd::SimdValue>::Element; 16]>,
170    T::Element: Scalar + Copy,
171    <DefaultAllocator as Allocator<T::Element, Const<D>>>::Buffer: Copy,
172{
173    #[inline]
174    fn from(arr: [Point<T::Element, D>; 16]) -> Self {
175        Self::from(OVector::from([
176            arr[0].coords,
177            arr[1].coords,
178            arr[2].coords,
179            arr[3].coords,
180            arr[4].coords,
181            arr[5].coords,
182            arr[6].coords,
183            arr[7].coords,
184            arr[8].coords,
185            arr[9].coords,
186            arr[10].coords,
187            arr[11].coords,
188            arr[12].coords,
189            arr[13].coords,
190            arr[14].coords,
191            arr[15].coords,
192        ]))
193    }
194}