1use crate::Axis;
2use core::convert::TryInto;
3use core::ops::*;
4use num_traits::float::FloatCore;
5use num_traits::Zero;
6#[cfg(feature="serde")]
7use serde::{Deserialize, Serialize};
8
9#[inline(always)]
11pub const fn vec2<N>(x: N, y: N) -> Vec2<N> {
12 Vec2 { x, y }
13}
14
15#[inline(always)]
17pub fn vec2same<N: Copy>(a: N) -> Vec2<N> {
18 Vec2 { x: a, y: a }
19}
20
21#[derive(Default, Copy, Clone, Debug, PartialEq, Eq, Hash)]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24#[must_use]
25pub struct Vec2<N> {
26 pub x: N,
27 pub y: N,
28}
29
30impl<N> AsRef<[N; 2]> for Vec2<N> {
31 #[inline(always)]
32 fn as_ref(&self) -> &[N; 2] {
33 unsafe { &*(self as *const _ as *const _) }
34 }
35}
36
37impl<N> AsMut<[N; 2]> for Vec2<N> {
38 #[inline(always)]
39 fn as_mut(&mut self) -> &mut [N; 2] {
40 unsafe { &mut *(self as *mut _ as *mut _) }
41 }
42}
43
44#[inline(always)]
45pub fn absdiff<T>(x: T, y: T) -> T
46where
47 T: Sub<Output = T> + PartialOrd,
48{
49 if x < y {
50 y - x
51 } else {
52 x - y
53 }
54}
55
56fn gen_abs<S: Neg<Output = S> + PartialOrd + Zero>(num: S) -> S {
57 if num < S::zero() {
58 -num
59 } else {
60 num
61 }
62}
63impl<S: Copy + Neg<Output = S> + PartialOrd + Zero> Vec2<S> {
64 #[inline(always)]
65 pub fn abs(&self) -> Vec2<S> {
66 vec2(gen_abs(self.x), gen_abs(self.y))
67 }
68 #[inline(always)]
69 pub fn rotate_90deg_right(&self) -> Vec2<S> {
70 vec2(-self.y, self.x)
71 }
72 #[inline(always)]
73 pub fn rotate_90deg_left(&self) -> Vec2<S> {
74 vec2(self.y, self.x)
75 }
76
77 #[inline(always)]
78 pub fn split_into_components(&self) -> [Vec2<S>; 2] {
79 [vec2(self.x, S::zero()), vec2(S::zero(), self.y)]
80 }
81}
82
83impl<S: Add<Output = S> + Sub<Output = S> + PartialOrd + Copy> Vec2<S> {
84 #[inline(always)]
85 pub fn manhattan_dis(&self, other: Vec2<S>) -> S {
86 absdiff(self.x, other.x) + absdiff(self.y, other.y)
87 }
88}
89
90impl<
91 T: Copy
92 + PartialOrd
93 + core::ops::Sub<Output = T>
94 + core::ops::Mul<Output = T>
95 + core::ops::Add<Output = T>,
96 > Vec2<T>
97{
98 #[inline(always)]
101 #[must_use]
102 pub fn distance_squared_to_point(&self, point: Vec2<T>) -> T {
103 (point.x - self.x) * (point.x - self.x) + (point.y - self.y) * (point.y - self.y)
104 }
105}
106
107#[test]
108fn test_rotate() {
109 let b = vec2(1, 1).rotate_90deg_right();
110 assert_eq!(b, vec2(-1, 1));
111
112 let b = vec2(1, 0).rotate_90deg_right();
113 assert_eq!(b, vec2(0, 1));
114}
115
116impl<S: Mul<Output = S> + Div<Output = S> + Add<Output = S> + Copy> Vec2<S> {
117 #[inline(always)]
118 pub fn scale(&self, other: Vec2<S>) -> Vec2<S> {
119 vec2(self.x * other.x, self.y * other.y)
120 }
121
122 #[inline(always)]
123 pub fn inv_scale(&self, other: Vec2<S>) -> Vec2<S> {
124 vec2(self.x / other.x, self.y / other.y)
125 }
126
127 #[inline(always)]
128 #[must_use]
129 pub fn magnitude2(&self) -> S {
130 self.x * self.x + self.y * self.y
131 }
132 #[inline(always)]
133 #[must_use]
134 pub fn dot(&self, other: Vec2<S>) -> S {
135 self.x * other.x + self.y * other.y
136 }
137}
138impl<S: FloatCore> Vec2<S> {
139 #[inline(always)]
140 pub fn is_nan(&self) -> bool {
141 self.x.is_nan() || self.y.is_nan()
142 }
143}
144
145#[cfg(feature = "std")]
146impl<S: num_traits::Float> Vec2<S> {
147 #[inline(always)]
148 pub fn truncate_at(&self, mag: S) -> Vec2<S> {
149 if self.magnitude() > mag {
150 self.normalize_to(mag)
151 } else {
152 *self
153 }
154 }
155
156 #[inline(always)]
157 pub fn normalize_to(&self, mag: S) -> Vec2<S> {
158 let l = self.magnitude2().sqrt();
159 (*self) * (mag / l)
160 }
161
162 #[inline(always)]
163 pub fn magnitude(&self) -> S {
164 self.magnitude2().sqrt()
165 }
166}
167
168#[must_use]
170pub fn arr2_as<B: 'static + Copy, A: num_traits::AsPrimitive<B>>(a: [A; 2]) -> [B; 2] {
171 let [a, b] = a;
172 [a.as_(), b.as_()]
173}
174
175impl<T> Vec2<T> {
176 #[inline(always)]
177 pub fn inner_as<B: 'static + Copy>(self) -> Vec2<B>
178 where
179 T: num_traits::AsPrimitive<B>,
180 {
181 vec2(self.x.as_(), self.y.as_())
182 }
183}
184
185impl<'a, B: Copy> From<&'a [B; 2]> for Vec2<B> {
186 fn from(a: &'a [B; 2]) -> Self {
187 let [a, b] = *a;
188 vec2(a, b)
189 }
190}
191
192impl<B> From<[B; 2]> for Vec2<B> {
193 fn from(a: [B; 2]) -> Self {
194 let [a, b] = a;
195 vec2(a, b)
196 }
197}
198
199impl<B> From<Vec2<B>> for [B; 2] {
200 fn from(a: Vec2<B>) -> Self {
201 [a.x, a.y]
202 }
203}
204
205impl<'a, B> From<&'a Vec2<B>> for &'a [B; 2] {
206 fn from(a: &'a Vec2<B>) -> Self {
207 a.as_ref()
208 }
209}
210
211impl<B> Vec2<B> {
212 #[inline(always)]
214 #[must_use]
215 pub fn get_axis(&self, axis: impl Axis) -> &B {
216 if axis.is_xaxis() {
217 &self.x
218 } else {
219 &self.y
220 }
221 }
222
223 #[inline(always)]
225 #[must_use]
226 pub fn get_axis_mut(&mut self, axis: impl Axis) -> &mut B {
227 if axis.is_xaxis() {
228 &mut self.x
229 } else {
230 &mut self.y
231 }
232 }
233
234 #[inline(always)]
235 pub fn inner_into<A>(self) -> Vec2<A>
236 where
237 B: Into<A>,
238 {
239 let x = self.x.into();
240 let y = self.y.into();
241 vec2(x, y)
242 }
243
244 #[inline(always)]
245 pub fn inner_try_into<A>(self) -> Result<Vec2<A>, B::Error>
246 where
247 B: TryInto<A>,
248 {
249 let x = self.x.try_into();
250 let y = self.y.try_into();
251 match (x, y) {
252 (Ok(x), Ok(y)) => Ok(vec2(x, y)),
253 (Ok(_), Err(e)) => Err(e),
254 (Err(e), Ok(_)) => Err(e),
255 (Err(e), Err(_)) => Err(e),
256 }
257 }
258}
259
260impl<S: Add<Output = S> + Copy> Add<Self> for Vec2<S> {
261 type Output = Self;
262 #[inline(always)]
263 fn add(self, rhs: Self) -> Self {
264 vec2(self.x + rhs.x, self.y + rhs.y)
265 }
266}
267
268impl<S: Sub<Output = S> + Copy> Sub<Self> for Vec2<S> {
269 type Output = Self;
270 #[inline(always)]
271 fn sub(self, rhs: Self) -> Self {
272 vec2(self.x - rhs.x, self.y - rhs.y)
273 }
274}
275
276impl<S: Mul<Output = S> + Copy> Mul<S> for Vec2<S> {
277 type Output = Self;
278 #[inline(always)]
279 fn mul(self, rhs: S) -> Self {
280 vec2(self.x * rhs, self.y * rhs)
281 }
282}
283
284impl<S: Div<Output = S> + Copy> Div<S> for Vec2<S> {
285 type Output = Self;
286 #[inline(always)]
287 fn div(self, rhs: S) -> Self {
288 vec2(self.x / rhs, self.y / rhs)
289 }
290}
291
292impl<S: DivAssign<S> + Copy> DivAssign<S> for Vec2<S> {
293 #[inline(always)]
294 fn div_assign(&mut self, scalar: S) {
295 self.x /= scalar;
296 self.y /= scalar;
297 }
298}
299impl<S: MulAssign<S> + Copy> MulAssign<S> for Vec2<S> {
300 #[inline(always)]
301 fn mul_assign(&mut self, scalar: S) {
302 self.x *= scalar;
303 self.y *= scalar;
304 }
305}
306
307impl<S: AddAssign<S> + Copy> AddAssign<Self> for Vec2<S> {
308 #[inline(always)]
309 fn add_assign(&mut self, rhs: Self) {
310 self.x += rhs.x;
311 self.y += rhs.y;
312 }
313}
314impl<S: SubAssign<S> + Copy> SubAssign<Self> for Vec2<S> {
315 #[inline(always)]
316 fn sub_assign(&mut self, rhs: Self) {
317 self.x -= rhs.x;
318 self.y -= rhs.y;
319 }
320}
321
322impl<S: Neg<Output = S>> Neg for Vec2<S> {
323 type Output = Vec2<S>;
324
325 #[inline]
326 fn neg(self) -> Vec2<S> {
327 vec2(-self.x, -self.y)
328 }
329}
330
331impl<S: Zero + Eq + Copy> Zero for Vec2<S> {
332 #[inline(always)]
333 fn zero() -> Vec2<S> {
334 vec2(S::zero(), S::zero())
335 }
336
337 #[inline(always)]
338 #[must_use]
339 fn is_zero(&self) -> bool {
340 *self == Vec2::zero()
341 }
342}