mathx/vectors/vector2.rs
1
2use core::ops::Neg;
3
4use crate::Math;
5use crate::Vector3;
6use crate::{AddSubArithmetic, MulDivScalar, use_impl_ops, impl_add, impl_sub, impl_mul, impl_div};
7
8/// A 2D vector that holds an x-coordinate and y-coordinate
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10#[derive(Debug, Clone, Copy)]
11pub struct Vector2 {
12 /// The x coordinate of the vector
13 x: f32,
14 /// The y coordinate of the vector
15 y: f32,
16}
17
18/// Constructors
19impl Vector2 {
20 /// Creates a new 2D vector
21 /// - **x**: The x coordinate of the vector
22 /// - **y**: The y coordinate of the vector
23 ///
24 /// **Returns**: Returns a new 2D vector
25 /// #### Examples
26 /// ```
27 /// # use mathx::Vector2;
28 /// let vector = Vector2::new(1.2, 3.45);
29 /// assert_eq!(1.2, vector.x());
30 /// assert_eq!(3.45, vector.y());
31 /// ```
32 pub fn new(x: f32, y: f32) -> Self { Vector2 { x, y } }
33
34 /// Creates a new 2D vector from a 3D vector
35 /// - **vector**: The 3D vector to convert from
36 ///
37 /// **Returns**: Returns a converted 2D vector
38 /// #### Examples
39 /// ```
40 /// # use mathx::{Vector2,Vector3};
41 /// let vector3 = Vector3::new(1.2, 3.45, 6.789);
42 /// let vector2 = Vector2::from_vector3(vector3);
43 /// assert_eq!(1.2, vector2.x());
44 /// assert_eq!(3.45, vector2.y());
45 /// ```
46 pub fn from_vector3(vector: Vector3) -> Self { Vector2::new(vector.x(), vector.y()) }
47
48 /// Creates an empty 2D vector: (0, 0)
49 ///
50 /// **Returns**: Returns an empty 2D vector
51 /// #### Examples
52 /// ```
53 /// # use mathx::Vector2;
54 /// let vector = Vector2::zero();
55 /// assert_eq!(0.0, vector.x());
56 /// assert_eq!(0.0, vector.y());
57 /// ```
58 pub fn zero() -> Self { Vector2 { x: 0.0, y: 0.0 } }
59
60 /// Creates a 2D unit vector that's pointing to the left: (-1, 0)
61 ///
62 /// **Returns**: Returns a 2D unit vector that's pointing to the left
63 /// #### Examples
64 /// ```
65 /// # use mathx::Vector2;
66 /// let vector = Vector2::left();
67 /// assert_eq!(-1.0, vector.x());
68 /// assert_eq!(0.0, vector.y());
69 /// ```
70 pub fn left() -> Self { Vector2 { x: -1.0, y: 0.0 } }
71
72 /// Creates a 2D unit vector that's pointing to the right: (1, 0)
73 ///
74 /// **Returns**: Returns a 2D unit vector that's pointing to the right
75 /// #### Examples
76 /// ```
77 /// # use mathx::Vector2;
78 /// let vector = Vector2::right();
79 /// assert_eq!(1.0, vector.x());
80 /// assert_eq!(0.0, vector.y());
81 /// ```
82 pub fn right() -> Self { Vector2 { x: 1.0, y: 0.0 } }
83
84 /// Creates a 2D unit vector that's pointing up: (0, 1)
85 ///
86 /// **Returns**: Returns a 2D unit vector that's pointing up
87 /// #### Examples
88 /// ```
89 /// # use mathx::Vector2;
90 /// let vector = Vector2::up();
91 /// assert_eq!(0.0, vector.x());
92 /// assert_eq!(1.0, vector.y());
93 /// ```
94 pub fn up() -> Self { Vector2 { x: 0.0, y: 1.0 } }
95
96 /// Creates a 2D unit vector that's pointing down: (0, -1)
97 ///
98 /// **Returns**: Returns a 2D unit vector that's pointing down
99 /// #### Examples
100 /// ```
101 /// # use mathx::Vector2;
102 /// let vector = Vector2::down();
103 /// assert_eq!(0.0, vector.x());
104 /// assert_eq!(-1.0, vector.y());
105 /// ```
106 pub fn down() -> Self { Vector2 { x: 0.0, y: -1.0 } }
107
108 /// Creates a 2D vector that contains 1 in all it's components: (1, 1)
109 ///
110 /// **Returns**: Returns a 2D vector that contains 1 in all it's components
111 /// #### Examples
112 /// ```
113 /// # use mathx::Vector2;
114 /// let vector = Vector2::one();
115 /// assert_eq!(1.0, vector.x());
116 /// assert_eq!(1.0, vector.y());
117 /// ```
118 pub fn one() -> Self { Vector2 { x: 1.0, y: 1.0 } }
119
120 /// Creates a 2D vector from a single angle (heading)
121 /// - **angle**: The angle in radians to create the 2D vector from
122 ///
123 /// **Returns**: Returns a 2D vector from the single angle
124 /// #### Examples
125 /// ```
126 /// # use mathx::{Vector2,Math,assert_range};
127 /// let vector = Vector2::from_heading(Math::PI_OVER_4);
128 /// assert_range!(0.7071068, vector.x());
129 /// assert_range!(0.7071068, vector.y());
130 /// let vector = Vector2::from_heading(4.0);
131 /// assert_range!(-0.653643620864, vector.x());
132 /// assert_range!(-0.756802495308, vector.y());
133 /// ```
134 pub fn from_heading(angle: f32) -> Self {
135 let (sin, cos) = Math::sin_cos(angle);
136
137 Vector2::new(cos, sin)
138 }
139
140 /// Creates a 2D vector from a single angle (heading)
141 /// - **angle**: The angle in degrees to create the 2D vector from
142 ///
143 /// **Returns**: Returns a 2D vector from the single angle
144 /// #### Examples
145 /// ```
146 /// # use mathx::{Vector2,Math,assert_range};
147 /// let vector = Vector2::from_heading_deg(45.0);
148 /// assert_range!(0.7071068, vector.x());
149 /// assert_range!(0.7071068, vector.y());
150 /// let vector = Vector2::from_heading_deg(229.183118052);
151 /// assert_range!(-0.653643620864, vector.x());
152 /// assert_range!(-0.756802495308, vector.y());
153 /// ```
154 pub fn from_heading_deg(angle: f32) -> Self {
155 let (sin, cos) = Math::sin_cos_deg(angle);
156
157 Vector2::new(cos, sin)
158 }
159}
160
161/// Properties
162impl Vector2 {
163 /// Gets the x coordinate of the vector
164 ///
165 /// **Returns**: Returns the x coordinate of the vector
166 pub fn x(&self) -> f32 { self.x }
167
168 /// Sets the x coordinate of the vector
169 /// - **value**: The value to set the x coordinate of the vector
170 pub fn set_x(&mut self, value: f32) { self.x = value; }
171
172 /// Gets the y coordinate of the vector
173 ///
174 /// **Returns**: Returns the y coordinate of the vector
175 pub fn y(&self) -> f32 { self.y }
176
177 /// Sets the y coordinate of the vector
178 /// - **value**: The value to set the y coordinate of the vector
179 pub fn set_y(&mut self, value: f32) { self.y = value; }
180
181 /// Get the heading from the vector in radians
182 ///
183 /// **Returns**: Returns the heading from the vector in radians
184 /// #### Examples
185 /// ```
186 /// # use mathx::{Math,Vector2,assert_range};
187 /// let heading = Vector2::one().heading();
188 /// assert_range!(Math::PI_OVER_4, heading);
189 /// ```
190 pub fn heading(&self) -> f32 { Math::atan2(self.y, self.x) }
191
192 /// Sets the heading for the vector in radians
193 /// - **angle**: The angle to set the heading of the vector for in radians
194 /// #### Examples
195 /// ```
196 /// # use mathx::{Math,Vector2,assert_range};
197 /// let mut vector = Vector2::zero();
198 /// vector.set_heading(Math::PI_OVER_4);
199 /// assert_range!(0.70710678118, vector.x());
200 /// assert_range!(0.70710678118, vector.y());
201 /// ```
202 pub fn set_heading(&mut self, angle: f32) {
203 let vector = Vector2::from_heading(angle);
204
205 self.x = vector.x;
206 self.y = vector.y;
207 }
208
209 /// Get the heading from the vector in degrees
210 ///
211 /// **Returns**: Returns the heading from the vector in degrees
212 /// #### Examples
213 /// ```
214 /// # use mathx::{Math,Vector2,assert_range};
215 /// let heading = Vector2::one().heading_deg();
216 /// assert_range!(45.0, heading, 0.001);
217 /// ```
218 pub fn heading_deg(&self) -> f32 { Math::rad2deg(self.heading()) }
219
220 /// Sets the heading for the vector in degrees
221 /// - **angle**: The angle to set the heading of the vector for in degrees
222 ///
223 /// #### Examples
224 /// ```
225 /// # use mathx::{Math,Vector2,assert_range};
226 /// let mut vector = Vector2::zero();
227 /// vector.set_heading_deg(45.0);
228 /// assert_range!(0.70710678118, vector.x());
229 /// assert_range!(0.70710678118, vector.y());
230 /// ```
231 pub fn set_heading_deg(&mut self, angle: f32) { self.set_heading(Math::deg2rad(angle)) }
232
233 /// Gets the magnitude of the vector. This returns the length of the vector
234 ///
235 /// **Returns**: Returns the magnitude of the vector
236 /// #### Examples
237 /// ```
238 /// # use mathx::Vector2;
239 /// let a = Vector2::new(-1.0, 2.0);
240 /// assert_eq!(2.236068, a.magnitude());
241 /// ```
242 pub fn magnitude(&self) -> f32 {
243 let magnitude = self.square_magnitude();
244
245 if magnitude == 0.0 || magnitude == 1.0 {
246 return magnitude;
247 }
248
249 return Math::sqrt(magnitude);
250 }
251
252 /// Gets the magnitude squared, avoiding the use of a square root
253 ///
254 /// **Returns**: Returns the magnitude of the vector squared
255 /// #### Examples
256 /// ```
257 /// # use mathx::Vector2;
258 /// let a = Vector2::new(-1.0, 2.0);
259 /// assert_eq!(5.0, a.square_magnitude());
260 /// ```
261 pub fn square_magnitude(&self) -> f32 { self.x * self.x + self.y * self.y }
262}
263
264/// Public Methods
265impl Vector2 {
266 /// Gets the angle between the two vectors in radians
267 /// - **rhs**: The other vector to get the angle from
268 ///
269 /// **Returns**: Returns the angle between the two vectors in radians
270 /// #### Examples
271 /// ```
272 /// # use mathx::{Vector2,Math,assert_range};
273 /// let a = Vector2::new(0.25, -0.5);
274 /// let b = Vector2::new(2.0, 0.5);
275 /// assert_range!(1.35212751547, a.angle_between(b));
276 /// ```
277 pub fn angle_between(self, rhs: Vector2) -> f32 {
278 let value = Math::sqrt(self.square_magnitude() * rhs.square_magnitude());
279
280 if value < 0.0000000001 { return 0.0; }
281 else { return Math::acos(Math::clamp((self * rhs) / value, -1.0, 1.0)); }
282 }
283
284 /// Gets the angle between the two vectors in degrees
285 /// - **rhs**: The other vector to get the angle from
286 ///
287 /// **Returns**: Returns the angle between the two vectors in degrees
288 /// #### Examples
289 /// ```
290 /// # use mathx::{Vector2,Math,assert_range};
291 /// let a = Vector2::new(0.25, -0.5);
292 /// let b = Vector2::new(2.0, 0.5);
293 /// assert_range!(77.4712, a.angle_between_deg(b), 0.01);
294 /// ```
295 pub fn angle_between_deg(self, rhs: Vector2) -> f32 { return Math::rad2deg(self.angle_between(rhs)); }
296
297 /// Gets the distance between the two vectors
298 /// - **rhs**: The other vector to get the distance between
299 ///
300 /// **Returns**: Returns the distance between the two vectors
301 /// #### Examples
302 /// ```
303 /// # use mathx::Vector2;
304 /// let a = Vector2::new(0.25, -0.5);
305 /// let b = Vector2::new(2.0, 0.5);
306 /// assert_eq!(2.0155644, a.distance(b));
307 /// ```
308 pub fn distance(self, rhs: Vector2) -> f32 { (rhs - self).magnitude() }
309
310 /// Gets the dot product of between the two vectors.
311 /// It can be used to determine the angle between two vectors.
312 /// - **rhs**: The other vector to dot product with
313 ///
314 /// **Returns**: Returns the dot product
315 /// #### Remarks
316 /// Using two unit vectors, the maximum range of numbers go from -1 to 1. It scales with
317 /// the magnitude of both vectors (multiplying them together `a.magnitude() * b.magnitude()`)
318 /// #### Examples
319 /// ```
320 /// # use mathx::Vector2;
321 /// let a = Vector2::one();
322 /// let b = Vector2::new(0.25, 1.1);
323 /// let dot = a.dot(b);
324 /// assert_eq!(1.35, dot);
325 /// ```
326 /// Note that if the angle is 90 degrees (PI / 2) then it's going to return 0
327 /// ```
328 /// # use mathx::Vector2;
329 /// let a = Vector2::right();
330 /// let b = 2.0 * Vector2::up();
331 /// let dot = a.dot(b);
332 /// assert_eq!(0.0, dot);
333 /// ```
334 /// Where as, if the angle is 0 degrees or 180 degrees (PI) then it's going to return 1 and -1 respectively;
335 /// given that the two vectors are unit vectors
336 /// ```
337 /// # use mathx::Vector2;
338 /// let a = Vector2::right();
339 /// let b = Vector2::left();
340 /// let dot_one = a.dot(a);
341 /// let dot_negative_one = a.dot(b);
342 /// assert_eq!(1.0, dot_one);
343 /// assert_eq!(-1.0, dot_negative_one);
344 /// ```
345 pub fn dot(self, rhs: Vector2) -> f32 {
346 self.x * rhs.x + self.y * rhs.y
347 }
348
349 /// Linearly interpolates between the this and the other vector
350 /// - **rhs**: The other vector to end from
351 /// - **t**: The ratio value to interpolate between both vectors. Clamped between 0.0 and 1.0
352 ///
353 /// **Returns**: Returns the interpolated vector
354 /// #### Examples
355 /// ```
356 /// # use mathx::Vector2;
357 /// let a = Vector2::new(0.0, -10.0);
358 /// let b = Vector2::new(1.0, -4.0);
359 /// let expected = Vector2::new(0.7, -5.8);
360 /// assert_eq!(expected, a.lerp_unclamped(b, 0.7));
361 /// ```
362 pub fn lerp(self, rhs: Vector2, t: f32) -> Self { self.lerp_unclamped(rhs, t.clamp(0.0, 1.0)) }
363
364 /// Linearly interpolates between the this and the other vector (not clamped)
365 /// - **rhs**: The other vector to end from
366 /// - **t**: The ratio value to interpolate between both vectors
367 ///
368 /// **Returns**: Returns the interpolated vector
369 /// #### Examples
370 /// ```
371 /// # use mathx::Vector2;
372 /// let a = Vector2::new(0.0, -10.0);
373 /// let b = Vector2::new(1.0, -4.0);
374 /// let expected = Vector2::new(0.7, -5.8);
375 /// assert_eq!(expected, a.lerp_unclamped(b, 0.7));
376 /// ```
377 pub fn lerp_unclamped(self, rhs: Vector2, t: f32) -> Self {
378 Vector2::new(
379 Math::lerp_unclamped(self.x, rhs.x, t),
380 Math::lerp_unclamped(self.y, rhs.y, t)
381 )
382 }
383
384 /// Moves this vector towards the target vector, it will never move past the target
385 /// - **target**: The target vector to move towards
386 /// - **delta**: The delta distance to try and move with, defines the maximum distance moved
387 ///
388 /// **Returns**: Returns the vector that is closer towards the target
389 /// #### Examples
390 /// ```
391 /// # use mathx::Vector2;
392 /// let a = Vector2::new(0.25, -0.5);
393 /// let b = Vector2::new(2.0, 0.5);
394 /// let expected = Vector2::new(0.42364863, -0.4007722);
395 /// assert_eq!(expected, a.move_towards(b, 0.2));
396 /// assert_eq!(b, a.move_towards(b, 20.0));
397 /// ```
398 pub fn move_towards(self, target: Vector2, delta: f32) -> Self {
399 let dir = target - self;
400 let sq_magnitude = dir.square_magnitude();
401 if sq_magnitude == 0.0 || (delta >= 0.0 && sq_magnitude <= delta * delta) {
402 return target;
403 }
404
405 let diff = delta / Math::sqrt(sq_magnitude);
406
407 return diff * dir + self;
408 }
409
410 /// Normalizes the vector
411 ///
412 /// **Returns**: Returns the unit vector version of this vector
413 /// #### Examples
414 /// ```
415 /// # use mathx::{Vector2,Math,assert_range};
416 /// let vector = Vector2::one().normalize();
417 /// assert_range!(0.70710678118, vector.x());
418 /// assert_range!(0.70710678118, vector.y());
419 /// let vector = Vector2::new(-0.1, 1.0).normalize();
420 /// assert_range!(-0.09950372, vector.x());
421 /// assert_range!(0.99503714, vector.y());
422 /// ```
423 pub fn normalize(self) -> Self { self / self.magnitude() }
424
425 /// Creates a perpendicular 2D vector
426 ///
427 /// **Returns**: Returns a perpendicular 2D vector
428 /// #### Examples
429 /// ```
430 /// # use mathx::Vector2;
431 /// let vector = Vector2::new(1.0, 2.0);
432 /// let perpendicular = vector.perpendicular();
433 /// assert_eq!(0.0, vector * perpendicular);
434 /// ```
435 pub fn perpendicular(self) -> Self { Vector2::new(self.y, -self.x) }
436
437 /// Projects this vector onto the given vector
438 /// - **rhs**: The vector to project onto
439 ///
440 /// **Returns**: Returns the projected vector
441 /// #### Examples
442 /// ```
443 /// # use mathx::{Vector2,Math,assert_range};
444 /// let a = Vector2::new(1.0, 2.0);
445 /// let b = Vector2::new(3.0, 4.0);
446 /// let expected = Vector2::new(1.32, 1.76);
447 /// assert_range!(expected.x(), a.project(b).x());
448 /// assert_range!(expected.y(), a.project(b).y());
449 /// ```
450 pub fn project(self, rhs: Vector2) -> Self {
451 let top = self * rhs;
452 let bottom = rhs.square_magnitude();
453
454 return (top / bottom) * rhs;
455 }
456
457 /// Rejects this vector from the given vector
458 /// - **rhs**: The vector to reject from
459 ///
460 /// **Returns**: Returns the rejected vector
461 /// #### Examples
462 /// ```
463 /// # use mathx::{Vector2,Math,assert_range};
464 /// let a = Vector2::new(1.0, 2.0);
465 /// let b = Vector2::new(3.0, 4.0);
466 /// let expected = Vector2::new(-0.32, 0.24);
467 /// assert_range!(expected.x(), a.reject(b).x());
468 /// assert_range!(expected.y(), a.reject(b).y());
469 /// ```
470 pub fn reject(self, rhs: Vector2) -> Self {
471 self - self.project(rhs)
472 }
473
474 /// Reflects this vector using a normal vector
475 /// - **normal**: The normal vector to reflect off of
476 ///
477 /// **Returns**: Returns the reflected vector
478 /// #### Examples
479 /// ```
480 /// # use mathx::Vector2;
481 /// let direction = Vector2::new(1.0, 0.0);
482 /// let normal = Vector2::new(1.0, 1.0);
483 /// let expected = Vector2::new(-1.0, -2.0);
484 /// assert_eq!(expected, direction.reflect(normal));
485 /// let direction = Vector2::new(0.25, -0.5);
486 /// let normal = Vector2::new(1.0, 0.5);
487 /// let expected = Vector2::new(0.25, -0.5);
488 /// assert_eq!(expected, direction.reflect(normal));
489 /// ```
490 pub fn reflect(self, normal: Vector2) -> Self {
491 let dot = -2.0 * (self * normal);
492
493 return dot * normal + self;
494 }
495
496 /// Scales the vector using another vector, multiplying everything component-wise
497 /// - **rhs**: The other vector to scale with
498 ///
499 /// **Returns**: Returns the scaled vector
500 /// #### Examples
501 /// ```
502 /// # use mathx::Vector2;
503 /// let a = Vector2::new(0.25, -0.5);
504 /// let b = Vector2::new(2.0, 0.5);
505 /// let expected = Vector2::new(0.5, -0.25);
506 /// assert_eq!(expected, a.scale(b));
507 /// ```
508 pub fn scale(self, rhs: Vector2) -> Self {
509 Vector2::new(
510 self.x * rhs.x,
511 self.y * rhs.y
512 )
513 }
514
515 /// Gets the signed angle between the two vectors using an axis in radians
516 /// - **rhs**: The other vector to get the angle from
517 ///
518 /// **Returns**: Returns the signed angle between the two vectors using an axis in radians
519 /// #### Examples
520 /// ```
521 /// # use mathx::{Vector2,Math,assert_range};
522 /// let a = Vector2::new(0.25, -0.5);
523 /// let b = Vector2::new(-2.0, 0.5);
524 /// assert_range!(-2.27942269238, a.signed_angle_between(b));
525 /// ```
526 pub fn signed_angle_between(self, rhs: Vector2) -> f32 {
527 let angle = self.angle_between(rhs);
528 let sign = Math::sign(self * rhs.perpendicular());
529
530 return sign * angle;
531 }
532
533 /// Gets the signed angle between the two vectors using an axis in degrees
534 /// - **rhs**: The other vector to get the angle from
535 ///
536 /// **Returns**: Returns the signed angle between the two vectors using an axis in degrees
537 /// #### Examples
538 /// ```
539 /// # use mathx::{Vector2,Math,assert_range};
540 /// let a = Vector2::new(0.25, -0.5);
541 /// let b = Vector2::new(-2.0, 0.5);
542 /// assert_range!(-130.6013, a.signed_angle_between_deg(b), 0.01);
543 /// ```
544 pub fn signed_angle_between_deg(self, rhs: Vector2) -> f32 { Math::rad2deg(self.signed_angle_between(rhs)) }
545
546}
547
548/// Conversions
549impl Vector2 {
550 pub fn to_vector3(self) -> Vector3 { Vector3::new(self.x, self.y, 0.0) }
551}
552
553impl From<Vector3> for Vector2 {
554 fn from(value: Vector3) -> Self { Vector2::from_vector3(value) }
555}
556
557unsafe impl Send for Vector2 {}
558unsafe impl Sync for Vector2 {}
559
560// Equates
561impl Eq for Vector2 {}
562impl PartialEq for Vector2 {
563 fn eq(&self, other: &Self) -> bool {
564 Math::approx(self.x, other.x)
565 && Math::approx(self.y, other.y)
566 }
567}
568
569// Display
570#[cfg(not(feature = "no_std"))]
571impl std::fmt::Display for Vector2 {
572 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
573 f.write_str(&format!("({}, {})", self.x, self.y))
574 }
575}
576
577// Arithmetic
578impl AddSubArithmetic<Vector2> for Vector2 {
579 type Output = Vector2;
580 fn add_other(self, rhs: Vector2) -> Self::Output {
581 Vector2 { x: self.x + rhs.x, y: self.y + rhs.y }
582 }
583 fn add_assign_other(&mut self, rhs: Vector2) {
584 self.x += rhs.x;
585 self.y += rhs.y;
586 }
587 fn subtract_other(self, rhs: Vector2) -> Self::Output {
588 Vector2 { x: self.x - rhs.x, y: self.y - rhs.y }
589 }
590 fn subtract_assign_other(&mut self, rhs: Vector2) {
591 self.x -= rhs.x;
592 self.y -= rhs.y;
593 }
594}
595
596impl AddSubArithmetic<Vector3> for Vector2 {
597 type Output = Vector3;
598
599 fn add_other(self, rhs: Vector3) -> Self::Output {
600 Vector3::new(self.x + rhs.x(), self.y + rhs.y(), rhs.z())
601 }
602 fn add_assign_other(&mut self, rhs: Vector3) {
603 self.x += rhs.x();
604 self.y += rhs.y();
605 }
606 fn subtract_other(self, rhs: Vector3) -> Self::Output {
607 Vector3::new(self.x - rhs.x(), self.y - rhs.y(), -rhs.z())
608 }
609 fn subtract_assign_other(&mut self, rhs: Vector3) {
610 self.x -= rhs.x();
611 self.y -= rhs.y();
612 }
613}
614
615impl MulDivScalar for Vector2 {
616 type Output = Vector2;
617 fn multiply_scalar(self, rhs: f32) -> Self::Output {
618 Vector2 { x: rhs * self.x, y: rhs * self.y }
619 }
620 fn multiply_assign_scalar(&mut self, rhs: f32) {
621 self.x *= rhs;
622 self.y *= rhs;
623 }
624 fn divide_scalar(self, rhs: f32) -> Self::Output {
625 if rhs == 0.0 { return Vector2::zero(); }
626 Vector2 { x: self.x / rhs, y: self.y / rhs }
627 }
628 fn divide_assign_scalar(&mut self, rhs: f32) {
629 if rhs == 0.0 {
630 self.x = 0.0;
631 self.y = 0.0;
632 }
633 else {
634 self.x /= rhs;
635 self.y /= rhs;
636 }
637 }
638 fn reciprocal_scalar(self, rhs: f32) -> Self::Output {
639 Vector2 {
640 x: if self.x != 0.0 { rhs / self.x } else { 0.0 },
641 y: if self.y != 0.0 { rhs / self.y } else { 0.0 },
642 }
643 }
644}
645
646impl Neg for Vector2 {
647 type Output = Vector2;
648 fn neg(self) -> Self::Output { Vector2::new(-self.x, -self.y) }
649}
650
651use_impl_ops!();
652impl_add!(Vector2);
653impl_add!(Vector2 => Vector3: Vector3);
654impl_sub!(Vector2);
655impl_sub!(Vector2 => Vector3: Vector3);
656impl_mul!(Vector2);
657impl_mul!(Vector2, Vector2 => f32: dot);
658impl_div!(Vector2);