kd_tree_rs/
point.rs

1use crate::dim::Dim;
2
3use std::cmp::Ordering;
4use std::ops::{Add, Mul, Sub};
5
6#[derive(Debug, PartialEq, Copy, Clone)]
7pub struct Point<T: PartialEq> {
8    pub x: T,
9    pub y: T,
10}
11
12impl<T: PartialEq + PartialOrd + Into<f64> + Copy> Point<T> {
13    pub(crate) fn gt(&self, rs: &Point<T>, dim: &Dim) -> bool {
14        match dim {
15            Dim::X => self.x > rs.x,
16            Dim::Y => self.y > rs.y,
17        }
18    }
19
20    pub(crate) fn in_radius(&self, rs: &Point<T>, dim: &Dim, radius: f64) -> bool {
21        let origin: &T = match dim {
22            Dim::X => &self.x,
23            Dim::Y => &self.y,
24        };
25
26        let point: &T = match dim {
27            Dim::X => &rs.x,
28            Dim::Y => &rs.y,
29        };
30
31        let origin: f64 = (*origin).into();
32        let point: f64 = (*point).into();
33
34        return (origin + radius > point && origin < point) || (origin - radius < point && origin > point);
35    }
36
37    pub(crate) fn cmp(&self, rs: &Point<T>, dim: &Dim) -> Ordering {
38        let ls_value: &T = self.get_dim_value(dim);
39        let rs_value: &T = rs.get_dim_value(dim);
40        ls_value.partial_cmp(&rs_value).unwrap()
41    }
42
43    pub(crate) fn get_dim_value(&self, dim: &Dim) -> &T {
44        match dim {
45            Dim::X => &self.x,
46            Dim::Y => &self.y,
47        }
48    }
49}
50
51pub fn distance<T>(ls: &Point<T>, rs: &Point<T>) -> f64
52where
53    T: Mul<Output = T>
54        + Sub<Output = T>
55        + Add<Output = T>
56        + Copy
57        + PartialEq
58        + Into<f64>
59        + Mul<Output = T>,
60{
61    let x: T = ls.x - rs.x;
62    let y: T = ls.y - rs.y;
63    let diff: T = x * x + y * y;
64    diff.into().sqrt()
65}
66
67#[test]
68fn test_distance() {
69    let p1 = Point { x: 1., y: 1. };
70    let p2 = Point { x: 2., y: 2. };
71    let p3 = Point { x: 1., y: 2. };
72    let p4 = Point { x: 2., y: 1. };
73
74    assert_eq!(distance(&p1, &p2), 2f64.sqrt());
75    assert_eq!(distance(&p1, &p3), 1f64);
76    assert_eq!(distance(&p1, &p4), 1f64);
77}
78
79#[test]
80fn test_cmp_points() {
81    let p1 = Point { x: 1, y: 1 };
82    let p2 = Point { x: 2, y: 2 };
83    let p3 = Point { x: 1, y: 2 };
84    let p4 = Point { x: 2, y: 1 };
85
86    assert_eq!(p1.cmp(&p2, &Dim::X), Ordering::Less);
87    assert_eq!(p1.cmp(&p2, &Dim::Y), Ordering::Less);
88    assert_eq!(p1.cmp(&p3, &Dim::X), Ordering::Equal);
89    assert_eq!(p1.cmp(&p3, &Dim::Y), Ordering::Less);
90    assert_eq!(p1.cmp(&p4, &Dim::X), Ordering::Less);
91    assert_eq!(p1.cmp(&p4, &Dim::Y), Ordering::Equal);
92}