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; use crate::storage::Owned; use crate::{DimName, OPoint}; /* * This file provides the following conversions: * ============================================= * * Point -> Point * Point -> Vector (homogeneous) */ impl SubsetOf> for OPoint where T2: SupersetOf, DefaultAllocator: Allocator + Allocator, { #[inline] fn to_superset(&self) -> OPoint { OPoint::from(self.coords.to_superset()) } #[inline] fn is_in_subset(m: &OPoint) -> 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: &OPoint) -> Self { Self::from(Matrix::from_superset_unchecked(&m.coords)) } } impl SubsetOf>> for OPoint where D: DimNameAdd, T2: Scalar + Zero + One + ClosedDiv + SupersetOf, DefaultAllocator: Allocator + Allocator + Allocator> + Allocator>, // + Allocator // + Allocator, { #[inline] fn to_superset(&self) -> OVector> { let p: OPoint = self.to_superset(); p.to_homogeneous() } #[inline] fn is_in_subset(v: &OVector>) -> bool { crate::is_convertible::<_, OVector>>(v) && !v[D::dim()].is_zero() } #[inline] fn from_superset_unchecked(v: &OVector>) -> Self { let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].clone(); Self { coords: crate::convert_unchecked(coords), } } } impl From> for OVector> where D: DimNameAdd, DefaultAllocator: Allocator> + Allocator, { #[inline] fn from(t: OPoint) -> Self { t.to_homogeneous() } } impl From<[T; D]> for Point { #[inline] fn from(coords: [T; D]) -> Self { Point { coords: coords.into(), } } } impl From> for [T; D] { #[inline] fn from(p: Point) -> Self { p.coords.into() } } impl From> for OPoint where DefaultAllocator: Allocator, { #[inline] fn from(coords: OVector) -> Self { OPoint { coords } } } impl From<[Point; 2]> for Point where T: From<[::Element; 2]>, T::Element: Copy, Owned>: 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: Copy, Owned>: 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: Copy, Owned>: 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: Copy, Owned>: 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, ])) } }