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}