common_stdx/
point.rs

1use num_traits::Zero;
2use std::ops::{Add, Mul, Neg, Sub};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub struct Point<T> {
6    pub x: T,
7    pub y: T,
8}
9
10impl<T> Point<T> {
11    pub fn new(x: T, y: T) -> Self {
12        Point { x, y }
13    }
14}
15
16impl<T> From<(T, T)> for Point<T> {
17    fn from((x, y): (T, T)) -> Self {
18        Point { x, y }
19    }
20}
21
22impl<T> Point<T>
23where
24    T: Copy + Zero + PartialEq,
25{
26    pub fn zero() -> Self {
27        Point {
28            x: T::zero(),
29            y: T::zero(),
30        }
31    }
32
33    pub fn is_zero(&self) -> bool {
34        self.x == T::zero() && self.y == T::zero()
35    }
36}
37
38impl<T> Add for Point<T>
39where
40    T: Add<Output = T> + Copy,
41{
42    type Output = Point<T>;
43    fn add(self, rhs: Point<T>) -> Self::Output {
44        Point {
45            x: self.x + rhs.x,
46            y: self.y + rhs.y,
47        }
48    }
49}
50
51impl<T> Sub for Point<T>
52where
53    T: Sub<Output = T> + Copy,
54{
55    type Output = Point<T>;
56    fn sub(self, rhs: Point<T>) -> Self::Output {
57        Point {
58            x: self.x - rhs.x,
59            y: self.y - rhs.y,
60        }
61    }
62}
63
64impl<T> Mul<T> for Point<T>
65where
66    T: Mul<Output = T> + Copy,
67{
68    type Output = Point<T>;
69    fn mul(self, rhs: T) -> Self::Output {
70        Point {
71            x: self.x * rhs,
72            y: self.y * rhs,
73        }
74    }
75}
76
77impl<T> Neg for Point<T>
78where
79    T: Neg<Output = T> + Copy,
80{
81    type Output = Point<T>;
82    fn neg(self) -> Self::Output {
83        Point {
84            x: -self.x,
85            y: -self.y,
86        }
87    }
88}
89
90impl<T> Point<T>
91where
92    T: Copy + Mul<Output = T> + Add<Output = T>,
93{
94    pub fn dot(self, other: Point<T>) -> T {
95        self.x * other.x + self.y * other.y
96    }
97}
98
99#[cfg(feature = "float")]
100impl<T> Point<T>
101where
102    T: Copy + Sub<Output = T> + Into<f64>,
103{
104    pub fn distance(self, other: Point<T>) -> f64 {
105        let dx: f64 = (self.x - other.x).into();
106        let dy: f64 = (self.y - other.y).into();
107        (dx * dx + dy * dy).sqrt()
108    }
109
110    pub fn magnitude(self) -> f64 {
111        let x: f64 = self.x.into();
112        let y: f64 = self.y.into();
113        (x * x + y * y).sqrt()
114    }
115}