1use crate::{Px, PxPoint, PxRect};
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, bytemuck::Zeroable, bytemuck::Pod)]
9#[repr(transparent)]
10#[serde(transparent)]
11pub struct DistanceKey(u64);
12impl DistanceKey {
13 pub const NONE_MAX: DistanceKey = DistanceKey(u64::MAX);
15
16 pub const NONE_MIN: DistanceKey = DistanceKey(0);
18
19 pub const MAX: DistanceKey = DistanceKey((Px::MAX.0 as u64).pow(2));
21
22 pub const MIN: DistanceKey = DistanceKey(1);
24
25 pub fn from_points(a: PxPoint, b: PxPoint) -> Self {
27 let pa = ((a.x - b.x).0.unsigned_abs() as u64).pow(2);
28 let pb = ((a.y - b.y).0.unsigned_abs() as u64).pow(2);
29
30 Self((pa + pb) + 1)
31 }
32
33 pub fn from_rect_to_point(a: PxRect, b: PxPoint) -> Self {
35 Self::from_points(b.clamp(a.min(), a.max()), b)
36 }
37
38 pub fn from_distance(d: Px) -> Self {
44 let p = (d.0.unsigned_abs() as u64).pow(2);
45 Self(p + 1)
46 }
47
48 pub fn is_none(self) -> bool {
53 self == Self::NONE_MAX || self == Self::NONE_MIN
54 }
55
56 pub fn distance(self) -> Option<Px> {
58 if self.is_none() {
59 None
60 } else {
61 let p = self.0 - 1;
62 let d = (p as f64).sqrt();
63
64 Some(Px(d.round() as i32))
65 }
66 }
67
68 pub fn min(self, other: Self) -> Self {
70 Self(self.0.min(other.0))
71 }
72
73 pub fn max(self, other: Self) -> Self {
75 Self(self.0.max(other.0))
76 }
77}