etiles_core/
bounding_volume.rs1use 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}