density_mesh_core/
coord.rs

1use crate::Scalar;
2use serde::{Deserialize, Serialize};
3use std::ops::{Add, Div, Mul, Neg, Sub};
4
5/// Point coordinate.
6///
7/// # Examples
8/// ```
9/// use density_mesh_core::prelude::*;
10///
11/// let a = Coord::new(0.0, 0.0);
12/// let b = Coord::new(2.0, 0.0);
13/// assert_eq!((b - a).magnitude(), 2.0);
14/// assert_eq!((b - a).sqr_magnitude(), 4.0);
15/// assert_eq!((b - a).normalized(), Coord::new(1.0, 0.0));
16/// assert_eq!((b - a).normalized().right(), Coord::new(0.0, -1.0));
17/// assert_eq!(Coord::new(1.0, 0.0).dot(Coord::new(-1.0, 0.0)), -1.0);
18/// ```
19#[derive(Debug, Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
20pub struct Coord {
21    /// X value.
22    pub x: Scalar,
23    /// Y value.
24    pub y: Scalar,
25}
26
27impl Coord {
28    /// Create new point coordinate.
29    ///
30    /// # Arguments
31    /// * `x` - X value.
32    /// * `y` - Y value.
33    #[inline]
34    pub fn new(x: Scalar, y: Scalar) -> Self {
35        Self { x, y }
36    }
37
38    /// Return squared length of the vector.
39    #[inline]
40    pub fn sqr_magnitude(self) -> Scalar {
41        self.x * self.x + self.y * self.y
42    }
43
44    /// Return length of the vector.
45    #[inline]
46    pub fn magnitude(self) -> Scalar {
47        self.sqr_magnitude().sqrt()
48    }
49
50    /// Return normalized vector (length equals to 1).
51    #[inline]
52    pub fn normalized(self) -> Self {
53        self / self.magnitude()
54    }
55
56    /// Returns dot product (cosinus of the angle between two vectors when both are normalized).
57    ///
58    /// ```plain
59    ///        self 1 other
60    ///             ^
61    ///             |
62    /// other 0 <---*---> 0 other
63    ///             |
64    ///             v
65    ///            -1
66    ///           other
67    /// ```
68    /// # Arguments
69    /// * `other` - Other vector.
70    #[inline]
71    pub fn dot(self, other: Self) -> Scalar {
72        self.x * other.x + self.y * other.y
73    }
74
75    /// Return right vector.
76    ///
77    /// ```plain
78    ///      ^
79    /// self |
80    ///      *---> right
81    /// ```
82    #[inline]
83    pub fn right(self) -> Self {
84        Self {
85            x: self.y,
86            y: -self.x,
87        }
88    }
89
90    /// Tells the side which this point occupy relative to the line.
91    ///
92    /// # Arguments
93    /// * `from` - Start point of the line.
94    /// * `to` - End point of the line.
95    ///
96    /// # Returns
97    /// - `1` - Point lay on the left of the line.
98    /// - `0` - Point lay on the line.
99    /// - `-1` - Point lay on the right of the line.
100    #[inline]
101    pub fn is_left_wrt_line(self, from: Self, to: Self) -> i8 {
102        ((to.x - from.x) * (self.y - from.y) - (self.x - from.x) * (to.y - from.y)) as i8
103    }
104}
105
106impl Add for Coord {
107    type Output = Self;
108
109    fn add(self, other: Self) -> Self {
110        Self {
111            x: self.x + other.x,
112            y: self.y + other.y,
113        }
114    }
115}
116
117impl Add<Scalar> for Coord {
118    type Output = Self;
119
120    fn add(self, other: Scalar) -> Self {
121        Self {
122            x: self.x + other,
123            y: self.y + other,
124        }
125    }
126}
127
128impl Sub for Coord {
129    type Output = Self;
130
131    fn sub(self, other: Self) -> Self {
132        Self {
133            x: self.x - other.x,
134            y: self.y - other.y,
135        }
136    }
137}
138
139impl Sub<Scalar> for Coord {
140    type Output = Self;
141
142    fn sub(self, other: Scalar) -> Self {
143        Self {
144            x: self.x - other,
145            y: self.y - other,
146        }
147    }
148}
149
150impl Mul for Coord {
151    type Output = Self;
152
153    fn mul(self, other: Self) -> Self {
154        Self {
155            x: self.x * other.x,
156            y: self.y * other.y,
157        }
158    }
159}
160
161impl Mul<Scalar> for Coord {
162    type Output = Self;
163
164    fn mul(self, other: Scalar) -> Self {
165        Self {
166            x: self.x * other,
167            y: self.y * other,
168        }
169    }
170}
171
172impl Div for Coord {
173    type Output = Self;
174
175    fn div(self, other: Self) -> Self {
176        Self {
177            x: self.x / other.x,
178            y: self.y / other.y,
179        }
180    }
181}
182
183impl Div<Scalar> for Coord {
184    type Output = Self;
185
186    fn div(self, other: Scalar) -> Self {
187        Self {
188            x: self.x / other,
189            y: self.y / other,
190        }
191    }
192}
193
194impl Neg for Coord {
195    type Output = Self;
196
197    fn neg(self) -> Self {
198        Self {
199            x: -self.x,
200            y: -self.y,
201        }
202    }
203}