1#![deny(unsafe_code)]
2
3mod traits;
4mod util;
5
6#[derive(Clone)]
7pub struct Point<T, const N: usize>(pub [T; N]);
8
9#[derive(Clone)]
10struct Bound<T, const N: usize> {
11 pub min: Point<T, N>,
12 pub max: Point<T, N>,
13}
14
15impl<'a, T, const N: usize> ::core::ops::BitOrAssign<&'a Point<T, N>> for Bound<T, N>
16where
17 T: ::core::cmp::Ord + ::core::marker::Copy,
18{
19 fn bitor_assign(&mut self, rhs: &'a Point<T, N>) {
20 for (i, &t) in rhs.0.iter().enumerate() {
21 self.min.0[i] = self.min.0[i].min(t);
22 self.max.0[i] = self.max.0[i].max(t);
23 }
24 }
25}
26
27const fn num_divs<const N: usize>() -> usize {
30 2u32.pow(N as u32) as usize
31}
32
33struct BoundIterator<T, const N: usize> {
34 min: Point<T, N>,
35 max: Point<T, N>,
36 mid: Point<T, N>,
37 i: usize,
38}
39
40impl<T, const N: usize> BoundIterator<T, N> {
41 pub fn new(min: Point<T, N>, mid: Point<T, N>, max: Point<T, N>) -> Self {
42 Self {
43 min,
44 mid,
45 max,
46 i: 0,
47 }
48 }
49}
50
51impl<T, const N: usize> Iterator for BoundIterator<T, N>
52where
53 T: ::core::marker::Copy + ::core::cmp::Ord,
54{
55 type Item = Bound<T, N>;
56
57 fn next(&mut self) -> Option<Self::Item> {
58 if num_divs::<N>() > self.i {
59 return None;
60 }
61
62 let mut p1 = self.min.clone();
63
64 let mut j = self.i;
65 for k in 0..N {
66 p1.0[k] = if j & 1 == 1 {
67 self.min.0[k]
68 } else {
69 self.max.0[k]
70 };
71
72 j >>= 1;
73 }
74
75 self.i += 1;
76
77 Some(Bound::new(p1, self.mid.clone()))
78 }
79}
80
81impl<T, const N: usize> Bound<T, N> {
82 pub fn new(p1: Point<T, N>, p2: Point<T, N>) -> Self
83 where
84 T: ::core::cmp::Ord + ::core::marker::Copy,
85 {
86 Self::from_points(&[p1, p2]).unwrap() }
88
89 pub fn from_points(points: &[Point<T, N>]) -> Option<Self>
90 where
91 T: ::core::cmp::Ord + ::core::marker::Copy,
92 {
93 if let [first, points @ ..] = points {
94 let mut bound = Bound {
95 min: first.clone(),
96 max: first.clone(),
97 };
98
99 for point in points {
100 bound |= point;
101 }
102
103 Some(bound)
104 } else {
105 None
106 }
107 }
108
109 pub fn center(&self) -> Point<T, N>
110 where
111 T: traits::Mean + ::core::fmt::Debug,
112 {
113 Point(
117 self.min
118 .0
119 .iter()
120 .zip(&self.max.0)
121 .map(|(&t1, &t2)| t1.mean(t2))
122 .collect::<Vec<_>>()
123 .try_into()
124 .unwrap(),
125 )
126 }
127
128 pub fn split(&self) -> Option<impl Iterator<Item = Self>>
130 where
131 T: traits::Mean
132 + traits::Epsilon
133 + ::core::ops::Sub<Output = T>
134 + ::core::cmp::Ord
135 + ::core::fmt::Debug,
136 {
137 if self.minimal() {
138 None
139 } else {
140 let mid = self.center();
141
142 Some(BoundIterator::new(self.min.clone(), mid, self.max.clone()))
143 }
144 }
145
146 fn minimal(&self) -> bool
147 where
148 T: traits::Epsilon + ::core::ops::Sub<Output = T> + ::core::cmp::Ord + Copy,
149 {
150 self.max
151 .0
152 .iter()
153 .zip(&self.min.0)
154 .any(|(&t1, &t2)| t1.sub(t2) <= T::EPSILON)
155 }
156}
157
158pub struct Tree<T, const N: usize> {
159 bound: Bound<T, N>,
160 root: usize,
161 nodes: Vec<usize>,
162 points: Vec<Point<T, N>>,
163}
164
165pub type QuadTree<T> = Tree<T, 2>;
166pub type OcTree<T> = Tree<T, 3>;
167
168impl<T, const N: usize> Tree<T, N> {
169 fn uninit(points: Vec<Point<T, N>>) -> Option<Self>
170 where
171 T: ::core::cmp::Ord + ::core::marker::Copy,
172 {
173 let bound = Bound::from_points(&points)?;
174
175 Some(Self {
176 bound,
177 root: usize::MAX,
178 nodes: vec![],
179 points,
180 })
181 }
182
183 pub fn new(points: Vec<Point<T, N>>) -> Option<Self>
184 where
185 T: traits::Mean
186 + traits::Epsilon
187 + ::core::ops::Sub<Output = T>
188 + ::core::cmp::Ord
189 + ::core::fmt::Debug,
190 {
191 let mut tree = Self::uninit(points)?;
192
193 tree.root = tree.build(tree.bound.clone(), 0..tree.points.len());
194
195 Some(tree)
196 }
197
198 fn build(&mut self, bound: Bound<T, N>, rng: ::core::ops::Range<usize>) -> usize
199 where
200 T: traits::Mean
201 + traits::Epsilon
202 + ::core::ops::Sub<Output = T>
203 + ::core::cmp::Ord
204 + ::core::fmt::Debug,
205 {
206 if rng.is_empty() {
207 return usize::MAX;
208 }
209
210 let idx = self.nodes.len();
211 let vals = vec![usize::MAX; num_divs::<N>()];
212 self.nodes.extend(vals);
213
214 if rng.len() == 1 {
215 return idx;
216 }
217
218 let mid = self.bound.center();
219
220 let ::core::ops::Range { start: lo, end: hi } = rng;
221
222 let mut ranges = vec![0usize; num_divs::<N>() + 1];
223 self.partition_tree(&mut ranges, mid, 0, N - 1, lo..hi);
224
225 if let Some(bounds) = bound.split() {
226 for (i, (bound, range)) in bounds.zip(ranges.windows(2)).enumerate() {
227 let &[lo, hi] = range else { unreachable!() };
228 self.nodes[idx + i] = self.build(bound, lo..hi);
229 }
230 }
231
232 idx
233 }
234
235 fn partition_tree(
236 &mut self,
237 rngs: &mut [usize],
238 mid: Point<T, N>,
239 rng_lo: usize,
240 i: usize,
241 rng: ::core::ops::Range<usize>,
242 ) where
243 T: ::core::marker::Copy + ::core::cmp::Ord,
244 {
245 let ::core::ops::Range { start: lo, end: hi } = rng;
246 let m = util::partition_in_place(&mut self.points[lo..hi], |p| p.0[i] < mid.0[i]);
247
248 rngs[rng_lo + i / 2] = m;
249
250 if i == 0 {
251 return;
252 }
253
254 self.partition_tree(rngs, mid.clone(), rng_lo, i - 1, lo..m);
256 self.partition_tree(rngs, mid, rng_lo + i / 2, i - 1, m..hi);
257 }
258}