etiles_core/
bounding_volume.rs

1use ecoord::AxisAlignedBoundingCube;
2use eproj::Coordinate3;
3use nalgebra::{Point3, Vector3};
4
5#[derive(Debug, Clone, Copy)]
6pub struct BoundingCube {
7    center: Point3<f64>,
8    width: f64,
9}
10
11impl BoundingCube {
12    pub fn new(center: Point3<f64>, width: f64) -> Self {
13        Self { center, width }
14    }
15
16    pub fn from_axis_aligned_bounding_cube(bounding_cube: &AxisAlignedBoundingCube) -> Self {
17        Self {
18            center: bounding_cube.center(),
19            width: bounding_cube.edge_length(),
20        }
21    }
22
23    pub fn get_lower_bound(&self) -> Point3<f64> {
24        self.center - Vector3::new(self.width, self.width, self.width)
25    }
26
27    pub fn get_upper_bound(&self) -> Point3<f64> {
28        self.center + Vector3::new(self.width, self.width, self.width)
29    }
30
31    pub fn center_vector(&self) -> Vector3<f64> {
32        self.center.coords
33    }
34
35    pub fn get_octant(&self, x_half: bool, y_half: bool, z_half: bool) -> BoundingCube {
36        let octant_width = self.width / 2.0;
37        let x_sign = if x_half { 1.0 } else { -1.0 };
38        let y_sign = if y_half { 1.0 } else { -1.0 };
39        let z_sign = if z_half { 1.0 } else { -1.0 };
40
41        let octant_center = self.center
42            + Vector3::new(
43                octant_width * x_sign,
44                octant_width * y_sign,
45                octant_width * z_sign,
46            );
47
48        Self::new(octant_center, octant_width)
49    }
50
51    pub fn x_axis(&self) -> Vector3<f64> {
52        Vector3::new(self.width / 2.0, 0.0, 0.0)
53    }
54
55    pub fn y_axis(&self) -> Vector3<f64> {
56        Vector3::new(0.0, self.width / 2.0, 0.0)
57    }
58
59    pub fn z_axis(&self) -> Vector3<f64> {
60        Vector3::new(0.0, 0.0, self.width / 2.0)
61    }
62
63    pub fn bounding_array(&self) -> [f64; 12] {
64        let center_vec = self.center_vector();
65        let x_axis_vec = self.x_axis();
66        let y_axis_vec = self.y_axis();
67        let z_axis_vec = self.z_axis();
68
69        [
70            center_vec.x,
71            center_vec.y,
72            center_vec.z,
73            x_axis_vec.x,
74            x_axis_vec.y,
75            x_axis_vec.z,
76            y_axis_vec.x,
77            y_axis_vec.y,
78            y_axis_vec.z,
79            z_axis_vec.x,
80            z_axis_vec.y,
81            z_axis_vec.z,
82        ]
83    }
84}
85
86#[derive(Debug, Clone, Copy)]
87pub struct BoundingRegion {
88    south_west_min_height: Coordinate3,
89    north_east_max_height: Coordinate3,
90}
91
92impl BoundingRegion {
93    pub fn new(south_west_min_height: Coordinate3, north_east_max_height: Coordinate3) -> Self {
94        Self {
95            south_west_min_height,
96            north_east_max_height,
97        }
98    }
99
100    pub fn as_array(&self) -> [f64; 6] {
101        let south_west_min_height_radian = self.south_west_min_height.to_radians();
102        let north_east_max_height_radian = self.north_east_max_height.to_radians();
103
104        [
105            south_west_min_height_radian.x(),
106            south_west_min_height_radian.y(),
107            north_east_max_height_radian.x(),
108            north_east_max_height_radian.y(),
109            south_west_min_height_radian.z(),
110            north_east_max_height_radian.z(),
111        ]
112    }
113}