use num::{One, Zero}; use simba::scalar::{ClosedDiv, SubsetOf, SupersetOf}; use simba::simd::PrimitiveSimdValue; use crate::base::allocator::Allocator; use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::{Const, DefaultAllocator, Matrix, OVector, Scalar}; use crate::geometry::Point; /* * This file provides the following conversions: * ============================================= * * Point -> Point * Point -> Vector (homogeneous) */ impl SubsetOf> for Point where T1: Scalar, T2: Scalar + SupersetOf, { #[inline] fn to_superset(&self) -> Point { Point::from(self.coords.to_superset()) } #[inline] fn is_in_subset(m: &Point) -> bool { // TODO: is there a way to reuse the `.is_in_subset` from the matrix implementation of // SubsetOf? m.iter().all(|e| e.is_in_subset()) } #[inline] fn from_superset_unchecked(m: &Point) -> Self { Self::from(Matrix::from_superset_unchecked(&m.coords)) } } impl SubsetOf, U1>>> for Point where Const: DimNameAdd, T1: Scalar, T2: Scalar + Zero + One + ClosedDiv + SupersetOf, DefaultAllocator: Allocator, U1>> + Allocator, U1>>, // + Allocator // + Allocator, { #[inline] fn to_superset(&self) -> OVector, U1>> { let p: Point = self.to_superset(); p.to_homogeneous() } #[inline] fn is_in_subset(v: &OVector, U1>>) -> bool { crate::is_convertible::<_, OVector, U1>>>(v) && !v[D].is_zero() } #[inline] fn from_superset_unchecked(v: &OVector, U1>>) -> Self { let coords = v.fixed_slice::(0, 0) / v[D].inlined_clone(); Self { coords: crate::convert_unchecked(coords), } } } impl From> for OVector, U1>> where Const: DimNameAdd, DefaultAllocator: Allocator, U1>>, { #[inline] fn from(t: Point) -> Self { t.to_homogeneous() } } impl From<[T; D]> for Point { #[inline] fn from(coords: [T; D]) -> Self { Point { coords: coords.into(), } } } impl Into<[T; D]> for Point { #[inline] fn into(self) -> [T; D] { self.coords.into() } } impl From>> for Point { #[inline] fn from(coords: OVector>) -> Self { Point { coords } } } impl From<[Point; 2]> for Point where T: From<[::Element; 2]>, T::Element: Scalar + Copy, >>::Buffer: Copy, { #[inline] fn from(arr: [Point; 2]) -> Self { Self::from(OVector::from([arr[0].coords, arr[1].coords])) } } impl From<[Point; 4]> for Point where T: From<[::Element; 4]>, T::Element: Scalar + Copy, >>::Buffer: Copy, { #[inline] fn from(arr: [Point; 4]) -> Self { Self::from(OVector::from([ arr[0].coords, arr[1].coords, arr[2].coords, arr[3].coords, ])) } } impl From<[Point; 8]> for Point where T: From<[::Element; 8]>, T::Element: Scalar + Copy, >>::Buffer: Copy, { #[inline] fn from(arr: [Point; 8]) -> Self { Self::from(OVector::from([ arr[0].coords, arr[1].coords, arr[2].coords, arr[3].coords, arr[4].coords, arr[5].coords, arr[6].coords, arr[7].coords, ])) } } impl From<[Point; 16]> for Point where T: From<[::Element; 16]>, T::Element: Scalar + Copy, >>::Buffer: Copy, { #[inline] fn from(arr: [Point; 16]) -> Self { Self::from(OVector::from([ arr[0].coords, arr[1].coords, arr[2].coords, arr[3].coords, arr[4].coords, arr[5].coords, arr[6].coords, arr[7].coords, arr[8].coords, arr[9].coords, arr[10].coords, arr[11].coords, arr[12].coords, arr[13].coords, arr[14].coords, arr[15].coords, ])) } }