vrp_core/algorithms/geometry/
point.rs1#[cfg(test)]
2#[path = "../../../tests/unit/algorithms/geometry/point_test.rs"]
3mod point_test;
4
5use rosomaxa::prelude::Float;
6use std::hash::{Hash, Hasher};
7
8#[derive(Clone, Debug)]
10pub struct Point {
11 pub x: Float,
13 pub y: Float,
15}
16
17impl Point {
18 pub fn new(x: Float, y: Float) -> Self {
20 Self { x, y }
21 }
22
23 pub fn distance_to_point(&self, other: &Point) -> Float {
25 let delta_x = self.x - other.x;
26 let delta_y = self.y - other.y;
27
28 (delta_x * delta_x + delta_y * delta_y).sqrt()
29 }
30
31 pub fn distance_to_line(&self, a: &Point, b: &Point) -> Float {
33 let a_b_distance = a.distance_to_point(b);
34
35 if a_b_distance == 0. {
36 0.
37 } else {
38 (Self::cross_product(a, b, self) / a_b_distance).abs()
39 }
40 }
41
42 pub fn distance_to_segment(&self, a: &Point, b: &Point) -> Float {
44 if Self::dot_product(a, b, self) > 0. {
45 return b.distance_to_point(self);
46 }
47
48 if Self::dot_product(b, a, self) > 0. {
49 return a.distance_to_point(self);
50 }
51
52 self.distance_to_line(a, b)
53 }
54
55 pub fn dot_product(a: &Point, b: &Point, c: &Point) -> Float {
57 let ab_x = b.x - a.x;
58 let ab_y = b.y - a.y;
59 let bc_x = c.x - b.x;
60 let bc_y = c.y - b.y;
61
62 ab_x * bc_x + ab_y * bc_y
63 }
64
65 pub fn cross_product(a: &Point, b: &Point, c: &Point) -> Float {
67 let ab_x = b.x - a.x;
68 let ab_y = b.y - a.y;
69 let ac_x = c.x - a.x;
70 let ac_y = c.y - a.y;
71
72 ab_x * ac_y - ab_y * ac_x
73 }
74}
75
76impl Point {
77 fn transmute(&self) -> (i64, i64) {
78 let x = self.x.to_bits() as i64;
79 let y = self.y.to_bits() as i64;
80
81 (x, y)
82 }
83}
84
85impl Hash for Point {
86 fn hash<H: Hasher>(&self, state: &mut H) {
87 let (x, y) = self.transmute();
88 x.hash(state);
89 y.hash(state);
90 }
91}
92
93impl Eq for Point {}
94
95impl PartialEq for Point {
96 fn eq(&self, other: &Self) -> bool {
97 let (self_x, self_y) = self.transmute();
98 let (other_x, other_y) = other.transmute();
99
100 self_x == other_x && self_y == other_y
101 }
102}