use num::{One, Zero}; use simba::scalar::{ClosedDiv, SubsetOf, SupersetOf}; use simba::simd::PrimitiveSimdValue; use crate::base::allocator::Allocator; use crate::base::dimension::{DimName, DimNameAdd, DimNameSum, U1}; use crate::base::{DefaultAllocator, Matrix, Scalar, VectorN}; #[cfg(feature = "mint")] use crate::base::dimension::{U2, U3}; #[cfg(feature = "mint")] use crate::base::storage::{Storage, StorageMut}; use crate::geometry::Point; #[cfg(feature = "mint")] use mint; #[cfg(feature = "mint")] use std::convert::{AsMut, AsRef, From, Into}; /* * This file provides the following conversions: * ============================================= * * Point -> Point * Point -> Vector (homogeneous) * * mint::Point <-> Point */ impl SubsetOf> for Point where D: DimName, N1: Scalar, N2: Scalar + SupersetOf, DefaultAllocator: Allocator + Allocator, { #[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>> for Point where D: DimNameAdd, N1: Scalar, N2: Scalar + Zero + One + ClosedDiv + SupersetOf, DefaultAllocator: Allocator + Allocator> + Allocator> + Allocator, { #[inline] fn to_superset(&self) -> VectorN> { let p: Point = self.to_superset(); p.to_homogeneous() } #[inline] fn is_in_subset(v: &VectorN>) -> bool { crate::is_convertible::<_, VectorN>>(v) && !v[D::dim()].is_zero() } #[inline] fn from_superset_unchecked(v: &VectorN>) -> Self { let coords = v.fixed_slice::(0, 0) / v[D::dim()].inlined_clone(); Self { coords: crate::convert_unchecked(coords), } } } #[cfg(feature = "mint")] macro_rules! impl_from_into_mint_1D( ($($NRows: ident => $PT:ident, $VT:ident [$SZ: expr]);* $(;)*) => {$( impl From> for Point where N: Scalar { #[inline] fn from(p: mint::$PT) -> Self { Self { coords: VectorN::from(mint::$VT::from(p)), } } } impl Into> for Point where N: Scalar { #[inline] fn into(self) -> mint::$PT { let mint_vec: mint::$VT = self.coords.into(); mint::$PT::from(mint_vec) } } impl AsRef> for Point where N: Scalar { #[inline] fn as_ref(&self) -> &mint::$PT { unsafe { &*(self.coords.data.ptr() as *const mint::$PT) } } } impl AsMut> for Point where N: Scalar { #[inline] fn as_mut(&mut self) -> &mut mint::$PT { unsafe { &mut *(self.coords.data.ptr_mut() as *mut mint::$PT) } } } )*} ); // Implement for points of dimension 2, 3. #[cfg(feature = "mint")] impl_from_into_mint_1D!( U2 => Point2, Vector2[2]; U3 => Point3, Vector3[3]; ); impl From> for VectorN> where D: DimNameAdd, DefaultAllocator: Allocator + Allocator>, { #[inline] fn from(t: Point) -> Self { t.to_homogeneous() } } impl From> for Point where DefaultAllocator: Allocator, { #[inline] fn from(coords: VectorN) -> Self { Point { coords } } } impl From<[Point; 2]> for Point where N: From<[::Element; 2]>, N::Element: Scalar + Copy, DefaultAllocator: Allocator + Allocator, >::Buffer: Copy, { #[inline] fn from(arr: [Point; 2]) -> Self { Self::from(VectorN::from([arr[0].coords, arr[1].coords])) } } impl From<[Point; 4]> for Point where N: From<[::Element; 4]>, N::Element: Scalar + Copy, DefaultAllocator: Allocator + Allocator, >::Buffer: Copy, { #[inline] fn from(arr: [Point; 4]) -> Self { Self::from(VectorN::from([ arr[0].coords, arr[1].coords, arr[2].coords, arr[3].coords, ])) } } impl From<[Point; 8]> for Point where N: From<[::Element; 8]>, N::Element: Scalar + Copy, DefaultAllocator: Allocator + Allocator, >::Buffer: Copy, { #[inline] fn from(arr: [Point; 8]) -> Self { Self::from(VectorN::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 N: From<[::Element; 16]>, N::Element: Scalar + Copy, DefaultAllocator: Allocator + Allocator, >::Buffer: Copy, { #[inline] fn from(arr: [Point; 16]) -> Self { Self::from(VectorN::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, ])) } }