common_stdx/
point.rs

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