1use std::{
26 cmp::{Eq, Ordering},
27 hash::{Hash, Hasher},
28 ops::{Mul, Neg},
29};
30
31use crate::*;
32
33#[derive(Debug, PartialEq, PartialOrd, Clone)]
36pub struct Norm2D {
38 x: f64,
39 y: f64,
40}
41
42impl Eq for Norm2D {}
43
44impl Ord for Norm2D {
45 fn cmp(&self, other: &Self) -> Ordering {
46 let origin = Point2D::default();
47 sqr_dist_2d(&origin, self)
48 .partial_cmp(&sqr_dist_2d(&origin, other))
49 .unwrap_or(Ordering::Equal)
50 }
51}
52
53impl Hash for Norm2D {
54 #[inline(always)]
55 fn hash<H: Hasher>(&self, state: &mut H) {
56 hash_f64(self.x, state);
57 hash_f64(self.y, state);
58 }
59}
60
61impl Mul<f64> for Norm2D {
62 type Output = Point2D;
63
64 fn mul(self, other: f64) -> Point2D {
65 Point2D {
66 x: other * self.x,
67 y: other * self.y,
68 }
69 }
70}
71
72impl Mul<f64> for &Norm2D {
73 type Output = Point2D;
74
75 fn mul(self, other: f64) -> Point2D {
76 Point2D {
77 x: other * self.x,
78 y: other * self.y,
79 }
80 }
81}
82
83impl Neg for Norm2D {
84 type Output = Norm2D;
85
86 fn neg(self) -> Norm2D {
87 Norm2D {
88 x: -self.x,
89 y: -self.y,
90 }
91 }
92}
93
94impl Neg for &Norm2D {
95 type Output = Norm2D;
96
97 fn neg(self) -> Norm2D {
98 Norm2D {
99 x: -self.x,
100 y: -self.y,
101 }
102 }
103}
104
105impl IsND for Norm2D {
106 fn n_dimensions() -> usize {
107 2
108 }
109
110 fn position_nd(&self, dimension: usize) -> Result<f64> {
111 match dimension {
112 0 => Ok(self.x),
113 1 => Ok(self.y),
114 _ => Err(ErrorKind::IncorrectDimension),
115 }
116 }
117}
118
119impl Is2D for Norm2D {
120 #[inline(always)]
121 fn x(&self) -> f64 {
122 self.x
123 }
124
125 #[inline(always)]
126 fn y(&self) -> f64 {
127 self.y
128 }
129}
130
131impl IsNormalized2D for Norm2D {
132 fn new<P>(p: P) -> Result<Self>
133 where
134 P: Is2D,
135 {
136 let l = p.abs().get();
137 if l == 0.0 {
138 return Err(ErrorKind::NormalizeVecWithoutLength);
139 }
140
141 let f = 1.0 / l;
142
143 Ok(Norm2D {
144 x: f * p.x(),
145 y: f * p.y(),
146 })
147 }
148}