1use std::ops;
2
3#[derive(Copy, Clone, Debug, PartialEq)]
6pub struct Vect{
7 pub x: f32,
8 pub y: f32,
9}
10
11impl Vect {
12 pub const ZERO: Self = Self { x: 0f32, y: 0f32 };
13 pub const LEFT: Self = Self { x: -1f32, y: 0f32 };
14 pub const RIGHT: Self = Self { x: 1f32, y: 0f32 };
15 pub const UP: Self = Self { x: 0f32, y: 1f32 };
16 pub const DOWN: Self = Self { x: 0f32, y: -1f32 };
17 pub const MAX: Self = Self { x: f32::MAX, y: f32::MAX };
18 pub const MIN: Self = Self { x: f32::MIN, y: f32::MIN };
19
20 #[inline]
22 pub fn average(arr: &[Vect]) -> Self {
23 let len = arr.len();
24 if len == 0 {
25 return Self::ZERO;
26 }
27
28 let mut total = Self::ZERO;
29 for vec in arr {
30 total += *vec
31 }
32
33 total / len as f32
34 }
35
36 #[inline]
38 pub fn new(x: f32, y: f32) -> Self {
39 Self { x, y }
40 }
41
42 #[inline]
44 pub fn mirror(m: f32) -> Self {
45 Self { x: m, y: m }
46 }
47
48 #[inline]
50 pub fn unit(a: f32) -> Self {
51 Self { x: a.cos(), y: a.sin() }
52 }
53
54 #[inline]
56 pub fn rad(a: f32, l: f32) -> Self {
57 Self::unit(a) * l
58 }
59
60 #[inline]
62 pub fn clamped(&self, min: f32, max: f32) -> Self {
63 Self::rad(self.ang(), clamp!(self.len(), min, max))
64 }
65
66 pub fn lerp(self, o: Vect, t: f32) -> Vect {
67 o * t + self * (1.0 - t)
68 }
69
70 #[inline]
72 pub fn ang(&self) -> f32 {
73 self.y.atan2(self.x)
74 }
75
76 #[inline]
78 pub fn len(&self) -> f32 {
79 self.x.hypot(self.y)
80 }
81
82 #[inline]
84 pub fn norm(self) -> Self {
85 let len = self.len();
86 if len == 0f32 {
87 return Self::ZERO
88 }
89 self / len
90 }
91
92 #[inline]
94 pub fn normal(&self) -> Self {
95 Self {
96 x: self.y,
97 y: -self.x,
98 }
99 }
100
101 #[inline]
103 pub fn swp(self) -> Self {
104 Self { x: self.y, y: self.x }
105 }
106
107 #[inline]
109 pub fn rot(self, a: f32) -> Self {
110 Self::rad(self.ang() + a, self.len())
111 }
112
113 #[inline]
115 pub fn dist(self, b: Self) -> f32 {
116 (self - b).len()
117 }
118
119 #[inline]
121 pub fn to(self, b: Self) -> Self {
122 b - self
123 }
124
125 #[inline]
127 pub fn dot(self, b: Self) -> f32 {
128 self.x * b.x + self.y * b.y
129 }
130
131 #[inline]
133 pub fn ang_to(self, b: Self) -> f32 {
134 let r = self.norm().dot(b.norm()).acos();
135 if r.is_nan() { 0.0 } else { r }
136 }
137
138 #[inline]
140 pub fn trn<T: Fn(f32) -> f32>(&self, tr: T) -> Self {
141 Self { x: tr(self.x), y: tr(self.y) }
142 }
143
144 #[inline]
146 pub fn inverted(&self) -> Self {
147 Self { x: -self.x, y: -self.y }
148 }
149
150 #[inline]
152 pub fn round(&self) -> Self {
153 Self { x: self.x.round(), y: self.y.round() }
154 }
155}
156
157impl ops::Add<Vect> for Vect {
158 type Output = Vect;
159 #[inline]
160 fn add(self, rhs: Vect) -> Self::Output {
161 Self::new(self.x + rhs.x, self.y + rhs.y)
162 }
163}
164
165impl ops::AddAssign<Vect> for Vect {
166 #[inline]
167 fn add_assign(&mut self, rhs: Vect) {
168 self.x += rhs.x;
169 self.y += rhs.y;
170 }
171}
172
173impl ops::Sub<Vect> for Vect {
174 type Output = Vect;
175 #[inline]
176 fn sub(self, rhs: Vect) -> Self::Output {
177 Self::new(self.x - rhs.x, self.y - rhs.y)
178 }
179}
180
181impl ops::SubAssign<Vect> for Vect {
182 #[inline]
183 fn sub_assign(&mut self, rhs: Vect) {
184 self.x -= rhs.x;
185 self.y -= rhs.y;
186 }
187}
188
189impl ops::Mul<Vect> for Vect {
190 type Output = Vect;
191 #[inline]
192 fn mul(self, rhs: Vect) -> Self::Output {
193 Self::new(self.x * rhs.x, self.y * rhs.y)
194 }
195}
196
197impl ops::MulAssign<Vect> for Vect {
198 #[inline]
199 fn mul_assign(&mut self, rhs: Vect) {
200 self.x *= rhs.x;
201 self.y *= rhs.y;
202 }
203}
204
205impl ops::Mul<f32> for Vect {
206 type Output = Vect;
207 #[inline]
208 fn mul(self, rhs: f32) -> Self::Output {
209 Self::new(self.x * rhs, self.y * rhs)
210 }
211}
212
213impl ops::MulAssign<f32> for Vect {
214 #[inline]
215 fn mul_assign(&mut self, rhs: f32) {
216 self.x *= rhs;
217 self.y *= rhs;
218 }
219}
220
221impl ops::Div<Vect> for Vect {
222 type Output = Vect;
223 #[inline]
224 fn div(self, rhs: Vect) -> Self::Output {
225 Self::new(self.x / rhs.x, self.y / rhs.y)
226 }
227}
228
229impl ops::DivAssign<Vect> for Vect {
230 #[inline]
231 fn div_assign(&mut self, rhs: Vect) {
232 self.x /= rhs.x;
233 self.y /= rhs.y;
234 }
235}
236
237impl ops::Div<f32> for Vect {
238 type Output = Vect;
239 #[inline]
240 fn div(self, rhs: f32) -> Self::Output {
241 Self::new(self.x / rhs, self.y / rhs)
242 }
243}
244
245impl ops::DivAssign<f32> for Vect {
246 #[inline]
247 fn div_assign(&mut self, rhs: f32) {
248 self.x /= rhs;
249 self.y /= rhs;
250 }
251}
252
253impl Default for Vect {
254 fn default() -> Self {
255 Vect::ZERO
256 }
257}
258
259#[cfg(test)]
260mod tests {
261 use std::f32::consts::PI;
262 use crate::math::vect::Vect;
263
264 fn round(a: f32, decimals: i32) -> f32 {
265 let mul = 10f32.powi(decimals);
266 (a * mul).round() / mul
267 }
268
269 #[test]
270 fn angle_test() {
271 assert_eq!(PI, Vect::LEFT.ang())
272 }
273 #[test]
274 fn ang_to_test() {
275 assert_eq!(PI, Vect::LEFT.ang_to(Vect::RIGHT))
276 }
277 #[test]
278 fn rot_test() {
279 assert_eq!(Vect::LEFT.x,round(Vect::RIGHT.rot(PI).x, 6));
280 assert_eq!(Vect::LEFT.y,round(Vect::RIGHT.rot(PI).y, 6));
281 }
282 #[test]
283 fn average_test() {
284 let vec = vec![Vect::LEFT, Vect::RIGHT];
285 assert_eq!(Vect::average(&vec), Vect::ZERO);
286 }
287}