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}