From 969c84d9cc1bc1cd71fb1b195712d5e6a78b6c49 Mon Sep 17 00:00:00 2001 From: Joe Date: Wed, 21 Jan 2026 19:02:22 -0800 Subject: [PATCH] all impl'd, should work --- .rustfmt.toml | 4 +++ src/spindex.rs | 69 ++++++++++++++++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 25 deletions(-) create mode 100644 .rustfmt.toml diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..8feb93e --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,4 @@ +imports_granularity = "Crate" +group_imports = "StdExternalCrate" +wrap_comments = true +edition = "2024" diff --git a/src/spindex.rs b/src/spindex.rs index 00cb114..2d5ef6f 100644 --- a/src/spindex.rs +++ b/src/spindex.rs @@ -1,10 +1,11 @@ -use crate::geom::Point; +use std::cmp::Ordering; + use bevy::{ math::bounding::{Aabb2d, BoundingVolume, IntersectsVolume}, prelude::*, }; -use ordered_float::OrderedFloat; -use std::{cmp::Ordering, collections::BinaryHeap}; + +use crate::geom::Point; // Epsilon value for zero-sizes bounding boxes/cubes. const EPSILON: f32 = 1e-10; @@ -37,16 +38,15 @@ pub struct TreeNode { /// R*‑tree data structure for indexing 2D or 3D points. /// -/// The tree is initialized with a maximum number of entries per node. If a node exceeds this -/// number, it will split. The tree supports insertion, deletion, and range searches. +/// The tree is initialized with a maximum number of entries per node. If a node +/// exceeds this number, it will split. The tree supports insertion, deletion, +/// and range searches. #[derive(Debug, Clone)] pub struct RStarTree { root: TreeNode, max_entries: usize, - min_entries: usize, } -// Common trait implementations for R*-tree to reuse shared algorithms. impl Entry { fn as_leaf_obj(&self) -> Option<&Point> { match self { @@ -94,18 +94,18 @@ impl TreeNode { let mut result = Vec::new(); if self.is_leaf() { for entry in self.entries() { - if let Some(obj) = entry.as_leaf_obj() { - if entry.mbr().intersects(bbox) { - result.push(obj); - } + if let Some(obj) = entry.as_leaf_obj() + && entry.mbr().intersects(bbox) + { + result.push(obj); } } } else { for entry in self.entries() { - if let Some(child) = entry.child() { - if entry.mbr().intersects(bbox) { - result.extend_from_slice(&child.range_search_bbox(bbox)); - } + if let Some(child) = entry.child() + && entry.mbr().intersects(bbox) + { + result.extend_from_slice(&child.range_search_bbox(bbox)); } } } @@ -119,14 +119,13 @@ impl TreeNode { impl RStarTree { pub fn new(max_entries: usize) -> Self { - let max_entries = max_entries.max(2); + let max_entries = max_entries.max(4); RStarTree { root: TreeNode { entries: Vec::new(), is_leaf: true, }, max_entries, - min_entries: (max_entries as f32 * 0.4).ceil() as usize, } } @@ -159,11 +158,11 @@ impl RStarTree { if reinsert_level == Some(overflow_level) { let old_entries = overflowed_node; let (group1, group2) = split_entries(old_entries, self.max_entries); - let mut mbr1 = group1[0].mbr().clone(); + let mut mbr1 = *group1[0].mbr(); for entry in group1.iter() { mbr1 = mbr1.merge(entry.mbr()); } - let mut mbr2 = group2[0].mbr().clone(); + let mut mbr2 = *group2[0].mbr(); for entry in group2.iter() { mbr2 = mbr2.merge(entry.mbr()); } @@ -212,7 +211,8 @@ impl RStarTree { /// /// # Returns /// - /// A vector of references to the objects whose minimum bounding volumes intersect the query. + /// A vector of references to the objects whose minimum bounding volumes + /// intersect the query. pub fn range_search_bbox(&self, query_bbox: &Aabb2d) -> Vec<&Point> { self.root.range_search_bbox(query_bbox) } @@ -481,11 +481,11 @@ fn split_entries(mut entries: Vec, max_entries: usize) -> (Vec, Ve for k in min_entries..=entries.len() - min_entries { let group1 = &entries[..k]; let group2 = &entries[k..]; - let mut mbr1 = group1[0].mbr().clone(); + let mut mbr1 = *group1[0].mbr(); for entry in group1 { mbr1 = mbr1.merge(entry.mbr()); } - let mbr2 = group2[0].mbr().clone(); + let mbr2 = *group2[0].mbr(); let margin = mbr1.margin() + mbr2.margin(); if margin < min_margin { @@ -532,7 +532,8 @@ fn split_entries(mut entries: Vec, max_entries: usize) -> (Vec, Ve impl RStarTree { /// Performs a range search on the R*‑tree using a query object and radius. /// - /// The query object is wrapped into a bounding volume using `from_point_radius`. + /// The query object is wrapped into a bounding volume using + /// `from_point_radius`. /// /// # Arguments /// @@ -555,7 +556,7 @@ impl RStarTree { fn entries_mbr(entries: &[Entry]) -> Option { let mut iter = entries.iter(); - let first = iter.next()?.mbr().clone(); + let first = *iter.next()?.mbr(); Some(iter.fold(first, |acc, entry| acc.merge(entry.mbr()))) } @@ -572,6 +573,24 @@ impl Bvr for Aabb2d { } fn overlap(&self, other: &Aabb2d) -> f32 { - todo!() + let Vec2 { + x: self_width, + y: self_height, + } = 2.0 * self.half_size(); + + let self_center = self.center(); + let other_center = other.center(); + + let Vec2 { + x: other_width, + y: other_height, + } = 2.0 * other.half_size(); + + let o_x = (self_center.x + self_width).min(other_center.x + other_width) + - self_center.x.max(other_center.x); + let o_y = (self_center.y + self_height).min(other_center.y + other_height) + - self_center.y.max(other_center.y); + + (o_x * o_y).max(0.0) } }