use crate::{centroid, DistDot, Normal3, Point3, Precision, ScoreCalc};
#[cfg(feature = "bosque")]
pub mod bosque;
#[cfg(feature = "kiddo")]
pub mod kiddo;
#[cfg(feature = "nabo")]
pub mod nabo;
#[cfg(feature = "rstar")]
pub mod rstar;
cfg_if::cfg_if! {
if #[cfg(feature = "kiddo")] {
pub type Neuron = self::kiddo::ExactKiddoNeuron;
} else if #[cfg(feature = "bosque")] {
pub type Neuron = self::bosque::BosqueNeuron;
} else if #[cfg(feature = "rstar")] {
pub type Neuron = self::rstar::RstarNeuron;
} else if #[cfg(feature = "nabo")] {
pub type Neuron = self::nabo::NaboNeuron;
} else {
compile_error!("No spatial query backend selected");
}
}
pub trait NblastNeuron {
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn points(&self) -> impl Iterator<Item = Point3> + '_;
fn centroid(&self) -> Point3 {
centroid(self.points())
}
fn tangents(&self) -> impl Iterator<Item = Normal3> + '_;
fn alphas(&self) -> impl Iterator<Item = Precision> + '_;
}
pub trait QueryNeuron: NblastNeuron {
fn query_dist_dots<'a>(
&'a self,
target: &'a impl TargetNeuron,
use_alpha: bool,
) -> impl Iterator<Item = DistDot> + 'a;
fn query(
&self,
target: &impl TargetNeuron,
use_alpha: bool,
score_calc: &ScoreCalc,
) -> Precision {
self.query_dist_dots(target, use_alpha)
.map(|dd| score_calc.calc(&dd))
.sum()
}
fn self_hit(&self, score_calc: &ScoreCalc, use_alpha: bool) -> Precision;
}
pub trait TargetNeuron: QueryNeuron {
fn nearest_match_dist_dot(
&self,
point: &Point3,
tangent: &Normal3,
alpha: Option<Precision>,
) -> DistDot;
}