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