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}