lighthouse_protocol/utils/
vec2.rs1use std::{fmt, ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}};
2
3use rand::{thread_rng, Rng};
4use serde::{Deserialize, Serialize};
5
6use super::{Sqrt, Unity, Zero};
7
8#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
10pub struct Vec2<T> {
11 pub x: T,
12 pub y: T,
13}
14
15impl<T> Vec2<T> {
16 pub const fn new(x: T, y: T) -> Self {
18 Self { x, y }
19 }
20
21 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Vec2<U> {
23 Vec2 {
24 x: f(self.x),
25 y: f(self.y),
26 }
27 }
28}
29
30impl<T> Zero for Vec2<T> where T: Zero {
31 const ZERO: Self = Self::new(T::ZERO, T::ZERO);
33}
34
35impl<T> Vec2<T> where T: Zero + Unity {
36 pub const LEFT: Self = Self::new(T::NEG_ONE, T::ZERO);
38 pub const UP: Self = Self::new(T::ZERO, T::NEG_ONE);
40 pub const RIGHT: Self = Self::new(T::ONE, T::ZERO);
42 pub const DOWN: Self = Self::new(T::ZERO, T::ONE);
44
45 pub fn random_cardinal_with(rng: &mut impl Rng) -> Self {
47 match rng.gen_range(0..4) {
48 0 => Self::LEFT,
49 1 => Self::UP,
50 2 => Self::RIGHT,
51 3 => Self::DOWN,
52 _ => unreachable!(),
53 }
54 }
55
56 pub fn random_cardinal() -> Self {
58 Self::random_cardinal_with(&mut thread_rng())
59 }
60}
61
62impl<T> Vec2<T> where T: Add<Output = T> + Mul<Output = T> + Sqrt + Copy {
63 pub fn length(&self) -> T {
65 (self.x * self.x + self.y * self.y).sqrt()
66 }
67}
68
69impl<T> fmt::Display for Vec2<T> where T: fmt::Display {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 write!(f, "({}, {})", self.x, self.y)
72 }
73}
74
75impl<T> Add for Vec2<T> where T: Add<Output = T> {
76 type Output = Self;
77
78 fn add(self, rhs: Vec2<T>) -> Self {
79 Self::new(self.x + rhs.x, self.y + rhs.y)
80 }
81}
82
83impl<T> Neg for Vec2<T> where T: Neg<Output = T> {
84 type Output = Self;
85
86 fn neg(self) -> Self {
87 Self::new(-self.x, -self.y)
88 }
89}
90
91impl<T> Sub for Vec2<T> where T: Sub<Output = T> {
92 type Output = Self;
93
94 fn sub(self, rhs: Vec2<T>) -> Self {
95 Self::new(self.x - rhs.x, self.y - rhs.y)
96 }
97}
98
99impl<T> AddAssign<Self> for Vec2<T> where T: AddAssign<T> {
100 fn add_assign(&mut self, rhs: Vec2<T>) {
101 self.x += rhs.x;
102 self.y += rhs.y;
103 }
104}
105
106impl<T> SubAssign<Self> for Vec2<T> where T: SubAssign<T> {
107 fn sub_assign(&mut self, rhs: Vec2<T>) {
108 self.x -= rhs.x;
109 self.y -= rhs.y;
110 }
111}
112
113pub type Pos<T> = Vec2<T>;
115
116pub type Delta<T> = Vec2<T>;