galileo_types/cartesian/impls/
mod.rs

1use approx::AbsDiffEq;
2use nalgebra::Scalar;
3use num_traits::{Bounded, FromPrimitive};
4use serde::{Deserialize, Serialize};
5
6use super::Size;
7use crate::cartesian::traits::{
8    CartesianPoint2d, CartesianPoint3d, NewCartesianPoint2d, NewCartesianPoint3d,
9};
10use crate::geo::Projection;
11use crate::geometry::{Geom, Geometry};
12use crate::geometry_type::{CartesianSpace2d, GeometryType, PointGeometryType};
13
14/// A point in 2-dimensional cartesian coordinate space.
15#[derive(Debug, Default, Copy, Clone, PartialEq, Hash, Serialize, Deserialize)]
16pub struct Point2<Num = f64> {
17    x: Num,
18    y: Num,
19}
20
21impl<Num> Point2<Num> {
22    /// Creates a new point with the given coordinates.
23    pub const fn new(x: Num, y: Num) -> Self {
24        Self { x, y }
25    }
26
27    /// Returns coordinates of the point as an array of `Num`.
28    pub fn coords(&self) -> [Num; 2]
29    where
30        Num: Copy,
31    {
32        [self.x, self.y]
33    }
34}
35
36/// Vector between two points in 2-dimensional cartesian coordinate space.
37#[derive(Debug, Default, Copy, Clone, PartialEq, Hash, Serialize, Deserialize)]
38pub struct Vector2<Num = f64> {
39    dx: Num,
40    dy: Num,
41}
42
43impl<Num: Copy> Vector2<Num> {
44    /// Creates a new vector with the given coordinates.
45    pub fn new(dx: Num, dy: Num) -> Self {
46        Self { dx, dy }
47    }
48
49    /// Returns x coordinate of the vector.
50    pub fn dx(&self) -> Num {
51        self.dx
52    }
53
54    /// Returns y coordinate of the vector.
55    pub fn dy(&self) -> Num {
56        self.dy
57    }
58
59    /// Updates x coordinate of the vector.
60    pub fn set_dx(&mut self, dx: Num) {
61        self.dx = dx;
62    }
63
64    /// Updates y coordinate of the vector.
65    pub fn set_dy(&mut self, dy: Num) {
66        self.dy = dy;
67    }
68
69    /// Returns squared magnitude (squared length) of the vector.
70    pub fn magnitude_sq(&self) -> Num
71    where
72        Num: num_traits::Num,
73    {
74        self.dx * self.dx + self.dy * self.dy
75    }
76
77    /// Returns magnitude (length) of the vector.
78    pub fn magnitude(&self) -> Num
79    where
80        Num: num_traits::Float,
81    {
82        self.magnitude_sq().sqrt()
83    }
84}
85
86impl<Num> std::ops::Sub<Point2<Num>> for Point2<Num>
87where
88    Num: std::ops::Sub<Num, Output = Num>,
89{
90    type Output = Vector2<Num>;
91
92    fn sub(self, rhs: Point2<Num>) -> Self::Output {
93        Vector2 {
94            dx: self.x - rhs.x,
95            dy: self.y - rhs.y,
96        }
97    }
98}
99
100impl<Num> std::ops::Add<Vector2<Num>> for Point2<Num>
101where
102    Num: std::ops::Add<Num, Output = Num>,
103{
104    type Output = Point2<Num>;
105
106    fn add(self, rhs: Vector2<Num>) -> Self::Output {
107        Self {
108            x: self.x + rhs.dx,
109            y: self.y + rhs.dy,
110        }
111    }
112}
113
114impl<Num> std::ops::Sub<Vector2<Num>> for Point2<Num>
115where
116    Num: std::ops::Sub<Num, Output = Num>,
117{
118    type Output = Point2<Num>;
119
120    fn sub(self, rhs: Vector2<Num>) -> Self::Output {
121        Self {
122            x: self.x - rhs.dx,
123            y: self.y - rhs.dy,
124        }
125    }
126}
127
128impl<Num> std::ops::Mul<Num> for Vector2<Num>
129where
130    Num: std::ops::Mul<Num, Output = Num> + Copy,
131{
132    type Output = Vector2<Num>;
133
134    fn mul(self, rhs: Num) -> Self::Output {
135        Self {
136            dx: self.dx * rhs,
137            dy: self.dy * rhs,
138        }
139    }
140}
141
142impl<Num> std::ops::Mul<Size<Num>> for Vector2<Num>
143where
144    Num: num_traits::Num + Copy,
145{
146    type Output = Vector2<Num>;
147
148    fn mul(self, rhs: Size<Num>) -> Self::Output {
149        Self {
150            dx: self.dx * rhs.width(),
151            dy: self.dy * rhs.height(),
152        }
153    }
154}
155
156impl<Num> AbsDiffEq for Point2<Num>
157where
158    Num: AbsDiffEq<Num, Epsilon = Num> + Copy,
159{
160    type Epsilon = Num;
161
162    fn default_epsilon() -> Self::Epsilon {
163        Num::default_epsilon()
164    }
165
166    fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
167        self.x.abs_diff_eq(&other.x, epsilon) && self.y.abs_diff_eq(&other.y, epsilon)
168    }
169}
170
171/// A point in 3-dimensional cartesian coordinate space.
172#[derive(Debug, Default, Copy, Clone, PartialEq, Hash, Serialize, Deserialize)]
173pub struct Point3<Num = f64> {
174    x: Num,
175    y: Num,
176    z: Num,
177}
178
179impl<Num> Point3<Num> {
180    /// Creates a new instance of the point by its coordinates.
181    pub const fn new(x: Num, y: Num, z: Num) -> Self {
182        Self { x, y, z }
183    }
184}
185
186/// Vector between two points in 3-dimensional cartesian coordinate space.
187#[derive(Debug, Default, Copy, Clone, PartialEq, Hash, Serialize, Deserialize)]
188pub struct Vector3<Num = f64> {
189    dx: Num,
190    dy: Num,
191    dz: Num,
192}
193
194impl<Num: Copy> Vector3<Num> {
195    /// Creates a new vector with the given coordinates.
196    pub fn new(dx: Num, dy: Num, dz: Num) -> Self {
197        Self { dx, dy, dz }
198    }
199
200    /// Returns x coordinate of the vector.
201    pub fn dx(&self) -> Num {
202        self.dx
203    }
204
205    /// Returns y coordinate of the vector.
206    pub fn dy(&self) -> Num {
207        self.dy
208    }
209
210    /// Returns z coordinate of the vector.
211    pub fn dz(&self) -> Num {
212        self.dz
213    }
214
215    /// Updates x coordinate of the vector.
216    pub fn set_dx(&mut self, dx: Num) {
217        self.dx = dx;
218    }
219
220    /// Updates y coordinate of the vector.
221    pub fn set_dy(&mut self, dy: Num) {
222        self.dy = dy;
223    }
224
225    /// Updates z coordinate of the vector.
226    pub fn set_dz(&mut self, dz: Num) {
227        self.dz = dz;
228    }
229}
230
231impl<Num> std::ops::Sub<Point3<Num>> for Point3<Num>
232where
233    Num: std::ops::Sub<Num, Output = Num>,
234{
235    type Output = Vector3<Num>;
236
237    fn sub(self, rhs: Point3<Num>) -> Self::Output {
238        Vector3 {
239            dx: self.x - rhs.x,
240            dy: self.y - rhs.y,
241            dz: self.z - rhs.z,
242        }
243    }
244}
245
246impl<Num> std::ops::Add<Vector3<Num>> for Point3<Num>
247where
248    Num: std::ops::Add<Num, Output = Num>,
249{
250    type Output = Point3<Num>;
251
252    fn add(self, rhs: Vector3<Num>) -> Self::Output {
253        Self {
254            x: self.x + rhs.dx,
255            y: self.y + rhs.dy,
256            z: self.z + rhs.dz,
257        }
258    }
259}
260
261impl<Num> std::ops::Sub<Vector3<Num>> for Point3<Num>
262where
263    Num: std::ops::Sub<Num, Output = Num>,
264{
265    type Output = Point3<Num>;
266
267    fn sub(self, rhs: Vector3<Num>) -> Self::Output {
268        Self {
269            x: self.x - rhs.dx,
270            y: self.y - rhs.dy,
271            z: self.z - rhs.dz,
272        }
273    }
274}
275
276impl<Num> std::ops::Mul<Num> for Vector3<Num>
277where
278    Num: std::ops::Mul<Num, Output = Num> + Copy,
279{
280    type Output = Vector3<Num>;
281
282    fn mul(self, rhs: Num) -> Self::Output {
283        Self {
284            dx: self.dx * rhs,
285            dy: self.dy * rhs,
286            dz: self.dz * rhs,
287        }
288    }
289}
290
291impl<Num: num_traits::Num + Copy + PartialOrd + Bounded + Scalar + FromPrimitive> CartesianPoint2d
292    for Point2<Num>
293{
294    type Num = Num;
295
296    fn x(&self) -> Num {
297        self.x
298    }
299    fn y(&self) -> Num {
300        self.y
301    }
302}
303
304impl<Num: num_traits::Num + Copy + PartialOrd + Bounded + Scalar + FromPrimitive>
305    NewCartesianPoint2d<Num> for Point2<Num>
306{
307    fn new(x: Num, y: Num) -> Self {
308        Point2 { x, y }
309    }
310}
311
312impl<Num: Scalar + Copy> CartesianPoint3d for Point3<Num> {
313    type Num = Num;
314
315    fn x(&self) -> Self::Num {
316        self.x
317    }
318
319    fn y(&self) -> Self::Num {
320        self.y
321    }
322
323    fn z(&self) -> Self::Num {
324        self.z
325    }
326}
327
328impl<Num: Scalar + Copy> NewCartesianPoint3d<Num> for Point3<Num> {
329    fn new(x: Num, y: Num, z: Num) -> Self {
330        Point3 { x, y, z }
331    }
332}
333
334impl<Num: Scalar> GeometryType for Point2<Num> {
335    type Type = PointGeometryType;
336    type Space = CartesianSpace2d;
337}
338
339impl<Num: Scalar> Geometry for Point3<Num> {
340    type Point = Point3<Num>;
341
342    fn project<P: Projection<InPoint = Self::Point> + ?Sized>(
343        &self,
344        projection: &P,
345    ) -> Option<Geom<P::OutPoint>> {
346        Some(Geom::Point(projection.project(self)?))
347    }
348}