devela/num/geom/metric/angle/
kind.rs

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