Skip to main content

ginger/
vector2_ref.rs

1#![allow(dead_code)]
2
3/// A reference-based 2D vector implementation that holds mutable references to f64 values.
4///
5/// This structure provides mathematical operations on 2D vectors using mutable references
6/// to external f64 values rather than owning the values directly.
7pub struct Vector2Ref<'a> {
8    /// Mutable reference to the x component
9    pub x: &'a mut f64,
10    /// Mutable reference to the y component
11    pub y: &'a mut f64,
12}
13
14impl<'a> Vector2Ref<'a> {
15    /// Creates a new Vector2Ref from mutable references to two f64 values.
16    ///
17    /// # Arguments
18    ///
19    /// * `x` - A mutable reference to the x component
20    /// * `y` - A mutable reference to the y component
21    ///
22    /// # Examples
23    ///
24    /// ```
25    /// use ginger::vector2_ref::Vector2Ref;
26    ///
27    /// let mut x_val = 1.0;
28    /// let mut y_val = 2.0;
29    ///
30    /// let mut v = Vector2Ref::new(&mut x_val, &mut y_val);
31    /// ```
32    pub fn new(x: &'a mut f64, y: &'a mut f64) -> Self {
33        Vector2Ref { x, y }
34    }
35
36    /// Computes the dot product of this vector with another vector.
37    ///
38    /// $$\vec{a} \cdot \vec{b} = a_x b_x + a_y b_y$$
39    ///
40    /// # Arguments
41    ///
42    /// * `other` - Another Vector2Ref to compute the dot product with
43    ///
44    /// # Examples
45    ///
46    /// ```
47    /// use ginger::vector2_ref::Vector2Ref;
48    ///
49    /// let mut x1 = 1.0;
50    /// let mut y1 = 2.0;
51    /// let mut x2 = 3.0;
52    /// let mut y2 = 4.0;
53    ///
54    /// let v1 = Vector2Ref::new(&mut x1, &mut y1);
55    /// let v2 = Vector2Ref::new(&mut x2, &mut y2);
56    /// let result = v1.dot(&v2);
57    ///
58    /// assert_eq!(result, 11.0); // 1*3 + 2*4 = 11
59    /// ```
60    pub fn dot(&self, other: &Vector2Ref) -> f64 {
61        *self.x * *other.x + *self.y * *other.y
62    }
63
64    /// Computes the cross product of this vector with another vector.
65    ///
66    /// $$\vec{a} \times \vec{b} = a_x b_y - a_y b_x$$
67    ///
68    /// # Arguments
69    ///
70    /// * `other` - Another Vector2Ref to compute the cross product with
71    ///
72    /// # Examples
73    ///
74    /// ```
75    /// use ginger::vector2_ref::Vector2Ref;
76    ///
77    /// let mut x1 = 1.0;
78    /// let mut y1 = 2.0;
79    /// let mut x2 = 3.0;
80    /// let mut y2 = 4.0;
81    ///
82    /// let v1 = Vector2Ref::new(&mut x1, &mut y1);
83    /// let v2 = Vector2Ref::new(&mut x2, &mut y2);
84    /// let result = v1.cross(&v2);
85    ///
86    /// assert_eq!(result, -2.0); // 1*4 - 3*2 = -2
87    /// ```
88    pub fn cross(&self, other: &Vector2Ref) -> f64 {
89        *self.x * *other.y - *other.x * *self.y
90    }
91
92    /// Adds another vector to this vector in-place.
93    ///
94    /// $$\vec{a} \mathrel{+}= \vec{b} \implies (a_x + b_x,\; a_y + b_y)$$
95    ///
96    /// # Arguments
97    ///
98    /// * `other` - Another Vector2Ref to add to this vector
99    ///
100    /// # Examples
101    ///
102    /// ```
103    /// use ginger::vector2_ref::Vector2Ref;
104    ///
105    /// let mut x1 = 1.0;
106    /// let mut y1 = 2.0;
107    /// let mut x2 = 3.0;
108    /// let mut y2 = 4.0;
109    ///
110    /// let mut v1 = Vector2Ref::new(&mut x1, &mut y1);
111    /// let v2 = Vector2Ref::new(&mut x2, &mut y2);
112    /// v1.add_assign(&v2);
113    ///
114    /// assert_eq!(*v1.x, 4.0); // 1 + 3 = 4
115    /// assert_eq!(*v1.y, 6.0); // 2 + 4 = 6
116    /// ```
117    pub fn add_assign(&mut self, other: &Vector2Ref) {
118        *self.x += *other.x;
119        *self.y += *other.y;
120    }
121
122    /// Subtracts another vector from this vector in-place.
123    ///
124    /// $$\vec{a} \mathrel{-}= \vec{b} \implies (a_x - b_x,\; a_y - b_y)$$
125    ///
126    /// # Arguments
127    ///
128    /// * `other` - Another Vector2Ref to subtract from this vector
129    ///
130    /// # Examples
131    ///
132    /// ```
133    /// use ginger::vector2_ref::Vector2Ref;
134    ///
135    /// let mut x1 = 5.0;
136    /// let mut y1 = 6.0;
137    /// let mut x2 = 3.0;
138    /// let mut y2 = 4.0;
139    ///
140    /// let mut v1 = Vector2Ref::new(&mut x1, &mut y1);
141    /// let v2 = Vector2Ref::new(&mut x2, &mut y2);
142    /// v1.sub_assign(&v2);
143    ///
144    /// assert_eq!(*v1.x, 2.0); // 5 - 3 = 2
145    /// assert_eq!(*v1.y, 2.0); // 6 - 4 = 2
146    /// ```
147    pub fn sub_assign(&mut self, other: &Vector2Ref) {
148        *self.x -= *other.x;
149        *self.y -= *other.y;
150    }
151
152    /// Scales this vector by a scalar value in-place.
153    ///
154    /// $$\vec{v} \mathrel{*}= \alpha \implies (v_x \cdot \alpha,\; v_y \cdot \alpha)$$
155    ///
156    /// # Arguments
157    ///
158    /// * `alpha` - The scalar value to multiply the vector by
159    ///
160    /// # Examples
161    ///
162    /// ```
163    /// use ginger::vector2_ref::Vector2Ref;
164    ///
165    /// let mut x = 2.0;
166    /// let mut y = 3.0;
167    ///
168    /// let mut v = Vector2Ref::new(&mut x, &mut y);
169    /// v.mul_assign(2.0);
170    ///
171    /// assert_eq!(*v.x, 4.0); // 2 * 2 = 4
172    /// assert_eq!(*v.y, 6.0); // 3 * 2 = 6
173    /// ```
174    pub fn mul_assign(&mut self, alpha: f64) {
175        *self.x *= alpha;
176        *self.y *= alpha;
177    }
178
179    /// Divides this vector by a scalar value in-place.
180    ///
181    /// $$\vec{v} \mathrel{/}= \alpha \implies (v_x / \alpha,\; v_y / \alpha)$$
182    ///
183    /// # Arguments
184    ///
185    /// * `alpha` - The scalar value to divide the vector by
186    ///
187    /// # Examples
188    ///
189    /// ```
190    /// use ginger::vector2_ref::Vector2Ref;
191    ///
192    /// let mut x = 6.0;
193    /// let mut y = 8.0;
194    ///
195    /// let mut v = Vector2Ref::new(&mut x, &mut y);
196    /// v.div_assign(2.0);
197    ///
198    /// assert_eq!(*v.x, 3.0); // 6 / 2 = 3
199    /// assert_eq!(*v.y, 4.0); // 8 / 2 = 4
200    /// ```
201    pub fn div_assign(&mut self, alpha: f64) {
202        *self.x /= alpha;
203        *self.y /= alpha;
204    }
205}
206
207#[cfg(test)]
208mod tests {
209    use super::*;
210
211    #[test]
212    fn test_vector2() {
213        let mut x = 1.0;
214        let mut y = 2.0;
215
216        let mut v = Vector2Ref::new(&mut x, &mut y);
217        v.mul_assign(2.0);
218        assert_eq!(*v.x, 2.0);
219        assert_eq!(*v.y, 4.0);
220
221        let mut v2 = Vector2Ref::new(&mut x, &mut y);
222        v2.mul_assign(2.0);
223        assert_eq!(*v2.y, 8.0);
224    }
225
226    #[test]
227    fn test_dot() {
228        let mut x1 = 3.0;
229        let mut y1 = 4.0;
230        let mut x2 = 5.0;
231        let mut y2 = 6.0;
232
233        let v1 = Vector2Ref::new(&mut x1, &mut y1);
234        let v2 = Vector2Ref::new(&mut x2, &mut y2);
235        assert_eq!(v1.dot(&v2), 39.0);
236    }
237
238    #[test]
239    fn test_cross() {
240        let mut x1 = 3.0;
241        let mut y1 = 4.0;
242        let mut x2 = 5.0;
243        let mut y2 = 6.0;
244
245        let v1 = Vector2Ref::new(&mut x1, &mut y1);
246        let v2 = Vector2Ref::new(&mut x2, &mut y2);
247        assert_eq!(v1.cross(&v2), -2.0);
248    }
249
250    #[test]
251    fn test_add_assign() {
252        let mut x1 = 1.0;
253        let mut y1 = 2.0;
254        let mut x2 = 3.0;
255        let mut y2 = 4.0;
256
257        let mut v1 = Vector2Ref::new(&mut x1, &mut y1);
258        let v2 = Vector2Ref::new(&mut x2, &mut y2);
259        v1.add_assign(&v2);
260        assert_eq!(*v1.x, 4.0);
261        assert_eq!(*v1.y, 6.0);
262    }
263
264    #[test]
265    fn test_sub_assign() {
266        let mut x1 = 5.0;
267        let mut y1 = 6.0;
268        let mut x2 = 3.0;
269        let mut y2 = 4.0;
270
271        let mut v1 = Vector2Ref::new(&mut x1, &mut y1);
272        let v2 = Vector2Ref::new(&mut x2, &mut y2);
273        v1.sub_assign(&v2);
274        assert_eq!(*v1.x, 2.0);
275        assert_eq!(*v1.y, 2.0);
276    }
277
278    #[test]
279    fn test_div_assign() {
280        let mut x = 6.0;
281        let mut y = 8.0;
282
283        let mut v = Vector2Ref::new(&mut x, &mut y);
284        v.div_assign(2.0);
285        assert_eq!(*v.x, 3.0);
286        assert_eq!(*v.y, 4.0);
287    }
288}