Skip to main content

blockworx/
units.rs

1//! [`WorldPx`], the newtype for world-space magnitudes — radii, hit margins,
2//! snap thresholds, the lengths that scale with zoom on screen. Non-negative:
3//! a length below zero clamps to zero.
4
5use egui::Pos2;
6
7use crate::bounded::{Bounded, Bounds};
8
9pub struct WorldPxBounds;
10
11impl Bounds for WorldPxBounds {
12    const MIN: f32 = 0.0;
13    const MAX: f32 = f32::INFINITY;
14}
15
16pub type WorldPx = Bounded<WorldPxBounds>;
17
18impl WorldPx {
19    pub const ZERO: Self = Self::new(0.0);
20
21    /// An unbounded length — the "no limit" end of the range, used where a
22    /// length is a cap rather than a magnitude (an unwrapped text run).
23    pub const UNBOUNDED: Self = Self::max_value();
24
25    /// Whether `a` and `b` (world space) are within this length of each other.
26    pub fn within(self, a: Pos2, b: Pos2) -> bool {
27        a.distance(b) < self.get()
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34    use egui::pos2;
35
36    #[test]
37    fn within_is_a_strict_distance_check() {
38        let r = WorldPx::new(5.0);
39        assert!(r.within(pos2(0.0, 0.0), pos2(3.0, 0.0)));
40        assert!(!r.within(pos2(0.0, 0.0), pos2(5.0, 0.0)));
41    }
42
43    #[test]
44    fn lengths_cannot_be_negative() {
45        assert_eq!(WorldPx::new(-3.0).get(), 0.0);
46    }
47}