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}