devela/num/geom/metric/extent/
methods.rs
1use super::{Extent, Extent2d, Extent3d};
7use crate::{cfor, iif, Bound, ConstDefault, Interval};
8
9#[rustfmt::skip]
10impl<T, const D: usize> Extent<T, D> {
11 pub const fn new(dimensions: [T; D]) -> Self {
13 Self { size: dimensions }
14 }
15
16 #[must_use]
18 pub const fn as_slice(&self) -> &[T] {
19 &self.size
20 }
21 #[must_use]
23 pub fn as_slice_mut(&mut self) -> &mut [T] {
24 &mut self.size
25 }
26
27 #[must_use]
29 pub fn is_uniform_nd(&self) -> bool where T: PartialEq {
30 iif![D == 0; return true];
31 let mut i = 1;
32 while i < D {
33 iif![self.size[i] != self.size[0]; return false];
34 i += 1;
35 }
36 true
37 }
38}
39
40impl<T, const D: usize> Extent<T, D> {
43 #[must_use]
45 pub fn as_intervals(self) -> [Interval<T>; D]
46 where
47 T: Default,
48 {
49 self.size.map(|dim| Interval {
50 lower: Bound::Included(T::default()),
51 upper: Bound::Included(dim),
52 })
53 }
54
55 #[must_use]
57 pub const fn as_intervals_const(self) -> [Interval<T>; D]
58 where
59 T: Copy + ConstDefault,
60 {
61 let mut intervals = [Interval {
62 lower: Bound::Included(T::DEFAULT),
63 upper: Bound::Included(T::DEFAULT),
64 }; D];
65 let mut i = 0;
66 while i < D {
67 intervals[i] = Interval {
68 lower: Bound::Included(T::DEFAULT),
69 upper: Bound::Included(self.size[i]),
70 };
71 i += 1;
72 }
73 intervals
74 }
75
76 #[must_use]
78 pub fn to_intervals(&self) -> [Interval<T>; D]
79 where
80 T: Clone + Default,
81 {
82 self.size.clone().map(|dim| Interval {
83 lower: Bound::Included(T::default()),
84 upper: Bound::Included(dim),
85 })
86 }
87
88 #[must_use]
90 pub fn fits_within(&self, interval: &Interval<T>) -> bool
91 where
92 T: PartialOrd,
93 {
94 self.size.iter().all(|dim| {
95 matches!(interval.lower, Bound::Included(ref lb) if dim >= lb)
96 && matches!(interval.upper, Bound::Included(ref ub) if dim <= ub)
97 })
98 }
99}
100
101#[rustfmt::skip]
104impl<T> Extent2d<T> {
105 #[must_use]
107 pub const fn x(self) -> T where T: Copy { self.size[0] }
108 #[must_use]
110 pub const fn y(self) -> T where T: Copy { self.size[1] }
111
112 #[must_use]
114 pub const fn x_ref(&self) -> &T { &self.size[0] }
115 #[must_use]
117 pub const fn y_ref(&self) -> &T { &self.size[1] }
118
119 #[must_use]
121 pub fn x_mut(&mut self) -> &mut T { &mut self.size[0] }
122 #[must_use]
124 pub fn y_mut(&mut self) -> &mut T { &mut self.size[1] }
125
126 #[must_use]
128 pub fn is_uniform(&self) -> bool where T: PartialEq {
129 self.size[0] == self.size[1]
130 }
131}
132
133#[rustfmt::skip]
134impl<T> Extent3d<T> {
135 #[must_use]
137 pub const fn x(self) -> T where T: Copy { self.size[0] }
138 #[must_use]
140 pub const fn y(self) -> T where T: Copy { self.size[1] }
141 #[must_use]
143 pub const fn z(self) -> T where T: Copy { self.size[2] }
144
145 #[must_use]
147 pub const fn x_ref(&self) -> &T { &self.size[0] }
148 #[must_use]
150 pub const fn y_ref(&self) -> &T { &self.size[1] }
151 #[must_use]
153 pub const fn z_ref(&self) -> &T { &self.size[2] }
154
155 #[must_use]
157 pub fn x_mut(&mut self) -> &mut T { &mut self.size[0] }
158 #[must_use]
160 pub fn y_mut(&mut self) -> &mut T { &mut self.size[1] }
161 #[must_use]
163 pub fn z_mut(&mut self) -> &mut T { &mut self.size[2] }
164
165 #[must_use]
167 pub fn is_uniform_3d(&self) -> bool where T: PartialEq {
168 self.size[0] == self.size[1] && self.size[0] == self.size[2]
169 }
170}
171
172macro_rules! impl_extent {
174 () => {
175 impl_extent![sint i8, i16, i32, i64, i128, isize];
176 impl_extent![uint u8, u16, u32, u64, u128, usize];
177 impl_extent![float f32, f64];
178 };
179 (int $($t:ty),+) => { $( impl_extent![@int $t]; )+ };
183 (@int $t:ty) => {
184 impl<const D: usize> Extent<$t, D> {
185 pub const fn c_measure(self) -> $t {
189 let mut measure = 1;
190 cfor!(i in 0..D => {
191 measure *= self.size[i];
192 });
193 measure
194 }
195 pub const fn c_boundary(self) -> $t {
199 let mut boundary = 0;
200 cfor!(i in 0..D => {
201 let mut face_measure = 1;
202 cfor!(j in 0..D => {
203 iif![i != j; face_measure *= self.size[j]];
204 });
205 boundary += face_measure;
206 });
207 2 * boundary }
209 }
210
211 impl Extent<$t, 1> {
212 #[must_use]
214 pub const fn c_length(self) -> $t { self.size[0] }
215 }
216 impl Extent2d<$t> {
217 #[must_use]
219 pub const fn c_area(self) -> $t { self.size[0] * self.size[1] }
220
221 #[must_use]
223 pub const fn c_perimeter(self) -> $t { 2 * (self.size[0] + self.size[1]) }
224
225 }
226 impl Extent3d<$t> {
227 #[must_use]
229 pub const fn c_volume(self) -> $t {
230 self.size[0] * self.size[1] * self.size[2]
231 }
232
233 #[must_use]
235 pub const fn c_surface_area(self) -> $t {
236 2 * (self.size[0] * self.size[1]
237 + self.size[1] * self.size[2]
238 + self.size[2] * self.size[0])
239 }
240 }
241 };
242
243 (sint $($t:ty),+) => { $( impl_extent![@sint $t]; )+ };
244 (@sint $t:ty ) => {
245 impl_extent![int $t];
246 };
247 (uint $($t:ty),+) => { $( impl_extent![@uint $t]; )+ };
248 (@uint $t:ty ) => {
249 impl_extent![int $t];
250 };
251
252 (float $($f:ty),+) => { $( impl_extent![@float $f]; )+ };
254 (@float $f:ty) => {
255 impl<const D: usize> Extent<$f, D> {
256 #[must_use]
260 pub const fn measure(self) -> $f {
261 let mut measure = 1.0;
262 cfor!(i in 0..D => {
263 measure *= self.size[i];
264 });
265 measure
266 }
267 #[must_use]
271 pub const fn boundary(self) -> $f {
272 let mut boundary = 0.0;
273 cfor!(i in 0..D => {
274 let mut face_measure = 1.0;
275 cfor!(j in 0..D => {
276 iif![i != j; face_measure *= self.size[j]];
277 });
278 boundary += face_measure;
279 });
280 2.0 * boundary }
282 }
283
284 impl Extent<$f, 1> {
285 #[must_use]
287 pub const fn length(self) -> $f { self.size[0] }
288 }
289 impl Extent2d<$f> {
290 #[must_use]
292 pub const fn area(self) -> $f { self.size[0] * self.size[1] }
293
294 #[must_use]
296 pub const fn perimeter(self) -> $f { 2.0 * (self.size[0] + self.size[1]) }
297
298 }
299 impl Extent3d<$f> {
300 #[must_use]
302 pub const fn volume(self) -> $f {
303 self.size[0] * self.size[1] * self.size[2]
304 }
305
306 #[must_use]
308 pub const fn surface_area(self) -> $f {
309 2.0 * (self.size[0] * self.size[1]
310 + self.size[1] * self.size[2]
311 + self.size[2] * self.size[0])
312 }
313 }
314 };
315}
316impl_extent![];