bottomless_pit/
vectors.rs

1//! Generic implmentation of 2D Vectors
2use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
3
4use winit::dpi::Size;
5
6/// A generic representation of 2D data
7#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
8pub struct Vec2<T> {
9    pub x: T,
10    pub y: T,
11}
12
13impl<T> Vec2<T> {
14    pub fn new(x: T, y: T) -> Self {
15        Self { x, y }
16    }
17
18    pub fn to_raw(self) -> [T; 2] {
19        [self.x, self.y]
20    }
21}
22
23#[macro_export]
24macro_rules! vec2 {
25    ($x:expr, $y:expr) => {
26        Vec2 { x: $x, y: $y }
27    };
28
29    ($x:expr) => {
30        Vec2 { x: $x, y: $x }
31    };
32}
33
34macro_rules! from_vec2_impl {
35    ($type_one:ident, $type_two:ident) => {
36        impl From<Vec2<$type_two>> for Vec2<$type_one> {
37            fn from(value: Vec2<$type_two>) -> Self {
38                Vec2 {
39                    x: $type_one::from(value.x),
40                    y: $type_one::from(value.y),
41                }
42            }
43        }
44    };
45}
46
47from_vec2_impl!(i128, i8);
48from_vec2_impl!(i128, i16);
49from_vec2_impl!(i128, i32);
50from_vec2_impl!(i128, i64);
51from_vec2_impl!(i128, u8);
52from_vec2_impl!(i128, u16);
53from_vec2_impl!(i128, u32);
54from_vec2_impl!(i128, u64);
55from_vec2_impl!(i64, i8);
56from_vec2_impl!(i64, i16);
57from_vec2_impl!(i64, i32);
58from_vec2_impl!(i64, u8);
59from_vec2_impl!(i64, u16);
60from_vec2_impl!(i64, u32);
61from_vec2_impl!(i32, i8);
62from_vec2_impl!(i32, i16);
63from_vec2_impl!(i32, u8);
64from_vec2_impl!(i32, u16);
65from_vec2_impl!(i16, i8);
66from_vec2_impl!(i16, u8);
67from_vec2_impl!(u128, u8);
68from_vec2_impl!(u128, u16);
69from_vec2_impl!(u128, u32);
70from_vec2_impl!(u128, u64);
71from_vec2_impl!(u64, u8);
72from_vec2_impl!(u64, u16);
73from_vec2_impl!(u64, u32);
74from_vec2_impl!(u32, u8);
75from_vec2_impl!(u32, u16);
76from_vec2_impl!(u16, u8);
77from_vec2_impl!(f64, f32);
78from_vec2_impl!(f64, i32);
79from_vec2_impl!(f64, i16);
80from_vec2_impl!(f64, i8);
81from_vec2_impl!(f64, u32);
82from_vec2_impl!(f64, u16);
83from_vec2_impl!(f64, u8);
84from_vec2_impl!(f32, i16);
85from_vec2_impl!(f32, i8);
86from_vec2_impl!(f32, u16);
87from_vec2_impl!(f32, u8);
88
89impl<T: Mul<Output = T> + Copy> Vec2<T> {
90    pub fn scale(self, number: T) -> Vec2<T> {
91        Vec2 {
92            x: self.x * number,
93            y: self.y * number,
94        }
95    }
96}
97
98impl<T> From<Vec2<T>> for (T, T) {
99    fn from(value: Vec2<T>) -> Self {
100        (value.x, value.y)
101    }
102}
103
104impl From<Vec2<u32>> for glyphon::Resolution {
105    fn from(value: Vec2<u32>) -> Self {
106        Self {
107            width: value.x,
108            height: value.y,
109        }
110    }
111}
112
113impl From<Size> for Vec2<u32> {
114    fn from(value: Size) -> Self {
115        match value {
116            Size::Physical(s) => vec2!(s.width, s.height),
117            Size::Logical(s) => vec2!(s.width as u32, s.height as u32),
118        }
119    }
120}
121
122impl<T> From<(T, T)> for Vec2<T> {
123    fn from(value: (T, T)) -> Self {
124        Vec2 {
125            x: value.0,
126            y: value.1,
127        }
128    }
129}
130
131impl<T> From<winit::dpi::PhysicalSize<T>> for Vec2<T> {
132    fn from(value: winit::dpi::PhysicalSize<T>) -> Self {
133        Vec2 {
134            x: value.width,
135            y: value.height,
136        }
137    }
138}
139
140impl From<glam::Vec2> for Vec2<f32> {
141    fn from(value: glam::Vec2) -> Self {
142        Self {
143            x: value.x,
144            y: value.y,
145        }
146    }
147}
148
149impl From<Vec2<f32>> for glam::Vec2 {
150    fn from(val: Vec2<f32>) -> Self {
151        Self { x: val.x, y: val.y }
152    }
153}
154
155impl<T: Add<Output = T>> Add for Vec2<T> {
156    type Output = Vec2<T>;
157    fn add(self, rhs: Self) -> Self::Output {
158        Self {
159            x: self.x + rhs.x,
160            y: self.y + rhs.y,
161        }
162    }
163}
164
165impl<T: Sub<Output = T>> Sub for Vec2<T> {
166    type Output = Vec2<T>;
167    fn sub(self, rhs: Self) -> Self::Output {
168        Self {
169            x: self.x - rhs.x,
170            y: self.y - rhs.y,
171        }
172    }
173}
174
175impl<T: AddAssign> AddAssign for Vec2<T> {
176    fn add_assign(&mut self, rhs: Self) {
177        self.x += rhs.x;
178        self.y += rhs.y;
179    }
180}
181
182impl<T: SubAssign> SubAssign for Vec2<T> {
183    fn sub_assign(&mut self, rhs: Self) {
184        self.x -= rhs.x;
185        self.y -= rhs.y;
186    }
187}