1use core::ops::{Add, Div, Mul, Neg, Rem, Sub};
3use num_traits::{Num, Signed, Zero};
4
5#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
22pub struct Vector2<T> {
23 pub x_: T,
25 pub y_: T,
27}
28
29impl<T> Vector2<T> {
30 #[inline]
53 pub const fn new(x_: T, y_: T) -> Self {
54 Vector2 { x_, y_ }
55 }
56}
57
58impl<T: Clone + Num> Vector2<T> {
59 #[inline]
81 pub fn dot(&self, other: &Self) -> T {
82 self.x_.clone() * other.x_.clone() + self.y_.clone() * other.y_.clone()
83 }
84
85 #[inline]
107 pub fn cross(&self, other: &Self) -> T {
108 self.x_.clone() * other.y_.clone() - self.y_.clone() * other.x_.clone()
109 }
110
111 #[inline]
128 pub fn norm_sqr(&self) -> T {
129 self.dot(self)
130 }
131
132 #[inline]
153 pub fn scale(&self, alpha: T) -> Self {
154 Self::new(self.x_.clone() * alpha.clone(), self.y_.clone() * alpha)
155 }
156
157 #[inline]
177 pub fn unscale(&self, alpha: T) -> Self {
178 Self::new(self.x_.clone() / alpha.clone(), self.y_.clone() / alpha)
179 }
180}
181
182impl<T: Clone + Signed> Vector2<T> {
183 #[inline]
201 pub fn l1_norm(&self) -> T {
202 self.x_.abs() + self.y_.abs()
203 }
204}
205
206impl<T: Clone + PartialOrd> Vector2<T> {
207 #[inline]
223 pub fn norm_inf(&self) -> T {
224 if self.x_ > self.y_ {
225 self.x_.clone()
226 } else {
227 self.y_.clone()
228 }
229 }
230}
231
232macro_rules! forward_xf_xf_binop {
233 (impl $imp:ident, $method:ident) => {
234 impl<'a, 'b, T: Clone + Num> $imp<&'b Vector2<T>> for &'a Vector2<T> {
235 type Output = Vector2<T>;
236
237 #[inline]
238 fn $method(self, other: &Vector2<T>) -> Self::Output {
239 self.clone().$method(other.clone())
240 }
241 }
242 };
243}
244
245macro_rules! forward_xf_val_binop {
246 (impl $imp:ident, $method:ident) => {
247 impl<'a, T: Clone + Num> $imp<Vector2<T>> for &'a Vector2<T> {
248 type Output = Vector2<T>;
249
250 #[inline]
251 fn $method(self, other: Vector2<T>) -> Self::Output {
252 self.clone().$method(other)
253 }
254 }
255 };
256}
257
258macro_rules! forward_val_xf_binop {
259 (impl $imp:ident, $method:ident) => {
260 impl<'a, T: Clone + Num> $imp<&'a Vector2<T>> for Vector2<T> {
261 type Output = Vector2<T>;
262
263 #[inline]
264 fn $method(self, other: &Vector2<T>) -> Self::Output {
265 self.$method(other.clone())
266 }
267 }
268 };
269}
270
271macro_rules! forward_all_binop {
272 (impl $imp:ident, $method:ident) => {
273 forward_xf_xf_binop!(impl $imp, $method);
274 forward_xf_val_binop!(impl $imp, $method);
275 forward_val_xf_binop!(impl $imp, $method);
276 };
277}
278
279forward_all_binop!(impl Add, add);
281
282impl<T: Clone + Num> Add<Vector2<T>> for Vector2<T> {
284 type Output = Self;
285
286 #[inline]
287 fn add(self, other: Self) -> Self::Output {
288 Self::Output::new(self.x_ + other.x_, self.y_ + other.y_)
289 }
290}
291
292forward_all_binop!(impl Sub, sub);
293
294impl<T: Clone + Num> Sub<Vector2<T>> for Vector2<T> {
296 type Output = Self;
297
298 #[inline]
299 fn sub(self, other: Self) -> Self::Output {
300 Self::Output::new(self.x_ - other.x_, self.y_ - other.y_)
301 }
302}
303
304mod opassign {
307 use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
308
309 use num_traits::NumAssign;
310
311 use crate::Vector2;
312
313 impl<T: Clone + NumAssign> AddAssign for Vector2<T> {
314 fn add_assign(&mut self, other: Self) {
315 self.x_ += other.x_;
316 self.y_ += other.y_;
317 }
318 }
319
320 impl<T: Clone + NumAssign> SubAssign for Vector2<T> {
321 fn sub_assign(&mut self, other: Self) {
322 self.x_ -= other.x_;
323 self.y_ -= other.y_;
324 }
325 }
326
327 impl<T: Clone + NumAssign> MulAssign<T> for Vector2<T> {
328 fn mul_assign(&mut self, other: T) {
329 self.x_ *= other.clone();
330 self.y_ *= other;
331 }
332 }
333
334 impl<T: Clone + NumAssign> DivAssign<T> for Vector2<T> {
335 fn div_assign(&mut self, other: T) {
336 self.x_ /= other.clone();
337 self.y_ /= other;
338 }
339 }
340
341 macro_rules! forward_op_assign1 {
342 (impl $imp:ident, $method:ident) => {
343 impl<'a, T: Clone + NumAssign> $imp<&'a Vector2<T>> for Vector2<T> {
344 #[inline]
345 fn $method(&mut self, other: &Self) {
346 self.$method(other.clone())
347 }
348 }
349 };
350 }
351
352 macro_rules! forward_op_assign2 {
353 (impl $imp:ident, $method:ident) => {
354 impl<'a, T: Clone + NumAssign> $imp<&'a T> for Vector2<T> {
355 #[inline]
356 fn $method(&mut self, other: &T) {
357 self.$method(other.clone())
358 }
359 }
360 };
361 }
362
363 forward_op_assign1!(impl AddAssign, add_assign);
364 forward_op_assign1!(impl SubAssign, sub_assign);
365 forward_op_assign2!(impl MulAssign, mul_assign);
366 forward_op_assign2!(impl DivAssign, div_assign);
367}
368
369impl<T: Clone + Num + Neg<Output = T>> Neg for Vector2<T> {
370 type Output = Self;
371
372 #[inline]
373 fn neg(self) -> Self::Output {
374 Self::Output::new(-self.x_, -self.y_)
375 }
376}
377
378impl<'a, T: Clone + Num + Neg<Output = T>> Neg for &'a Vector2<T> {
379 type Output = Vector2<T>;
380
381 #[inline]
382 fn neg(self) -> Self::Output {
383 -self.clone()
384 }
385}
386
387macro_rules! scalar_arithmetic {
388 (@forward $imp:ident::$method:ident for $($scalar:ident),*) => (
389 impl<'a, T: Clone + Num> $imp<&'a T> for Vector2<T> {
390 type Output = Vector2<T>;
391
392 #[inline]
393 fn $method(self, other: &T) -> Self::Output {
394 self.$method(other.clone())
395 }
396 }
397 impl<'a, T: Clone + Num> $imp<T> for &'a Vector2<T> {
398 type Output = Vector2<T>;
399
400 #[inline]
401 fn $method(self, other: T) -> Self::Output {
402 self.clone().$method(other)
403 }
404 }
405 impl<'a, 'b, T: Clone + Num> $imp<&'a T> for &'b Vector2<T> {
406 type Output = Vector2<T>;
407
408 #[inline]
409 fn $method(self, other: &T) -> Self::Output {
410 self.clone().$method(other.clone())
411 }
412 }
413 $(
414 impl<'a> $imp<&'a Vector2<$scalar>> for $scalar {
415 type Output = Vector2<$scalar>;
416
417 #[inline]
418 fn $method(self, other: &Vector2<$scalar>) -> Vector2<$scalar> {
419 self.$method(other.clone())
420 }
421 }
422 impl<'a> $imp<Vector2<$scalar>> for &'a $scalar {
423 type Output = Vector2<$scalar>;
424
425 #[inline]
426 fn $method(self, other: Vector2<$scalar>) -> Vector2<$scalar> {
427 self.clone().$method(other)
428 }
429 }
430 impl<'a, 'b> $imp<&'a Vector2<$scalar>> for &'b $scalar {
431 type Output = Vector2<$scalar>;
432
433 #[inline]
434 fn $method(self, other: &Vector2<$scalar>) -> Vector2<$scalar> {
435 self.clone().$method(other.clone())
436 }
437 }
438 )*
439 );
440 ($($scalar:ident),*) => (
441 scalar_arithmetic!(@forward Mul::mul for $($scalar),*);
442 $(
446 impl Mul<Vector2<$scalar>> for $scalar {
447 type Output = Vector2<$scalar>;
448
449 #[inline]
450 fn mul(self, other: Vector2<$scalar>) -> Self::Output {
451 Self::Output::new(self * other.x_, self * other.y_)
452 }
453 }
454
455 )*
456 );
457}
458
459impl<T: Clone + Num> Mul<T> for Vector2<T> {
460 type Output = Vector2<T>;
461
462 #[inline]
463 fn mul(self, other: T) -> Self::Output {
464 Self::Output::new(self.x_ * other.clone(), self.y_ * other)
465 }
466}
467
468impl<T: Clone + Num> Div<T> for Vector2<T> {
469 type Output = Self;
470
471 #[inline]
472 fn div(self, other: T) -> Self::Output {
473 Self::Output::new(self.x_ / other.clone(), self.y_ / other)
474 }
475}
476
477impl<T: Clone + Num> Rem<T> for Vector2<T> {
478 type Output = Vector2<T>;
479
480 #[inline]
481 fn rem(self, other: T) -> Self::Output {
482 Self::Output::new(self.x_ % other.clone(), self.y_ % other)
483 }
484}
485
486scalar_arithmetic!(usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64);
487
488impl<T: Clone + Num> Zero for Vector2<T> {
490 #[inline]
491 fn zero() -> Self {
492 Self::new(Zero::zero(), Zero::zero())
493 }
494
495 #[inline]
496 fn is_zero(&self) -> bool {
497 self.x_.is_zero() && self.y_.is_zero()
498 }
499
500 #[inline]
501 fn set_zero(&mut self) {
502 self.x_.set_zero();
503 self.y_.set_zero();
504 }
505}
506
507#[cfg(test)]
517mod test {
518 #![allow(non_upper_case_globals)]
519
520 use super::Vector2;
522 use core::f64;
523 use num_traits::Zero;
524
525 pub const _0_0v: Vector2<f64> = Vector2 { x_: 0.0, y_: 0.0 };
526 pub const _1_0v: Vector2<f64> = Vector2 { x_: 1.0, y_: 0.0 };
527 pub const _1_1v: Vector2<f64> = Vector2 { x_: 1.0, y_: 1.0 };
528 pub const _0_1v: Vector2<f64> = Vector2 { x_: 0.0, y_: 1.0 };
529 pub const _neg1_1v: Vector2<f64> = Vector2 { x_: -1.0, y_: 1.0 };
530 pub const _05_05v: Vector2<f64> = Vector2 { x_: 0.5, y_: 0.5 };
531 pub const all_consts: [Vector2<f64>; 5] = [_0_0v, _1_0v, _1_1v, _neg1_1v, _05_05v];
532 pub const _4_2v: Vector2<f64> = Vector2 { x_: 4.0, y_: 2.0 };
533
534 #[test]
535 fn test_consts() {
536 fn test(c: Vector2<f64>, r: f64, i: f64) {
538 assert_eq!(c, Vector2::new(r, i));
539 }
540 test(_0_0v, 0.0, 0.0);
541 test(_1_0v, 1.0, 0.0);
542 test(_1_1v, 1.0, 1.0);
543 test(_neg1_1v, -1.0, 1.0);
544 test(_05_05v, 0.5, 0.5);
545 assert_eq!(_0_0v, Zero::zero());
546 }
547
548 #[test]
549 fn test_scale_unscale() {
550 assert_eq!(_05_05v.scale(2.0), _1_1v);
551 assert_eq!(_1_1v.unscale(2.0), _05_05v);
552 for &c in all_consts.iter() {
553 assert_eq!(c.scale(2.0).unscale(2.0), c);
554 }
555 }
556
557 }