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}