use nalgebra::{Point, Scalar};
use num_traits::{Bounded, NumOps};
use crate::utils::distance_squared;
#[inline]
#[cfg_attr(
feature = "tracing",
tracing::instrument("Find Closest Points", skip_all)
)]
pub fn find_nearest_neighbour_naive<T, const N: usize>(
point: &Point<T, N>,
all_points: &[Point<T, N>],
) -> Option<Point<T, N>>
where
T: Bounded + Copy + Default + NumOps + PartialOrd + Scalar,
{
if all_points.is_empty() {
return None;
}
let mut current_distance = T::max_value();
let mut current_point = all_points[0];
for target_point in all_points.iter() {
let distance = distance_squared(point, target_point);
if distance < current_distance {
current_distance = distance;
current_point = *target_point;
}
}
Some(current_point)
}
#[cfg(test)]
mod tests {
use nalgebra::{Point, Point2};
use crate::Vec;
use super::*;
#[test]
fn test_find_closest_point() {
let target_points = Vec::from([
Point2::new(1.0, 1.0),
Point2::new(2.0, 2.0),
Point2::new(5.0, 5.0),
Point2::new(8.0, 8.0),
]);
let transformed_point = Point2::new(4.0, 4.0);
let closest_point = find_nearest_neighbour_naive(&transformed_point, &target_points);
assert_eq!(closest_point, Some(Point2::new(5.0, 5.0)));
}
#[test]
fn test_find_closest_point_with_empty_target() {
let target_points: Vec<Point<f64, 2>> = Vec::new();
let transformed_point = Point2::new(4.0, 4.0);
assert_eq!(
find_nearest_neighbour_naive(&transformed_point, &target_points),
None
);
}
}