@@ -111,7 +111,7 @@ where
self.root = Some(new_parent);
}
- for node_index in self.stack.drain(..) {
+ for node_index in self.stack.drain(..).rev() {
let Node::Internal {
max_order: max_ordering,
..
@@ -119,7 +119,10 @@ where
else {
unreachable!()
};
- *max_ordering = cmp::max(*max_ordering, ordering);
+ if *max_ordering >= ordering {
+ break;
+ }
+ *max_ordering = ordering;
}
ordering
@@ -237,6 +240,7 @@ where
mod tests {
use super::*;
use crate::{Bounds, Point, Size};
+ use rand::{Rng, SeedableRng};
#[test]
fn test_insert() {
@@ -294,4 +298,40 @@ mod tests {
assert_eq!(tree.insert(bounds5), 1); // bounds5 does not overlap with any other bounds
assert_eq!(tree.insert(bounds6), 2); // bounds6 overlaps with bounds4, so it should have a different order
}
+
+ #[test]
+ fn test_random_iterations() {
+ let max_bounds = 100;
+ for seed in 1..=1000 {
+ // let seed = 44;
+ let mut tree = BoundsTree::default();
+ let mut rng = rand::rngs::StdRng::seed_from_u64(seed as u64);
+ let mut expected_quads: Vec<(Bounds<f32>, u32)> = Vec::new();
+
+ // Insert a random number of random AABBs into the tree.
+ let num_bounds = rng.gen_range(1..=max_bounds);
+ for _ in 0..num_bounds {
+ let min_x: f32 = rng.gen_range(-100.0..100.0);
+ let min_y: f32 = rng.gen_range(-100.0..100.0);
+ let width: f32 = rng.gen_range(0.0..50.0);
+ let height: f32 = rng.gen_range(0.0..50.0);
+ let bounds = Bounds {
+ origin: Point { x: min_x, y: min_y },
+ size: Size { width, height },
+ };
+
+ let expected_ordering = expected_quads
+ .iter()
+ .filter_map(|quad| quad.0.intersects(&bounds).then_some(quad.1))
+ .max()
+ .unwrap_or(0)
+ + 1;
+ expected_quads.push((bounds, expected_ordering));
+
+ // Insert the AABB into the tree and collect intersections.
+ let actual_ordering = tree.insert(bounds);
+ assert_eq!(actual_ordering, expected_ordering);
+ }
+ }
+ }
}