devela/num/geom/metric/angle/impl/
int.rs
1#[cfg(all(not(feature = "std"), _float··))]
11use crate::ExtFloat;
12#[cfg(_float··)]
13#[allow(unused_imports)]
14use crate::{fsize, ExtFloatConst};
15use crate::{Angle, AngleDirection, AngleKind};
16
17macro_rules! impl_angle {
30 () => {
31 impl_angle![sint
32 i8:f32;"_int_i8":"_float_f32",
33 i16:f32;"_int_i16":"_float_f32",
34 i32:f32;"_int_i32":"_float_f32",
35 i64:f64;"_int_i64":"_float_f64",
36 i128:f64;"_int_i128":"_float_f64"
37 ];
38 #[cfg(target_pointer_width = "32")]
39 impl_angle![sint isize:fsize;"_int_isize":"_float_f32"];
40 #[cfg(target_pointer_width = "64")]
41 impl_angle![sint isize:fsize;"_int_isize":"_float_f64"];
42
43 impl_angle![uint
44 u8:f32;"_int_u8":"_float_f32",
45 u16:f32;"_int_u16":"_float_f32",
46 u32:f32;"_int_u32":"_float_f32",
47 u64:f64;"_int_u64":"_float_f64",
48 u128:f64;"_int_u128":"_float_f64"
49 ];
50 #[cfg(target_pointer_width = "32")]
51 impl_angle![uint usize:fsize;"_int_usize":"_float_f32"];
52 #[cfg(target_pointer_width = "64")]
53 impl_angle![uint usize:fsize;"_int_usize":"_float_f64"];
54 };
55
56 (int $($t:ty : $f:ty ; $tcap:literal : $fcap:literal),+) => {
58 $( impl_angle![@int $t:$f ; $tcap:$fcap]; )+
59 };
60 (@int $t:ty : $f:ty ; $tcap:literal : $fcap:literal) => {
61 #[doc = concat!("# Methods for angles represented using `", stringify!($t), "`.")]
62 #[cfg(feature = $tcap )]
63 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $tcap)))]
64 impl Angle<$t> {
65 const fn to_float_normalized(self) -> $f { self.turn as $f / <$t>::MAX as $f }
69 #[cfg(any(feature = "std", feature = $fcap))]
71 fn from_float_normalized(value: $f, unit: $f) -> $t {
72 ((value / unit) * <$t>::MAX as $f).round() as $t
73 }
74
75 pub const fn new_full() -> Self { Self::new(0) }
79
80 pub const fn new_right() -> Self { Self::new(<$t>::MAX / 4) }
82
83 pub const fn new_straight() -> Self { Self::new(<$t>::MAX / 2) }
85
86 #[cfg(any(feature = "std", feature = $fcap))]
88 #[cfg_attr(feature = "nightly_doc", doc(cfg(any(feature = "std", feature = $fcap))))]
89 pub fn from_rad(radians: $f) -> Self {
90 Self::new(Self::from_float_normalized(radians, <$f>::TAU))
91 }
92
93 #[cfg(any(feature = "std", feature = $fcap))]
95 #[cfg_attr(feature = "nightly_doc", doc(cfg(any(feature = "std", feature = $fcap))))]
96 pub fn from_deg(degrees: $f) -> Self {
97 Self::new(Self::from_float_normalized(degrees, 360.0))
98 }
99
100 #[cfg(any(feature = "std", feature = $fcap))]
102 #[cfg_attr(feature = "nightly_doc", doc(cfg(any(feature = "std", feature = $fcap))))]
103 pub fn from_custom(value: $f, custom_unit: $f) -> Self {
104 Self::new(Self::from_float_normalized(value, custom_unit))
105 }
106
107 #[must_use]
111 #[cfg(any(feature = "std", _float··))]
112 #[cfg_attr(feature = "nightly_doc", doc(cfg(any(feature = "std", _float··))))]
113 pub const fn to_rad(self) -> $f { self.to_float_normalized() * <$f>::TAU }
114
115 #[must_use]
117 pub const fn to_deg(self) -> $f { self.to_float_normalized() * 360.0 }
118
119 #[must_use]
121 pub const fn to_custom(self, custom_unit: $f) -> $f {
122 self.to_float_normalized() * custom_unit
123 }
124
125 #[must_use]
129 pub const fn is_normalized(self) -> bool { true }
130
131 pub const fn normalize(self) -> Self { self }
133
134 pub fn set_normalized(&mut self) {}
136
137 #[must_use ]
139 pub const fn has_direction(self, direction: AngleDirection) -> bool {
140 direction as i8 == self.direction() as i8
141 }
142
143 pub const fn kind(self) -> AngleKind {
147 let angle = self.positive().turn;
148 let right = <$t>::MAX / 4;
149 let straight = <$t>::MAX / 2;
150 use AngleKind as K;
151 if angle == 0 { K::Full
153 } else if angle == right { K::Right
155 } else if angle == straight { K::Straight
157 } else if angle < right { K::Acute
160 } else if angle < straight { K::Obtuse
162 } else { K::Reflex
164 }
165 }
166
167 #[must_use]
169 pub const fn is_kind(self, kind: AngleKind) -> bool {
170 let angle = self.positive().turn;
171 let right = <$t>::MAX / 4;
172 let straight = <$t>::MAX / 2;
173
174 use AngleKind as K;
175 match kind {
176 K::Full => angle == 0,
177 K::Right => angle == right,
178 K::Straight => angle == straight,
179 K::Acute => angle > 0 && angle < right,
181 K::Obtuse => angle < right && angle < straight,
182 K::Reflex => angle > right,
183 }
184 }
185 }
186 };
187
188 (sint $($t:ty : $f:ty ; $tcap:literal : $fcap:literal),+) => {
190 $( impl_angle![@sint $t:$f ; $tcap:$fcap]; )+
191 };
192 (@sint $t:ty : $f:ty ; $tcap:literal : $fcap:literal) => {
193 impl_angle![int $t:$f ; $tcap:$fcap];
194
195 #[doc = concat!("# Methods for angles represented using `", stringify!($t), "`, signed.")]
196 #[cfg(feature = $tcap )]
197 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $tcap)))]
198 impl Angle<$t> {
199 pub const fn direction(self) -> AngleDirection {
205 use AngleDirection as D;
206 if self.turn == 0 {
207 D::Undefined
208 } else if self.turn > 0 {
209 D::Positive
210 } else {
211 D::Negative
212 }
213 }
214
215 pub const fn with_direction(self, direction: AngleDirection) -> Self {
219 use AngleDirection as D;
220 match direction {
221 D::Positive | D::Undefined => Self::new(self.turn.saturating_abs()),
222 D::Negative => Self::new(-self.turn.saturating_abs()),
223 }
224 }
225
226 pub fn set_direction(&mut self, direction: AngleDirection) {
230 use AngleDirection as D;
231 match direction {
232 D::Positive | D::Undefined => self.turn = self.turn.saturating_abs(),
233 D::Negative => self.turn = -self.turn.saturating_abs(),
234 }
235 }
236
237 pub const fn invert_direction(self) -> Self {
239 Self::new(self.turn.saturating_neg())
240 }
241
242 pub const fn negative(self) -> Self { Self::new(-self.turn.saturating_abs()) }
244
245 pub fn set_negative(&mut self) { self.turn = -self.turn.saturating_abs(); }
247
248 pub const fn positive(self) -> Self { Self::new(self.turn.saturating_abs()) }
250
251 pub fn set_positive(&mut self) { self.turn = self.turn.saturating_abs(); }
253 }
254 };
255
256 (uint $($t:ty : $f:ty ; $tcap:literal : $fcap:literal),+) => {
258 $( impl_angle![@uint $t:$f ; $tcap:$fcap]; )+
259 };
260 (@uint $t:ty : $f:ty ; $tcap:literal : $fcap:literal) => {
261 impl_angle![int $t:$f ; $tcap:$fcap];
262
263 #[doc = concat!("# Methods for angles represented using `", stringify!($t), "`, unsigned.")]
264 #[cfg(feature = $tcap )]
265 #[cfg_attr(feature = "nightly_doc", doc(cfg(feature = $tcap)))]
266 impl Angle<$t> {
267 pub const fn direction(self) -> AngleDirection { AngleDirection::Positive }
273
274 pub const fn with_direction(self, _direction: AngleDirection) -> Self { self }
278
279 pub const fn set_direction(self, _direction: AngleDirection) {}
283
284 pub const fn invert_direction(self) -> Self { self }
288
289 pub const fn negative(self) -> Self { self }
291
292 pub fn set_negative(&mut self) {}
294
295 pub const fn positive(self) -> Self { self }
297
298 pub fn set_positive(&mut self) {}
300
301 }
302 };
303}
304impl_angle!();