#[cfg(feature = "arbitrary")] use quickcheck::{Arbitrary, Gen}; use num::{Bounded, One, Zero}; #[cfg(feature = "rand-no-std")] use rand::{ distributions::{Distribution, Standard}, Rng, }; use crate::base::allocator::Allocator; use crate::base::dimension::{DimNameAdd, DimNameSum, U1}; use crate::base::{DefaultAllocator, Scalar}; use crate::{ Const, DimName, OPoint, OVector, Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4, Vector5, Vector6, }; use simba::scalar::{ClosedDiv, SupersetOf}; use crate::geometry::Point; /// # Other construction methods impl OPoint where DefaultAllocator: Allocator, { /// Creates a new point with uninitialized coordinates. #[inline] pub unsafe fn new_uninitialized() -> Self { Self::from(crate::unimplemented_or_uninitialized_generic!( D::name(), Const::<1> )) } /// Creates a new point with all coordinates equal to zero. /// /// # Example /// /// ``` /// # use nalgebra::{Point2, Point3}; /// // This works in any dimension. /// // The explicit crate:: type annotation may not always be needed, /// // depending on the context of type inference. /// let pt = Point2::::origin(); /// assert!(pt.x == 0.0 && pt.y == 0.0); /// /// let pt = Point3::::origin(); /// assert!(pt.x == 0.0 && pt.y == 0.0 && pt.z == 0.0); /// ``` #[inline] pub fn origin() -> Self where T: Zero, { Self::from(OVector::from_element(T::zero())) } /// Creates a new point from a slice. /// /// # Example /// /// ``` /// # use nalgebra::{Point2, Point3}; /// let data = [ 1.0, 2.0, 3.0 ]; /// /// let pt = Point2::from_slice(&data[..2]); /// assert_eq!(pt, Point2::new(1.0, 2.0)); /// /// let pt = Point3::from_slice(&data); /// assert_eq!(pt, Point3::new(1.0, 2.0, 3.0)); /// ``` #[inline] pub fn from_slice(components: &[T]) -> Self { Self::from(OVector::from_row_slice(components)) } /// Creates a new point from its homogeneous vector representation. /// /// In practice, this builds a D-dimensional points with the same first D component as `v` /// divided by the last component of `v`. Returns `None` if this divisor is zero. /// /// # Example /// /// ``` /// # use nalgebra::{Point2, Point3, Vector3, Vector4}; /// /// let coords = Vector4::new(1.0, 2.0, 3.0, 1.0); /// let pt = Point3::from_homogeneous(coords); /// assert_eq!(pt, Some(Point3::new(1.0, 2.0, 3.0))); /// /// // All component of the result will be divided by the /// // last component of the vector, here 2.0. /// let coords = Vector4::new(1.0, 2.0, 3.0, 2.0); /// let pt = Point3::from_homogeneous(coords); /// assert_eq!(pt, Some(Point3::new(0.5, 1.0, 1.5))); /// /// // Fails because the last component is zero. /// let coords = Vector4::new(1.0, 2.0, 3.0, 0.0); /// let pt = Point3::from_homogeneous(coords); /// assert!(pt.is_none()); /// /// // Works also in other dimensions. /// let coords = Vector3::new(1.0, 2.0, 1.0); /// let pt = Point2::from_homogeneous(coords); /// assert_eq!(pt, Some(Point2::new(1.0, 2.0))); /// ``` #[inline] pub fn from_homogeneous(v: OVector>) -> Option where T: Scalar + Zero + One + ClosedDiv, D: DimNameAdd, DefaultAllocator: Allocator>, { if !v[D::dim()].is_zero() { let coords = v.generic_slice((0, 0), (D::name(), Const::<1>)) / v[D::dim()].inlined_clone(); Some(Self::from(coords)) } else { None } } /// Cast the components of `self` to another type. /// /// # Example /// ``` /// # use nalgebra::Point2; /// let pt = Point2::new(1.0f64, 2.0); /// let pt2 = pt.cast::(); /// assert_eq!(pt2, Point2::new(1.0f32, 2.0)); /// ``` pub fn cast(self) -> OPoint where OPoint: SupersetOf, DefaultAllocator: Allocator, { crate::convert(self) } } /* * * Traits that build points. * */ impl Bounded for OPoint where DefaultAllocator: Allocator, { #[inline] fn max_value() -> Self { Self::from(OVector::max_value()) } #[inline] fn min_value() -> Self { Self::from(OVector::min_value()) } } #[cfg(feature = "rand-no-std")] impl Distribution> for Standard where Standard: Distribution, DefaultAllocator: Allocator, { /// Generate a `Point` where each coordinate is an independent variate from `[0, 1)`. #[inline] fn sample<'a, G: Rng + ?Sized>(&self, rng: &mut G) -> OPoint { OPoint::from(rng.gen::>()) } } #[cfg(feature = "arbitrary")] impl Arbitrary for OPoint where >::Buffer: Send, DefaultAllocator: Allocator, { #[inline] fn arbitrary(g: &mut Gen) -> Self { Self::from(OVector::arbitrary(g)) } } /* * * Small points construction from components. * */ // NOTE: the impl for Point1 is not with the others so that we // can add a section with the impl block comment. /// # Construction from individual components impl Point1 { /// Initializes this point from its components. /// /// # Example /// /// ``` /// # use nalgebra::Point1; /// let p = Point1::new(1.0); /// assert_eq!(p.x, 1.0); /// ``` #[inline] pub fn new(x: T) -> Self { Point { coords: Vector1::new(x), } } } macro_rules! componentwise_constructors_impl( ($($doc: expr; $Point: ident, $Vector: ident, $($args: ident:$irow: expr),*);* $(;)*) => {$( impl $Point { #[doc = "Initializes this point from its components."] #[doc = "# Example\n```"] #[doc = $doc] #[doc = "```"] #[inline] pub fn new($($args: T),*) -> Self { Point { coords: $Vector::new($($args),*) } } } )*} ); componentwise_constructors_impl!( "# use nalgebra::Point2;\nlet p = Point2::new(1.0, 2.0);\nassert!(p.x == 1.0 && p.y == 2.0);"; Point2, Vector2, x:0, y:1; "# use nalgebra::Point3;\nlet p = Point3::new(1.0, 2.0, 3.0);\nassert!(p.x == 1.0 && p.y == 2.0 && p.z == 3.0);"; Point3, Vector3, x:0, y:1, z:2; "# use nalgebra::Point4;\nlet p = Point4::new(1.0, 2.0, 3.0, 4.0);\nassert!(p.x == 1.0 && p.y == 2.0 && p.z == 3.0 && p.w == 4.0);"; Point4, Vector4, x:0, y:1, z:2, w:3; "# use nalgebra::Point5;\nlet p = Point5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(p.x == 1.0 && p.y == 2.0 && p.z == 3.0 && p.w == 4.0 && p.a == 5.0);"; Point5, Vector5, x:0, y:1, z:2, w:3, a:4; "# use nalgebra::Point6;\nlet p = Point6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(p.x == 1.0 && p.y == 2.0 && p.z == 3.0 && p.w == 4.0 && p.a == 5.0 && p.b == 6.0);"; Point6, Vector6, x:0, y:1, z:2, w:3, a:4, b:5; );