1use crate::Pt3;
25
26#[derive(Clone, PartialEq)]
28pub struct Pt4s {
29 inner: Vec<Pt4>,
30}
31
32impl std::ops::Deref for Pt4s {
33 type Target = Vec<Pt4>;
34
35 fn deref(&self) -> &Self::Target {
36 &self.inner
37 }
38}
39
40impl std::ops::DerefMut for Pt4s {
41 fn deref_mut(&mut self) -> &mut Self::Target {
42 &mut self.inner
43 }
44}
45
46impl std::fmt::Display for Pt4s {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 write!(f, "[")?;
49 for i in 0..self.len() - 1 {
50 write!(f, "{},", self[i])?
51 }
52 write!(f, "{}]", self[self.len() - 1])
53 }
54}
55
56impl Pt4s {
57 pub fn new() -> Self {
58 Self { inner: Vec::new() }
59 }
60
61 pub fn with_capacity(capacity: usize) -> Self {
62 Self {
63 inner: Vec::with_capacity(capacity),
64 }
65 }
66
67 pub fn from_pt4s(pt4s: Vec<Pt4>) -> Self {
68 Self { inner: pt4s }
69 }
70}
71
72#[derive(Clone, Copy, Debug, Default, PartialEq)]
74pub struct Pt4 {
75 pub x: f64,
76 pub y: f64,
77 pub z: f64,
78 pub w: f64,
79}
80
81impl std::fmt::Display for Pt4 {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
84 }
85}
86
87impl std::ops::Index<usize> for Pt4 {
88 type Output = f64;
89
90 fn index(&self, index: usize) -> &Self::Output {
91 match index {
92 0 => &self.x,
93 1 => &self.y,
94 2 => &self.z,
95 3 => &self.w,
96 _ => panic!("Index {} is out of bounds.", index),
97 }
98 }
99}
100
101impl std::ops::IndexMut<usize> for Pt4 {
102 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
103 match index {
104 0 => &mut self.x,
105 1 => &mut self.y,
106 2 => &mut self.z,
107 3 => &mut self.w,
108 _ => panic!("Index {} is out of bounds.", index),
109 }
110 }
111}
112
113impl std::ops::Add for Pt4 {
114 type Output = Self;
115
116 fn add(self, rhs: Self) -> Self::Output {
117 Self::new(
118 self.x + rhs.x,
119 self.y + rhs.y,
120 self.z + rhs.z,
121 self.w + rhs.w,
122 )
123 }
124}
125
126impl std::ops::AddAssign for Pt4 {
127 fn add_assign(&mut self, rhs: Self) {
128 *self = *self + rhs;
129 }
130}
131
132impl std::ops::Sub for Pt4 {
133 type Output = Self;
134
135 fn sub(self, rhs: Self) -> Self::Output {
136 Self::new(
137 self.x - rhs.x,
138 self.y - rhs.y,
139 self.z - rhs.z,
140 self.w - rhs.w,
141 )
142 }
143}
144
145impl std::ops::SubAssign for Pt4 {
146 fn sub_assign(&mut self, rhs: Self) {
147 *self = *self - rhs;
148 }
149}
150
151impl std::ops::Mul<f64> for Pt4 {
152 type Output = Self;
153
154 fn mul(self, rhs: f64) -> Self::Output {
155 Self::new(self.x * rhs, self.y * rhs, self.z * rhs, self.w * rhs)
156 }
157}
158
159impl std::ops::MulAssign<f64> for Pt4 {
160 fn mul_assign(&mut self, rhs: f64) {
161 *self = *self * rhs;
162 }
163}
164
165impl std::ops::Div<f64> for Pt4 {
166 type Output = Self;
167
168 fn div(self, rhs: f64) -> Self::Output {
169 Self::new(self.x / rhs, self.y / rhs, self.z / rhs, self.w / rhs)
170 }
171}
172
173impl std::ops::DivAssign<f64> for Pt4 {
174 fn div_assign(&mut self, rhs: f64) {
175 *self = *self / rhs;
176 }
177}
178
179impl std::ops::Neg for Pt4 {
180 type Output = Self;
181
182 fn neg(self) -> Self::Output {
183 self * -1.0
184 }
185}
186
187impl Pt4 {
188 pub fn new(x: f64, y: f64, z: f64, w: f64) -> Self {
189 Self { x, y, z, w }
190 }
191
192 pub fn dot(self, rhs: Self) -> f64 {
193 self.x * rhs.x + self.y * rhs.y + self.z * rhs.z
194 }
195
196 pub fn cross(self, rhs: Self) -> Self {
197 Pt4::new(
198 self.y * rhs.z - self.z * rhs.y,
199 self.z * rhs.x - self.x * rhs.z,
200 self.x * rhs.y - self.y * rhs.x,
201 0.0,
202 )
203 }
204
205 pub fn len2(self) -> f64 {
206 self.dot(self)
207 }
208
209 pub fn len(self) -> f64 {
210 self.len2().sqrt()
211 }
212
213 pub fn normalize(&mut self) {
214 *self /= self.len();
215 }
216
217 pub fn normalized(self) -> Self {
218 let l = self.len();
219 Self::new(self.x / l, self.y / l, self.z / l, 0.0)
220 }
221
222 pub fn lerp(self, b: Self, t: f64) -> Self {
223 self + (b - self) * t
224 }
225
226 pub fn as_pt3(&self) -> Pt3 {
227 Pt3::new(self.x, self.y, self.z)
228 }
229}