1use core::{
2 fmt,
3 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
4};
5use vexide::{devices::math::Point2, float::Float};
6
7#[derive(Default, Debug, Clone, Copy, Eq, PartialEq)]
11pub struct Vec2<T> {
12 pub x: T,
14
15 pub y: T,
17}
18
19impl<T> Vec2<T> {
22 pub const fn new(x: T, y: T) -> Self {
24 Self { x, y }
25 }
26
27 pub fn set_x(&mut self, x: T) {
29 self.x = x;
30 }
31
32 pub fn set_y(&mut self, y: T) {
34 self.y = y;
35 }
36}
37
38impl<T: Copy> Vec2<T> {
39 pub const fn x(&self) -> T {
41 self.x
42 }
43
44 pub const fn y(&self) -> T {
46 self.y
47 }
48}
49
50impl<T: Float + Copy + Mul<Output = T>> Vec2<T> {
51 pub fn from_polar(r: T, theta: T) -> Self {
53 let (sin, cos) = theta.sin_cos();
54
55 Vec2 {
56 x: r * cos,
57 y: r * sin,
58 }
59 }
60}
61
62impl<T: Float + Copy> Vec2<T> {
65 pub fn angle(&self) -> T {
67 self.y.atan2(self.x)
68 }
69
70 pub fn length(&self) -> T {
72 self.x.hypot(self.y)
73 }
74}
75
76impl<T: Float + Copy + Sub<Output = T>> Vec2<T> {
77 pub fn distance(&self, other: Vec2<T>) -> T {
81 (*self - other).length()
82 }
83}
84
85impl<T: Float + Copy + Div<Output = T>> Vec2<T> {
86 #[must_use]
91 pub fn unit(&self) -> Self {
92 *self / self.length()
93 }
94}
95
96impl<T: Float + Copy + Add<Output = T> + Sub<Output = T> + Mul<Output = T>> Vec2<T> {
97 #[must_use]
99 pub fn lerp(self, other: Vec2<T>, t: T) -> Vec2<T> {
100 self + ((other - self) * t)
101 }
102
103 #[must_use]
106 pub fn rotated(&self, angle: T) -> Self {
107 let (sin, cos) = angle.sin_cos();
108
109 Self {
110 x: self.x * cos - self.y * sin,
111 y: self.x * sin + self.y * cos,
112 }
113 }
114}
115
116impl<T: Float + Copy + Mul<Output = T> + Sub<Output = T>> Vec2<T> {
117 pub fn cross(&self, other: Vec2<T>) -> T {
119 self.x * other.y - self.y * other.x
120 }
121}
122
123impl<T: Float + Copy + Mul<Output = T> + Add<Output = T>> Vec2<T> {
124 pub fn dot(&self, other: Vec2<T>) -> T {
130 self.x * other.x + self.y * other.y
131 }
132}
133
134impl<T: Float + Copy + Mul<Output = T> + Add<Output = T> + Div<Output = T>> Vec2<T> {
135 #[must_use]
137 pub fn projected(&self, onto: Vec2<T>) -> Self {
138 onto * (self.dot(onto) / onto.length().powi(2))
139 }
140}
141
142impl<T> From<(T, T)> for Vec2<T> {
145 fn from(tuple: (T, T)) -> Self {
146 Self {
147 x: tuple.0,
148 y: tuple.1,
149 }
150 }
151}
152
153impl<T> From<Point2<T>> for Vec2<T> {
154 fn from(value: Point2<T>) -> Self {
155 Self {
156 x: value.x,
157 y: value.y,
158 }
159 }
160}
161
162impl<T: fmt::Display> fmt::Display for Vec2<T> {
165 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166 write!(f, "({}, {})", self.x, self.y)
167 }
168}
169
170impl<T: Add<Output = T>> Add for Vec2<T> {
173 type Output = Self;
174
175 fn add(self, other: Vec2<T>) -> Self {
177 Self {
178 x: self.x + other.x,
179 y: self.y + other.y,
180 }
181 }
182}
183
184impl<T: Sub<Output = T>> Sub for Vec2<T> {
185 type Output = Self;
186
187 fn sub(self, other: Vec2<T>) -> Self {
189 Self {
190 x: self.x - other.x,
191 y: self.y - other.y,
192 }
193 }
194}
195
196impl<T: Mul<Output = T> + Copy> Mul<T> for Vec2<T> {
197 type Output = Self;
198
199 fn mul(self, scalar: T) -> Self {
201 Self {
202 x: self.x * scalar,
203 y: self.y * scalar,
204 }
205 }
206}
207
208impl<T: Div<Output = T> + Copy> Div<T> for Vec2<T> {
209 type Output = Self;
210
211 fn div(self, scalar: T) -> Self {
213 Self {
214 x: self.x / scalar,
215 y: self.y / scalar,
216 }
217 }
218}
219
220impl<T: Neg<Output = T>> Neg for Vec2<T> {
221 type Output = Self;
222
223 fn neg(self) -> Self {
225 Self {
226 x: -self.x,
227 y: -self.y,
228 }
229 }
230}
231
232impl<T: AddAssign> AddAssign for Vec2<T> {
233 fn add_assign(&mut self, other: Vec2<T>) {
235 self.x += other.x;
236 self.y += other.y;
237 }
238}
239
240impl<T: SubAssign> SubAssign for Vec2<T> {
241 fn sub_assign(&mut self, other: Vec2<T>) {
243 self.x -= other.x;
244 self.y -= other.y;
245 }
246}
247
248impl<T: MulAssign + Copy> MulAssign<T> for Vec2<T> {
249 fn mul_assign(&mut self, scalar: T) {
251 self.x *= scalar;
252 self.y *= scalar;
253 }
254}
255
256impl<T: DivAssign + Copy> DivAssign<T> for Vec2<T> {
257 fn div_assign(&mut self, scalar: T) {
259 self.x /= scalar;
260 self.y /= scalar;
261 }
262}