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