use boxes::BBox;
use set::BBoxSet;
use crate::internals::{hybrid, one_way_scan, two_way_scan};
pub mod boxes;
pub mod internals;
mod median;
pub mod set;
pub trait HasInfinity {
const NINFTY: Self;
const INFTY: Self;
}
pub trait Rng {
fn rand_usize(&mut self, high: usize) -> usize;
}
#[cfg(feature = "rand-crate")]
impl<R> Rng for R
where
R: rand::Rng,
{
fn rand_usize(&mut self, max: usize) -> usize {
self.gen_range(0..max)
}
}
pub fn intersect_ze<B, ID, R>(
a: &BBoxSet<B, ID>,
b: &BBoxSet<B, ID>,
out: &mut Vec<(ID, ID)>,
rand: &mut R,
) where
B: BBox,
B::Num: PartialOrd + HasInfinity,
ID: PartialOrd + Copy,
R: Rng,
{
const CUTOFF: usize = 1000; intersect_ze_custom::<B, ID, R, CUTOFF>(a, b, out, rand);
}
pub fn intersect_ze_custom<B, ID, R, const CUTOFF: usize>(
a: &BBoxSet<B, ID>,
b: &BBoxSet<B, ID>,
out: &mut Vec<(ID, ID)>,
rand: &mut R,
) where
B: BBox,
ID: PartialOrd + Copy,
B::Num: PartialOrd + HasInfinity,
ID: PartialEq,
R: Rng,
{
let same = a as *const _ == b as *const _;
if same {
hybrid::<B, ID, R, CUTOFF>(a, a, B::Num::NINFTY, B::Num::INFTY, B::DIM - 1, out, rand);
} else {
hybrid::<B, ID, R, CUTOFF>(a, b, B::Num::NINFTY, B::Num::INFTY, B::DIM - 1, out, rand);
hybrid::<B, ID, R, CUTOFF>(b, a, B::Num::NINFTY, B::Num::INFTY, B::DIM - 1, out, rand);
}
}
pub fn intersect_scan<B, ID>(a: &BBoxSet<B, ID>, b: &BBoxSet<B, ID>, out: &mut Vec<(ID, ID)>)
where
B: BBox,
ID: Copy + PartialOrd,
{
let same = a as *const _ == b as *const _; if same {
one_way_scan(a, b, B::DIM - 1, out);
} else {
two_way_scan(a, b, out);
}
}
pub fn intersect_brute_force<B, ID>(a: &BBoxSet<B, ID>, b: &BBoxSet<B, ID>, out: &mut Vec<(ID, ID)>)
where
B: BBox,
ID: Copy,
{
let same = a as *const _ == b as *const _; if same {
let mut start = 1;
for &(bbox, id) in &a.boxes {
for idx in start..a.boxes.len() {
let (bbox2, id2) = a.boxes[idx];
if bbox.intersects(&bbox2) {
out.push((id, id2));
}
}
start += 1;
}
} else {
for &(bbox, id) in &a.boxes {
for &(bbox2, id2) in &b.boxes {
if bbox.intersects(&bbox2) {
out.push((id, id2));
}
}
}
}
}
impl HasInfinity for f32 {
const NINFTY: Self = f32::NEG_INFINITY;
const INFTY: Self = f32::INFINITY;
}
impl HasInfinity for f64 {
const NINFTY: Self = f64::NEG_INFINITY;
const INFTY: Self = f64::INFINITY;
}
#[cfg(test)]
mod tests;