Skip to main content

devela/geom/dir/angle/
kind.rs

1// devela/src/geom/dir/angle/kind.rs
2//
3//! Defines [`AngleKind`].
4//
5
6use crate::{FloatConst, Interval};
7
8#[doc = crate::_tags!(geom)]
9/// The kind of [`Angle`][super::Angle], based on its normalized turn.
10#[doc = crate::_doc_meta!{location("num/geom/dir")}]
11///
12/// The variant values are normalized to the full range of an u8.
13#[must_use]
14#[repr(u8)]
15#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Hash)]
16pub enum AngleKind {
17    /// = 0º = 360º (1τ = 2π), a full turn, or no turn.
18    #[default]
19    Full,
20
21    /// > 0° and < 90°
22    Acute,
23
24    /// = 90° (¼τ), a quarter turn.
25    Right,
26
27    /// > 90° and < 180°.
28    Obtuse,
29
30    /// = 180° (½τ), a half turn.
31    Straight,
32
33    /// > 180° and < 360°.
34    Reflex,
35}
36
37impl AngleKind {
38    /// Returns an interval representing the angle range in degrees.
39    pub fn interval_deg(self) -> Interval<u16> {
40        use AngleKind as K;
41        match self {
42            K::Full => Interval::closed(0, 0),         // Full turn as [0, 0]
43            K::Acute => Interval::open(0, 90),         // Acute: (0, 90)
44            K::Right => Interval::closed(90, 90),      // Right: [90, 90]
45            K::Obtuse => Interval::open(90, 180),      // Obtuse: (90, 180)
46            K::Straight => Interval::closed(180, 180), // Straight: [180, 180]
47            K::Reflex => Interval::open(180, 360),     // Reflex: (180, 360)
48        }
49    }
50
51    /// Returns an interval representing the angle range in gradians.
52    pub fn interval_gra(self) -> Interval<u16> {
53        use AngleKind as K;
54        match self {
55            K::Full => Interval::closed(0, 0),
56            K::Acute => Interval::open(0, 100),
57            K::Right => Interval::closed(100, 100),
58            K::Obtuse => Interval::open(100, 200),
59            K::Straight => Interval::closed(200, 200),
60            K::Reflex => Interval::open(200, 400),
61        }
62    }
63
64    /// Returns an interval representing the angle range in radians.
65    pub fn interval_rad(self) -> Interval<f32> {
66        const PI: f32 = f32::PI;
67        use AngleKind as K;
68        match self {
69            K::Full => Interval::closed(0.0, 0.0),
70            K::Acute => Interval::open(0.0, PI / 2.0),
71            K::Right => Interval::closed(PI / 2.0, PI / 2.0),
72            K::Obtuse => Interval::open(PI / 2.0, PI),
73            K::Straight => Interval::closed(PI, PI),
74            K::Reflex => Interval::open(PI, 2.0 * PI),
75        }
76    }
77
78    /// Returns an interval representing the angle range using 256 as a full turn.
79    pub fn interval_u8(self) -> Interval<u8> {
80        use AngleKind as K;
81        match self {
82            K::Full => Interval::closed(0, 0),
83            K::Acute => Interval::open(0, 64),
84            K::Right => Interval::closed(64, 64),
85            K::Obtuse => Interval::open(64, 128),
86            K::Straight => Interval::closed(128, 128),
87            K::Reflex => Interval::open(128, 255),
88        }
89    }
90}