nalgebra/geometry/
point_conversion.rs

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
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<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 + ClosedDivAssign + SupersetOf<T1>,
49    DefaultAllocator: Allocator<D> + Allocator<DimNameSum<D, U1>>,
50    // + Allocator<T1, D>
51    // + Allocator<D>,
52{
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}