devela/num/geom/shape/point/
methods.rs

1// devela::geom::shape::point::methods
2//
3//!
4//
5
6#[cfg(feature = "alg")]
7use crate::Vector;
8use crate::{Point, Point2d, Point3d};
9
10#[rustfmt::skip]
11impl<T, const D: usize> Point<T, D> {
12    /// Returns a new `Point` from the given `coords` array.
13    #[must_use]
14    pub const fn new(coords: [T; D]) -> Self {
15        Self { coords }
16    }
17
18    /// Consumes this `Point` and converts it into a `Vector`.
19    #[must_use]
20    #[cfg(feature = "alg")]
21    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alg")))]
22    pub fn into_vector(self) -> Vector<T, D> {
23        Vector::new(self.coords)
24    }
25    /// Converts this `Point` to a `Vector`, keeping `self` intact.
26    #[must_use]
27    #[cfg(feature = "alg")]
28    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alg")))]
29    pub const fn to_vector(self) -> Vector<T, D> where T: Copy {
30        Vector::new(self.coords)
31    }
32
33    /// Creates a `Point` from a `Vector`.
34    #[must_use]
35    #[cfg(feature = "alg")]
36    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alg")))]
37    pub fn from_vector(v: Vector<T, D>) -> Self {
38        Self::new(v.coords)
39    }
40    /// Creates a `Point` from a constant `Vector`.
41    #[must_use]
42    #[cfg(feature = "alg")]
43    #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alg")))]
44    pub const fn from_vector_const(v: Vector<T, D>) -> Self where T: Copy {
45        Self::new(v.coords)
46    }
47}
48
49/* manual impls for specific dimensionalities */
50
51#[rustfmt::skip]
52impl<T> Point2d<T> {
53    /// Returns a copy of the first dimension `x`.
54    #[must_use]
55    pub const fn x(self) -> T where T: Copy { self.coords[0] }
56    /// Returns a copy of the second dimension `y`.
57    #[must_use]
58    pub const fn y(self) -> T where T: Copy { self.coords[1] }
59
60    /// Returns a shared reference to the first dimension `x`.
61    #[must_use]
62    pub const fn x_ref(&self) -> &T { &self.coords[0] }
63    /// Returns a shared reference to the second dimension `y`.
64    #[must_use]
65    pub const fn y_ref(&self) -> &T { &self.coords[1] }
66
67    /// Returns an exclusive reference to the first dimension `x`.
68    #[must_use]
69    pub fn x_mut(&mut self) -> &mut T { &mut self.coords[0] }
70    /// Returns an exclusive reference to the second dimension `y`.
71    #[must_use]
72    pub fn y_mut(&mut self) -> &mut T { &mut self.coords[1] }
73}
74
75#[rustfmt::skip]
76impl<T> Point3d<T> {
77    /// Returns a copy of the first dimension `x`.
78    #[must_use]
79    pub const fn x(self) -> T where T: Copy { self.coords[0] }
80    /// Returns a copy of the second dimension `y`.
81    #[must_use]
82    pub const fn y(self) -> T where T: Copy { self.coords[1] }
83    /// Returns a copy of the third dimension `z`.
84    #[must_use]
85    pub const fn z(self) -> T where T: Copy { self.coords[2] }
86
87    /// Returns a shared reference to the first dimension `x`.
88    #[must_use]
89    pub const fn x_ref(&self) -> &T { &self.coords[0] }
90    /// Returns a shared reference to the second dimension `y`.
91    #[must_use]
92    pub const fn y_ref(&self) -> &T { &self.coords[1] }
93    /// Returns a shared reference to the third dimension `z`.
94    #[must_use]
95    pub const fn z_ref(&self) -> &T { &self.coords[2] }
96
97    /// Returns an exclusive reference to the first dimension `x`.
98    #[must_use]
99    pub fn x_mut(&mut self) -> &mut T { &mut self.coords[0] }
100    /// Returns an exclusive reference to the second dimension `y`.
101    #[must_use]
102    pub fn y_mut(&mut self) -> &mut T { &mut self.coords[1] }
103    /// Returns an exclusive reference to the third dimension `z`.
104    #[must_use]
105    pub fn z_mut(&mut self) -> &mut T { &mut self.coords[2] }
106}
107
108/// helper for implementing methods on `Point`.
109///
110/// $t: the inner integer primitive type
111/// $cap:  the capability feature that enables the given implementation. E.g "_int_i8".
112macro_rules! impl_point {
113    () => {
114        impl_point![sint i8:"_int_i8", i16:"_int_i16", i32:"_int_i32",
115            i64:"_int_i64", i128:"_int_i128", isize:"_int_isize"];
116        impl_point![uint u8:"_int_u8", u16:"_int_u16", u32:"_int_u32",
117            u64:"_int_u64", u128:"_int_u128", usize:"_int_usize"];
118        impl_point![float f32:"_float_f32", f64:"_float_f64"];
119    };
120
121    // integers common methods
122    (int $($t:ty : $cap:literal),+) => { $( impl_point![@int $t:$cap]; )+ };
123    (@int $t:ty : $cap:literal) => {
124        #[cfg(feature = $cap )]
125        #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
126        impl<const D: usize> Point<$t, D> {
127            /// Adds the given vector.
128            #[must_use]
129            #[cfg(feature = "alg")]
130            #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alg")))]
131            pub const fn c_add_vector(self, v: Vector<$t, D>) -> Self {
132                Self { coords: Vector::new(self.coords).c_add(v).coords }
133            }
134            // /// Subtracts the given vector.
135            //
136            // #[cfg(feature = "alg")]
137            // #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alg")))]
138            // pub const fn c_sub_vector(self, v: Vector<$t, D>) -> Self {
139            //     Self { coords: self.coords.c_sub(v) }
140            // }
141        }
142    };
143    (sint $($t:ty : $cap:literal),+) => { $( impl_point![@sint $t:$cap]; )+ };
144    (@sint $t:ty : $cap:literal ) => {
145        impl_point![int $t:$cap];
146
147        // #[cfg(feature = $cap )]
148        // #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
149    };
150    (uint $($t:ty : $cap:literal),+) => { $( impl_point![@uint $t:$cap]; )+ };
151    (@uint $t:ty : $cap:literal) => {
152        impl_point![int $t:$cap];
153
154        // #[cfg(feature = $cap )]
155        // #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
156    };
157
158    // $f: the inner floating-point primitive type
159    (float $( $f:ty : $cap:literal ),+) => { $( impl_point![@float $f:$cap]; )+ };
160    (@float $f:ty : $cap:literal) => {
161        #[cfg(feature = $cap )]
162        #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $cap)))]
163        impl<const D: usize> Point<$f, D> {
164            // TODO
165            //
166            // /// Adds the given vector.
167            //
168            // #[cfg(feature = "alg")]
169            // #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alg")))]
170            // pub fn add_vector(self, v: Vector<$f, D>) -> Self {
171            //     Self { coords: self.coords.add(v) }
172            // }
173            // /// Subtracts the given vector.
174            //
175            // #[cfg(feature = "alg")]
176            // #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "alg")))]
177            // pub fn sub_vector(self, v: Vector<$f, D>) -> Self {
178            //     Self { coords: self.coords.sub(v) }
179            // }
180        }
181    };
182}
183impl_point!();