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 Norm3D {
38 x: f64,
39 y: f64,
40 z: f64,
41}
42
43impl Eq for Norm3D {}
44
45impl Ord for Norm3D {
46 fn cmp(&self, other: &Self) -> Ordering {
47 let origin = Point3D::default();
48 sqr_dist_3d(&origin, self)
49 .partial_cmp(&sqr_dist_3d(&origin, other))
50 .unwrap_or(Ordering::Equal)
51 }
52}
53
54impl Hash for Norm3D {
55 #[inline(always)]
56 fn hash<H: Hasher>(&self, state: &mut H) {
57 hash_f64(self.x, state);
58 hash_f64(self.y, state);
59 hash_f64(self.z, state);
60 }
61}
62
63impl Mul<f64> for Norm3D {
64 type Output = Point3D;
65
66 fn mul(self, other: f64) -> Point3D {
67 Point3D {
68 x: other * self.x,
69 y: other * self.y,
70 z: other * self.z,
71 }
72 }
73}
74
75impl Mul<f64> for &Norm3D {
76 type Output = Point3D;
77
78 fn mul(self, other: f64) -> Point3D {
79 Point3D {
80 x: other * self.x,
81 y: other * self.y,
82 z: other * self.z,
83 }
84 }
85}
86
87impl Neg for Norm3D {
88 type Output = Norm3D;
89
90 fn neg(self) -> Norm3D {
91 Norm3D {
92 x: -self.x,
93 y: -self.y,
94 z: -self.z,
95 }
96 }
97}
98
99impl Neg for &Norm3D {
100 type Output = Norm3D;
101
102 fn neg(self) -> Norm3D {
103 Norm3D {
104 x: -self.x,
105 y: -self.y,
106 z: -self.z,
107 }
108 }
109}
110
111impl IsND for Norm3D {
112 fn n_dimensions() -> usize {
113 3
114 }
115
116 fn position_nd(&self, dimension: usize) -> Result<f64> {
117 match dimension {
118 0 => Ok(self.x),
119 1 => Ok(self.y),
120 2 => Ok(self.z),
121 _ => Err(ErrorKind::IncorrectDimension),
122 }
123 }
124}
125
126impl Is3D for Norm3D {
127 #[inline(always)]
128 fn x(&self) -> f64 {
129 self.x
130 }
131
132 #[inline(always)]
133 fn y(&self) -> f64 {
134 self.y
135 }
136
137 #[inline(always)]
138 fn z(&self) -> f64 {
139 self.z
140 }
141}
142
143impl IsNormalized3D for Norm3D {
144 fn new<P>(p: P) -> Result<Self>
145 where
146 P: Is3D,
147 {
148 let l = p.abs().get();
149 if l == 0.0 {
150 return Err(ErrorKind::NormalizeVecWithoutLength);
151 }
152
153 let f = 1.0 / l;
154
155 Ok(Norm3D {
156 x: f * p.x(),
157 y: f * p.y(),
158 z: f * p.z(),
159 })
160 }
161}