gfx_maths/
vec2.rs

1use std::{fmt::Display, ops::Neg};
2
3use auto_ops::{impl_op_ex, impl_op_ex_commutative};
4
5use crate::Vec3;
6
7#[derive(Debug, Clone, Copy, PartialEq)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[repr(C)]
10pub struct Vec2 {
11    pub x: f32,
12    pub y: f32,
13}
14
15impl Default for Vec2 {
16    /// Creates a zero vector
17    fn default() -> Self {
18        Self::zero()
19    }
20}
21
22impl Display for Vec2 {
23    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24        let Self { x, y } = self;
25        write!(f, "({x}, {y})")
26    }
27}
28
29impl Vec2 {
30    pub const fn new(x: f32, y: f32) -> Self {
31        Self { x, y }
32    }
33
34    /// Creates (0, 0)
35    pub const fn zero() -> Self {
36        Self { x: 0.0, y: 0.0 }
37    }
38
39    /// Creates (1, 1)
40    pub const fn one() -> Self {
41        Self { x: 1.0, y: 1.0 }
42    }
43
44    /// Returns the square of the vector's length.
45    ///
46    /// Faster to compute than [`magnitude()`](Self::magnitude())
47    pub fn sqr_magnitude(&self) -> f32 {
48        self.x * self.x + self.y * self.y
49    }
50
51    /// Returns the vector's length
52    pub fn magnitude(&self) -> f32 {
53        self.sqr_magnitude().sqrt()
54    }
55
56    /// Normalizes `self` in place
57    pub fn normalize(&mut self) -> &mut Self {
58        let m = self.magnitude();
59        self.x /= m;
60        self.y /= m;
61        self
62    }
63    /// Returns a normalized copy of `self`
64    #[must_use]
65    pub fn normalized(&self) -> Self {
66        *self.clone().normalize()
67    }
68
69    /// Returns the dot product of `self` and `b`
70    pub fn dot(&self, b: Vec2) -> f32 {
71        self.x * b.x + self.y * b.y
72    }
73
74    pub fn extend(&self, z: f32) -> Vec3 {
75        Vec3 {
76            x: self.x,
77            y: self.y,
78            z,
79        }
80    }
81
82    swizzle!(x, x);
83    swizzle!(x, y);
84    swizzle!(y, x);
85    swizzle!(y, y);
86
87    swizzle!(x, x, x);
88    swizzle!(x, x, y);
89    swizzle!(x, y, x);
90    swizzle!(x, y, y);
91    swizzle!(y, x, x);
92    swizzle!(y, x, y);
93    swizzle!(y, y, x);
94    swizzle!(y, y, y);
95
96    swizzle!(x, x, x, x);
97    swizzle!(x, x, x, y);
98    swizzle!(x, x, y, x);
99    swizzle!(x, x, y, y);
100    swizzle!(x, y, x, x);
101    swizzle!(x, y, x, y);
102    swizzle!(x, y, y, x);
103    swizzle!(x, y, y, y);
104    swizzle!(y, x, x, x);
105    swizzle!(y, x, x, y);
106    swizzle!(y, x, y, x);
107    swizzle!(y, x, y, y);
108    swizzle!(y, y, x, x);
109    swizzle!(y, y, x, y);
110    swizzle!(y, y, y, x);
111    swizzle!(y, y, y, y);
112}
113
114impl_op_ex!(+= |a: &mut Vec2, b: &Vec2| { a.x += b.x; a.y += b.y; });
115impl_op_ex!(-= |a: &mut Vec2, b: &Vec2| { a.x -= b.x; a.y -= b.y; });
116impl_op_ex!(*= |a: &mut Vec2, b: &Vec2| { a.x *= b.x; a.y *= b.y; });
117impl_op_ex!(/= |a: &mut Vec2, b: &Vec2| { a.x /= b.x; a.y /= b.y; });
118
119impl_op_ex!(*= |a: &mut Vec2, b: &f32| { a.x *= b; a.y *= b });
120impl_op_ex!(/= |a: &mut Vec2, b: &f32| { a.x /= b; a.y /= b });
121
122impl_op_ex!(+ |a: &Vec2, b: &Vec2| -> Vec2 { Vec2{x: a.x + b.x, y: a.y + b.y} });
123impl_op_ex!(-|a: &Vec2, b: &Vec2| -> Vec2 {
124    Vec2 {
125        x: a.x - b.x,
126        y: a.y - b.y,
127    }
128});
129impl_op_ex!(*|a: &Vec2, b: &Vec2| -> Vec2 {
130    Vec2 {
131        x: a.x * b.x,
132        y: a.y * b.y,
133    }
134});
135impl_op_ex!(/ |a: &Vec2, b: &Vec2| -> Vec2 { Vec2{x: a.x / b.x, y: a.y / b.y} });
136
137impl_op_ex_commutative!(*|a: &Vec2, b: &f32| -> Vec2 {
138    Vec2 {
139        x: a.x * b,
140        y: a.y * b,
141    }
142});
143impl_op_ex!(/ |a: &Vec2, b: &f32| -> Vec2 { Vec2{x: a.x / b, y: a.y / b} });
144impl_op_ex!(/ |a: &f32, b: &Vec2| -> Vec2 { Vec2{x: a / b.x, y: a / b.y} });
145
146impl Neg for Vec2 {
147    type Output = Vec2;
148    fn neg(self) -> Self::Output {
149        Vec2 {
150            x: -self.x,
151            y: -self.y,
152        }
153    }
154}
155
156impl From<[f32; 2]> for Vec2 {
157    fn from(d: [f32; 2]) -> Self {
158        Self { x: d[0], y: d[1] }
159    }
160}
161
162#[cfg(test)]
163mod tests {
164    use super::*;
165
166    #[test]
167    fn operators() {
168        let a = Vec2::new(1.0, 2.0);
169        let b = Vec2::new(3.0, 4.0);
170
171        assert_eq!(-a, Vec2 { x: -1.0, y: -2.0 });
172
173        assert_eq!(a.sqr_magnitude(), 5.0);
174        assert_eq!(a.magnitude(), 5.0f32.sqrt());
175
176        assert_eq!(a.dot(b), 11.0);
177
178        assert_eq!(a + b, Vec2 { x: 4.0, y: 6.0 });
179        assert_eq!(a - b, Vec2 { x: -2.0, y: -2.0 });
180        assert_eq!(a * b, Vec2 { x: 3.0, y: 8.0 });
181        assert_eq!(
182            a / b,
183            Vec2 {
184                x: 1.0 / 3.0,
185                y: 0.5
186            }
187        );
188
189        assert_eq!(a * 2.0, Vec2 { x: 2.0, y: 4.0 });
190        assert_eq!(2.0 * a, Vec2 { x: 2.0, y: 4.0 });
191
192        assert_eq!(a / 2.0, Vec2 { x: 0.5, y: 1.0 });
193        assert_eq!(2.0 / a, Vec2 { x: 2.0, y: 1.0 });
194
195        let mut c = a;
196
197        assert_eq!(c.normalized(), a / a.magnitude());
198
199        c.normalize();
200        assert_eq!(c, a / a.magnitude());
201
202        c = a;
203        c += b;
204        assert_eq!(c, a + b);
205
206        c = a;
207        c -= b;
208        assert_eq!(c, a - b);
209
210        c = a;
211        c *= b;
212        assert_eq!(c, a * b);
213
214        c = a;
215        c /= b;
216        assert_eq!(c, a / b);
217
218        c = a;
219        c *= 2.0;
220        assert_eq!(c, a * 2.0);
221
222        c = a;
223        c /= 2.0;
224        assert_eq!(c, a / 2.0);
225    }
226}