Skip to main content

aeon_tk/geometry/
box.rs

1use std::array::{self, from_fn};
2
3use datasize::DataSize;
4
5use crate::geometry::Split;
6
7/// Represents a rectangular physical domain.
8#[derive(Debug, Copy, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
9pub struct HyperBox<const N: usize> {
10    /// Size of the rectangle along each axis.
11    #[serde(with = "crate::array")]
12    pub size: [f64; N],
13    /// Origin of the rectangle (located at the bottom-left corner).
14    #[serde(with = "crate::array")]
15    pub origin: [f64; N],
16}
17
18impl<const N: usize> DataSize for HyperBox<N> {
19    const IS_DYNAMIC: bool = false;
20    const STATIC_HEAP_SIZE: usize = 0;
21
22    fn estimate_heap_size(&self) -> usize {
23        0
24    }
25}
26
27impl<const N: usize> HyperBox<N> {
28    /// Unit rectangle.
29    pub const UNIT: Self = HyperBox {
30        size: [1.0; N],
31        origin: [0.0; N],
32    };
33
34    /// Constructs a rectangle from an aabb.
35    pub fn from_aabb(aa: [f64; N], bb: [f64; N]) -> Self {
36        let size = array::from_fn(|axis| (bb[axis] - aa[axis]).max(0.0));
37        Self { size, origin: aa }
38    }
39
40    /// Computes the center of the rectangle.
41    pub fn center(&self) -> [f64; N] {
42        array::from_fn(|i| self.origin[i] + self.size[i] / 2.0)
43    }
44
45    /// Returns true if the rectangle contains a point.
46    pub fn contains(&self, point: [f64; N]) -> bool {
47        for axis in 0..N {
48            if point[axis] < self.origin[axis] || point[axis] > self.origin[axis] + self.size[axis]
49            {
50                return false;
51            }
52        }
53
54        true
55    }
56
57    /// Subdivides the rectangle.
58    pub fn subdivide(&self, split: Split<N>) -> Self {
59        let size = array::from_fn(|i| self.size[i] / 2.0);
60        let origin = array::from_fn(|i| {
61            if split.is_set(i) {
62                self.origin[i] + self.size[i] / 2.0
63            } else {
64                self.origin[i]
65            }
66        });
67
68        Self { size, origin }
69    }
70
71    pub fn aa(&self) -> [f64; N] {
72        self.origin
73    }
74
75    pub fn bb(&self) -> [f64; N] {
76        from_fn(|i| self.origin[i] + self.size[i])
77    }
78
79    pub fn local_to_global(&self, local: [f64; N]) -> [f64; N] {
80        array::from_fn(|axis| local[axis] * self.size[axis] + self.origin[axis])
81    }
82
83    pub fn global_to_local(&self, global: [f64; N]) -> [f64; N] {
84        array::from_fn(|axis| (global[axis] - self.origin[axis]) / self.size[axis])
85    }
86}