1mod hprtree;
2pub use crate::hprtree::*;
3mod hprtree_wrapping;
4pub use crate::hprtree_wrapping::*;
5
6#[derive(Clone, Debug)]
10pub struct BBox {
11 pub minx: CoordinateType,
12 pub miny: CoordinateType,
13 pub maxx: CoordinateType,
14 pub maxy: CoordinateType,
15}
16
17impl Default for BBox {
18 fn default() -> Self {
22 Self {
23 minx: CoordinateType::MAX,
24 miny: CoordinateType::MAX,
25 maxx: CoordinateType::MIN,
26 maxy: CoordinateType::MIN,
27 }
28 }
29}
30
31impl BBox {
32 pub fn new(
33 minx: CoordinateType,
34 miny: CoordinateType,
35 maxx: CoordinateType,
36 maxy: CoordinateType,
37 ) -> Self {
38 Self {
39 minx,
40 miny,
41 maxx,
42 maxy,
43 }
44 }
45
46 pub fn width(&self) -> CoordinateType {
48 self.maxx - self.minx
49 }
50
51 pub fn height(&self) -> CoordinateType {
53 self.maxy - self.miny
54 }
55
56 pub fn expand_to_include(&mut self, other: &Self) {
58 self.minx = self.minx.min(other.minx);
59 self.miny = self.miny.min(other.miny);
60 self.maxx = self.maxx.max(other.maxx);
61 self.maxy = self.maxy.max(other.maxy);
62 }
63
64 pub fn expand_to_include_point(&mut self, point: &Point) {
66 self.minx = self.minx.min(point.x);
67 self.miny = self.miny.min(point.y);
68 self.maxx = self.maxx.max(point.x);
69 self.maxy = self.maxy.max(point.y);
70 }
71
72 pub fn expand_to_include_spatially_indexable(&mut self, point: &impl SpatiallyIndexable) {
74 self.minx = self.minx.min(point.x());
75 self.miny = self.miny.min(point.y());
76 self.maxx = self.maxx.max(point.x());
77 self.maxy = self.maxy.max(point.y());
78 }
79
80 pub fn contains(&self, other: &Point) -> bool {
82 !(other.x > self.maxx || other.x < self.minx || other.y > self.maxy || other.y < self.miny)
83 }
84
85 pub fn contains_spatially_indexable(&self, other: &impl SpatiallyIndexable) -> bool {
87 !(other.x() > self.maxx
88 || other.x() < self.minx
89 || other.y() > self.maxy
90 || other.y() < self.miny)
91 }
92
93 pub fn intersects(&self, other: &Self) -> bool {
95 !(other.minx > self.maxx
96 || other.maxx < self.minx
97 || other.miny > self.maxy
98 || other.maxy < self.miny)
99 }
100}
101
102#[derive(Clone, Debug)]
104pub struct Point {
105 pub x: CoordinateType,
106 pub y: CoordinateType,
107}
108
109impl SpatiallyIndexable for Point {
110 fn x(&self) -> CoordinateType {
111 self.x
112 }
113
114 fn y(&self) -> CoordinateType {
115 self.y
116 }
117}
118
119pub trait SpatiallyIndexable {
121 fn x(&self) -> CoordinateType;
122 fn y(&self) -> CoordinateType;
123}
124
125const NODE_CAPACITY: usize = 16;
126const HILBERT_LEVEL: usize = 12;
127const H: usize = (1 << HILBERT_LEVEL) - 1;
128
129fn interleave(x: u32) -> u32 {
130 let x = (x | (x << 8)) & 0x00FF00FF;
131 let x = (x | (x << 4)) & 0x0F0F0F0F;
132 let x = (x | (x << 2)) & 0x33333333;
133 (x | (x << 1)) & 0x55555555
134}
135
136#[allow(non_snake_case)]
137fn hilbert_xy_to_index(x: u32, y: u32) -> u32 {
138 let x = x << (16 - HILBERT_LEVEL);
139 let y = y << (16 - HILBERT_LEVEL);
140
141 let mut A: u32;
142 let mut B: u32;
143 let mut C: u32;
144 let mut D: u32;
145
146 {
148 let a = x ^ y;
149 let b = 0xFFFF ^ a;
150 let c = 0xFFFF ^ (x | y);
151 let d = x & (y ^ 0xFFFF);
152
153 A = a | (b >> 1);
154 B = (a >> 1) ^ a;
155
156 C = ((c >> 1) ^ (b & (d >> 1))) ^ c;
157 D = ((a & (c >> 1)) ^ (d >> 1)) ^ d;
158 }
159
160 {
161 let a = A;
162 let b = B;
163 let c = C;
164 let d = D;
165
166 A = (a & (a >> 2)) ^ (b & (b >> 2));
167 B = (a & (b >> 2)) ^ (b & ((a ^ b) >> 2));
168
169 C ^= (a & (c >> 2)) ^ (b & (d >> 2));
170 D ^= (b & (c >> 2)) ^ ((a ^ b) & (d >> 2));
171 }
172
173 {
174 let a = A;
175 let b = B;
176 let c = C;
177 let d = D;
178
179 A = (a & (a >> 4)) ^ (b & (b >> 4));
180 B = (a & (b >> 4)) ^ (b & ((a ^ b) >> 4));
181
182 C ^= (a & (c >> 4)) ^ (b & (d >> 4));
183 D ^= (b & (c >> 4)) ^ ((a ^ b) & (d >> 4));
184 }
185
186 {
188 let a = A;
189 let b = B;
190 let c = C;
191 let d = D;
192
193 C ^= (a & (c >> 8)) ^ (b & (d >> 8));
194 D ^= (b & (c >> 8)) ^ ((a ^ b) & (d >> 8));
195 }
196
197 let a = C ^ (C >> 1);
199 let b = D ^ (D >> 1);
200
201 let i0 = x ^ y;
203 let i1 = b | (0xFFFF ^ (i0 | a));
204
205 ((interleave(i1) << 1) | interleave(i0)) >> (32 - 2 * HILBERT_LEVEL)
206}
207
208fn get_layer_size(layer: usize, layer_start_index: &[usize]) -> usize {
209 layer_start_index[layer + 1] - layer_start_index[layer]
210}
211
212pub type CoordinateType = f32;