#[cfg(test)]
mod test_point_optimizations {
use crate::prelude::*;
#[test]
fn test_add_point_method() {
let mut tree = AABB::with_capacity(3);
tree.add_point(0.0, 0.0);
tree.add_point(1.0, 1.0);
tree.add_point(2.0, 2.0);
tree.build();
assert_eq!(tree.len(), 3);
assert_eq!(tree.get(0).unwrap(), (0.0, 0.0, 0.0, 0.0));
assert_eq!(tree.get(1).unwrap(), (1.0, 1.0, 1.0, 1.0));
assert_eq!(tree.get(2).unwrap(), (2.0, 2.0, 2.0, 2.0));
}
#[test]
fn test_add_point_equivalent_to_add() {
let mut tree1 = AABB::with_capacity(2);
tree1.add_point(1.5, 2.5);
tree1.add_point(3.5, 4.5);
tree1.build();
let mut tree2 = AABB::with_capacity(2);
tree2.add(1.5, 1.5, 2.5, 2.5);
tree2.add(3.5, 3.5, 4.5, 4.5);
tree2.build();
let mut results1 = Vec::new();
tree1.query_circle_points(1.5, 2.5, 1.0, &mut results1);
let mut results2 = Vec::new();
tree2.query_circle(1.5, 2.5, 1.0, &mut results2);
assert_eq!(results1, results2);
}
#[test]
fn test_query_circle_points_basic() {
let mut tree = AABB::with_capacity(5);
tree.add(0.0, 0.0, 0.0, 0.0); tree.add(1.0, 1.0, 1.0, 1.0); tree.add(2.0, 2.0, 2.0, 2.0); tree.add(5.0, 5.0, 5.0, 5.0); tree.add(10.0, 10.0, 10.0, 10.0); tree.build();
let mut results = Vec::new();
tree.query_circle_points(0.0, 0.0, 2.5, &mut results);
assert_eq!(results.len(), 2);
assert_eq!(results[0], 0); assert_eq!(results[1], 1); }
#[test]
fn test_query_circle_points_no_results() {
let mut tree = AABB::with_capacity(2);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(10.0, 10.0, 10.0, 10.0);
tree.build();
let mut results = Vec::new();
tree.query_circle_points(5.0, 5.0, 1.0, &mut results);
assert!(results.is_empty());
}
#[test]
fn test_query_circle_points_all_within() {
let mut tree = AABB::with_capacity(4);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(1.0, 0.0, 1.0, 0.0);
tree.add(0.0, 1.0, 0.0, 1.0);
tree.add(1.0, 1.0, 1.0, 1.0);
tree.build();
let mut results = Vec::new();
tree.query_circle_points(0.5, 0.5, 2.0, &mut results);
assert_eq!(results.len(), 4);
}
#[test]
fn test_query_nearest_k_points_basic() {
let mut tree = AABB::with_capacity(5);
tree.add(0.0, 0.0, 0.0, 0.0); tree.add(1.0, 1.0, 1.0, 1.0); tree.add(2.0, 2.0, 2.0, 2.0); tree.add(5.0, 5.0, 5.0, 5.0); tree.add(10.0, 10.0, 10.0, 10.0); tree.build();
let mut results = Vec::new();
tree.query_nearest_k_points(0.0, 0.0, 3, &mut results);
assert_eq!(results.len(), 3);
assert_eq!(results[0], 0);
assert_eq!(results[1], 1);
assert_eq!(results[2], 2);
}
#[test]
fn test_query_nearest_k_points_k_too_large() {
let mut tree = AABB::with_capacity(2);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(1.0, 1.0, 1.0, 1.0);
tree.build();
let mut results = Vec::new();
tree.query_nearest_k_points(0.0, 0.0, 10, &mut results);
assert_eq!(results.len(), 2);
assert_eq!(results[0], 0);
assert_eq!(results[1], 1);
}
#[test]
fn test_query_nearest_k_points_k_one() {
let mut tree = AABB::with_capacity(3);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(1.0, 0.0, 1.0, 0.0);
tree.add(10.0, 10.0, 10.0, 10.0);
tree.build();
let mut results = Vec::new();
tree.query_nearest_k_points(0.0, 0.0, 1, &mut results);
assert_eq!(results.len(), 1);
assert_eq!(results[0], 0); }
#[test]
fn test_query_circle_points_sorting() {
let mut tree = AABB::with_capacity(4);
tree.add(3.0, 4.0, 3.0, 4.0); tree.add(1.0, 0.0, 1.0, 0.0); tree.add(0.0, 2.0, 0.0, 2.0); tree.add(0.0, 0.0, 0.0, 0.0); tree.build();
let mut results = Vec::new();
tree.query_circle_points(0.0, 0.0, 6.0, &mut results);
assert_eq!(results.len(), 4);
assert!(results.contains(&0));
assert!(results.contains(&1));
assert!(results.contains(&2));
assert!(results.contains(&3));
}
#[test]
fn test_query_nearest_k_points_negative_coords() {
let mut tree = AABB::with_capacity(3);
tree.add(-1.0, -1.0, -1.0, -1.0); tree.add(0.0, 0.0, 0.0, 0.0); tree.add(1.0, 1.0, 1.0, 1.0); tree.build();
let mut results = Vec::new();
tree.query_nearest_k_points(-1.0, -1.0, 2, &mut results);
assert_eq!(results.len(), 2);
assert_eq!(results[0], 0); assert_eq!(results[1], 1); }
#[test]
fn test_query_circle_points_empty_tree() {
let tree = AABB::new();
let mut results = Vec::new();
tree.query_circle_points(0.0, 0.0, 5.0, &mut results);
assert!(results.is_empty());
}
#[test]
fn test_query_nearest_k_points_empty_tree() {
let tree = AABB::new();
let mut results = Vec::new();
tree.query_nearest_k_points(0.0, 0.0, 3, &mut results);
assert!(results.is_empty());
}
#[test]
fn test_query_circle_points_negative_radius() {
let mut tree = AABB::with_capacity(2);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(1.0, 1.0, 1.0, 1.0);
tree.build();
let mut results = Vec::new();
tree.query_circle_points(0.0, 0.0, -1.0, &mut results);
assert!(results.is_empty());
}
#[test]
fn test_query_nearest_k_points_k_zero() {
let mut tree = AABB::with_capacity(2);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(1.0, 1.0, 1.0, 1.0);
tree.build();
let mut results = Vec::new();
tree.query_nearest_k_points(0.0, 0.0, 0, &mut results);
assert!(results.is_empty());
}
#[test]
fn test_query_circle_points_matches_general_query() {
let mut tree = AABB::with_capacity(5);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(1.0, 1.0, 1.0, 1.0);
tree.add(2.0, 2.0, 2.0, 2.0);
tree.add(3.0, 3.0, 3.0, 3.0);
tree.add(5.0, 5.0, 5.0, 5.0);
tree.build();
let mut results_optimized = Vec::new();
tree.query_circle_points(1.0, 1.0, 2.5, &mut results_optimized);
let mut results_general = Vec::new();
tree.query_circle(1.0, 1.0, 2.5, &mut results_general);
assert_eq!(results_optimized.len(), results_general.len());
let mut general_sorted = results_general.clone();
general_sorted.sort();
let mut optimized_sorted = results_optimized.clone();
optimized_sorted.sort();
assert_eq!(optimized_sorted, general_sorted);
}
#[test]
fn test_query_circle_points_large_cloud() {
let mut tree = AABB::with_capacity(100);
for i in 0..10 {
for j in 0..10 {
let x = i as f64;
let y = j as f64;
tree.add(x, x, y, y);
}
}
tree.build();
let mut results = Vec::new();
tree.query_circle_points(4.5, 4.5, 2.0, &mut results);
assert!(results.len() > 5);
}
#[test]
fn test_query_circle_points_results_cleared() {
let mut tree = AABB::with_capacity(3);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(1.0, 1.0, 1.0, 1.0);
tree.add(2.0, 2.0, 2.0, 2.0);
tree.build();
let mut results = vec![999]; tree.query_circle_points(0.0, 0.0, 0.5, &mut results);
assert_eq!(results.len(), 1);
assert_eq!(results[0], 0); }
#[test]
fn test_query_nearest_k_points_results_cleared() {
let mut tree = AABB::with_capacity(3);
tree.add(0.0, 0.0, 0.0, 0.0);
tree.add(1.0, 1.0, 1.0, 1.0);
tree.add(2.0, 2.0, 2.0, 2.0);
tree.build();
let mut results = vec![999, 888]; tree.query_nearest_k_points(0.0, 0.0, 2, &mut results);
assert_eq!(results.len(), 2);
assert!(results[0] == 0 || results[0] == 1);
assert!(results[1] == 0 || results[1] == 1);
assert!(results[0] != 999);
assert!(results[1] != 888);
}
#[test]
fn test_get_point_method() {
let mut tree = AABB::with_capacity(4);
tree.add_point(0.0, 0.0);
tree.add_point(1.5, 2.5);
tree.add_point(3.0, 4.0);
tree.add_point(-1.0, -1.0);
tree.build();
assert_eq!(tree.get_point(0), Some((0.0, 0.0)));
assert_eq!(tree.get_point(1), Some((1.5, 2.5)));
assert_eq!(tree.get_point(2), Some((3.0, 4.0)));
assert_eq!(tree.get_point(3), Some((-1.0, -1.0)));
assert_eq!(tree.get_point(4), None);
}
#[test]
fn test_get_point_before_build() {
let mut tree = AABB::with_capacity(2);
tree.add_point(1.0, 2.0);
tree.add_point(3.0, 4.0);
assert_eq!(tree.get_point(0), Some((1.0, 2.0)));
assert_eq!(tree.get_point(1), Some((3.0, 4.0)));
}
#[test]
fn test_query_circle_points_very_small_radius() {
let mut tree = AABB::with_capacity(5);
tree.add_point(0.0, 0.0);
tree.add_point(1.0, 0.0);
tree.add_point(0.0, 1.0);
tree.add_point(1.0, 1.0);
tree.add_point(0.5, 0.5);
tree.build();
let mut results = Vec::new();
tree.query_circle_points(0.0, 0.0, 1e-9, &mut results);
assert_eq!(results, vec![0], "Query with radius 1e-9 should only return exact point");
tree.query_circle_points(0.0, 0.0, 1e-6, &mut results);
assert_eq!(results, vec![0], "Query with radius 1e-6 should only return exact point");
}
#[test]
fn test_point_storage_after_build() {
let mut tree = AABB::with_capacity(5);
tree.add_point(0.0, 0.0);
tree.add_point(1.0, 0.0);
tree.add_point(0.0, 1.0);
tree.add_point(1.0, 1.0);
tree.add_point(0.5, 0.5);
tree.build();
assert_eq!(tree.get_point(0), Some((0.0, 0.0)));
assert_eq!(tree.get_point(1), Some((1.0, 0.0)));
assert_eq!(tree.get_point(2), Some((0.0, 1.0)));
assert_eq!(tree.get_point(3), Some((1.0, 1.0)));
assert_eq!(tree.get_point(4), Some((0.5, 0.5)));
}
#[test]
fn test_add_point_coordinate_order() {
let mut tree = AABB::with_capacity(3);
tree.add_point(1.5, 2.5);
tree.add_point(3.0, 4.0);
tree.add_point(-1.0, -2.0);
tree.build();
assert_eq!(tree.get_point(0), Some((1.5, 2.5)));
assert_eq!(tree.get_point(1), Some((3.0, 4.0)));
assert_eq!(tree.get_point(2), Some((-1.0, -2.0)));
assert_eq!(tree.get(0).unwrap(), (1.5, 2.5, 1.5, 2.5));
assert_eq!(tree.get(1).unwrap(), (3.0, 4.0, 3.0, 4.0));
assert_eq!(tree.get(2).unwrap(), (-1.0, -2.0, -1.0, -2.0));
}
#[test]
fn test_query_circle_points_consistency_with_get_point() {
let mut tree = AABB::with_capacity(10);
for i in 0..3 {
for j in 0..3 {
tree.add_point(i as f64, j as f64);
}
}
tree.build();
let mut results = Vec::new();
tree.query_circle_points(1.0, 1.0, 1.5, &mut results);
for &idx in &results {
if let Some((x, y)) = tree.get_point(idx) {
let distance = ((x - 1.0).powi(2) + (y - 1.0).powi(2)).sqrt();
assert!(distance <= 1.5, "Point {} at ({}, {}) has distance {}, exceeds radius 1.5", idx, x, y, distance);
}
}
}
}