lighthouse_protocol/utils/
vec2.rs1use std::{fmt, ops::{Add, AddAssign, Neg, Sub, SubAssign}};
2
3use rand::{thread_rng, Rng};
4use serde::{Deserialize, Serialize};
5
6use super::{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> fmt::Display for Vec2<T> where T: fmt::Display {
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 write!(f, "({}, {})", self.x, self.y)
65 }
66}
67
68impl<T> Add for Vec2<T> where T: Add<Output = T> {
69 type Output = Self;
70
71 fn add(self, rhs: Vec2<T>) -> Self {
72 Self::new(self.x + rhs.x, self.y + rhs.y)
73 }
74}
75
76impl<T> Neg for Vec2<T> where T: Neg<Output = T> {
77 type Output = Self;
78
79 fn neg(self) -> Self {
80 Self::new(-self.x, -self.y)
81 }
82}
83
84impl<T> Sub for Vec2<T> where T: Sub<Output = T> {
85 type Output = Self;
86
87 fn sub(self, rhs: Vec2<T>) -> Self {
88 Self::new(self.x - rhs.x, self.y - rhs.y)
89 }
90}
91
92impl<T> AddAssign<Self> for Vec2<T> where T: AddAssign<T> {
93 fn add_assign(&mut self, rhs: Vec2<T>) {
94 self.x += rhs.x;
95 self.y += rhs.y;
96 }
97}
98
99impl<T> SubAssign<Self> for Vec2<T> where T: SubAssign<T> {
100 fn sub_assign(&mut self, rhs: Vec2<T>) {
101 self.x -= rhs.x;
102 self.y -= rhs.y;
103 }
104}
105
106pub type Pos<T> = Vec2<T>;
108
109pub type Delta<T> = Vec2<T>;