Skip to content

Commit

Permalink
Split the Point and Distance traits to reduce the burden on implement…
Browse files Browse the repository at this point in the history
…ors who do not need nearest neighbor search.
  • Loading branch information
adamreichold committed Aug 10, 2023
1 parent 1fdc0d4 commit b01f201
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "sif-kdtree"
description = "simple, immutable, flat k-d tree"
version = "0.4.0"
version = "0.5.0"
edition = "2018"
rust-version = "1.55"
authors = ["Adam Reichold <[email protected]>"]
Expand Down
16 changes: 12 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,11 @@ pub trait Point {

/// Access the coordinate value of the point along the given `axis`
fn coord(&self, axis: usize) -> Self::Coord;
}

/// Return the squared distance between `self` and `other`.
/// Extends the [`Point`] trait by a distance metric required for nearest neighbour search
pub trait Distance: Point {
/// Return the squared distance between `self` and `other`
///
/// This is called during nearest neighbour search and hence only the relation between two distance values is required so that computing square roots can be avoided.
fn distance_2(&self, other: &Self) -> Self::Coord;
Expand All @@ -143,7 +146,12 @@ where
fn coord(&self, axis: usize) -> Self::Coord {
self[axis]
}
}

impl<T, const N: usize> Distance for [T; N]
where
T: Num + Copy + PartialOrd,
{
fn distance_2(&self, other: &Self) -> Self::Coord {
(0..N).fold(T::zero(), |res, axis| {
let diff = self[axis] - other[axis];
Expand All @@ -153,12 +161,12 @@ where
}
}

/// Defines the objects which can be organized in a [`KdTree`] by positioning them in a real space defined via the [`Point`] trait
/// Defines the objects which can be organized in a [`KdTree`] by positioning them in the vector space defined via the [`Point`] trait
pub trait Object {
/// The [`Point`] implementation used to represent the [position][`Self::position`] of these objects.
/// The [`Point`] implementation used to represent the [position][`Self::position`] of these objects
type Point: Point;

/// Return the position associated with this object.
/// Return the position associated with this object
///
/// Note that calling this method is assumed to be cheap, returning a reference to a point stored in the interior of the object.
fn position(&self) -> &Self::Point;
Expand Down
2 changes: 1 addition & 1 deletion src/look_up.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use num_traits::Num;
#[cfg(feature = "rayon")]
use rayon::join;

use crate::{contains, split, KdTree, Object, Point};
use crate::{contains, split, Distance, KdTree, Object, Point};

/// Defines a spatial query by its axis-aligned bounding box (AABB) and a method to test a single point
///
Expand Down
4 changes: 3 additions & 1 deletion src/nearest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ use std::mem::swap;

use num_traits::Float;

use crate::{split, KdTree, Object, Point};
use crate::{split, Distance, KdTree, Object, Point};

impl<O, S> KdTree<O, S>
where
O: Object,
O::Point: Distance,
<O::Point as Point>::Coord: Float,
S: AsRef<[O]>,
{
Expand Down Expand Up @@ -44,6 +45,7 @@ where
fn nearest<'a, O>(args: &mut NearestArgs<'a, '_, O>, mut objects: &'a [O], mut axis: usize)
where
O: Object,
O::Point: Distance,
<O::Point as Point>::Coord: Float,
{
loop {
Expand Down

0 comments on commit b01f201

Please sign in to comment.