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);