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