#[allow(unused)]
#[cfg(not(feature = "std"))]
use crate::FloatExt;
use crate::{Angle, AngleDirection, AngleKind};
#[allow(unused_imports)]
use crate::{FloatConst, fsize};
macro_rules! impl_angle {
() => {
impl_angle![sint i8:f32, i16:f32, i32:f32, i64:f64, i128:f64, isize:fsize];
impl_angle![uint u8:f32, u16:f32, u32:f32, u64:f64, u128:f64, usize:fsize];
};
(int $($t:ty : $f:ty),+) => {
$( impl_angle![@int $t:$f]; )+
};
(@int $t:ty : $f:ty) => {
#[doc = concat!("# Methods for angles represented using `", stringify!($t), "`.")]
impl Angle<$t> {
const fn to_float_normalized(self) -> $f { self.turn as $f / <$t>::MAX as $f }
fn from_float_normalized(value: $f, unit: $f) -> $t {
((value / unit) * <$t>::MAX as $f).round() as $t
}
pub const fn new_full() -> Self { Self::new(0) }
pub const fn new_right() -> Self { Self::new(<$t>::MAX / 4) }
pub const fn new_straight() -> Self { Self::new(<$t>::MAX / 2) }
pub fn from_rad(radians: $f) -> Self {
Self::new(Self::from_float_normalized(radians, <$f>::TAU))
}
pub fn from_deg(degrees: $f) -> Self {
Self::new(Self::from_float_normalized(degrees, 360.0))
}
pub fn from_custom(value: $f, custom_unit: $f) -> Self {
Self::new(Self::from_float_normalized(value, custom_unit))
}
#[must_use]
pub const fn to_rad(self) -> $f { self.to_float_normalized() * <$f>::TAU }
#[must_use]
pub const fn to_deg(self) -> $f { self.to_float_normalized() * 360.0 }
#[must_use]
pub const fn to_custom(self, custom_unit: $f) -> $f {
self.to_float_normalized() * custom_unit
}
#[must_use]
pub const fn is_normalized(self) -> bool { true }
pub const fn normalize(self) -> Self { self }
pub fn set_normalized(&mut self) {}
#[must_use ]
pub const fn has_direction(self, direction: AngleDirection) -> bool {
direction as i8 == self.direction() as i8
}
pub const fn kind(self) -> AngleKind {
let angle = self.positive().turn;
let right = <$t>::MAX / 4;
let straight = <$t>::MAX / 2;
use AngleKind as K;
if angle == 0 { K::Full
} else if angle == right { K::Right
} else if angle == straight { K::Straight
} else if angle < right { K::Acute
} else if angle < straight { K::Obtuse
} else { K::Reflex
}
}
#[must_use]
pub const fn is_kind(self, kind: AngleKind) -> bool {
let angle = self.positive().turn;
let right = <$t>::MAX / 4;
let straight = <$t>::MAX / 2;
use AngleKind as K;
match kind {
K::Full => angle == 0,
K::Right => angle == right,
K::Straight => angle == straight,
K::Acute => angle > 0 && angle < right,
K::Obtuse => angle < right && angle < straight,
K::Reflex => angle > right,
}
}
}
};
(sint $($t:ty : $f:ty),+) => {
$( impl_angle![@sint $t:$f]; )+
};
(@sint $t:ty : $f:ty) => {
impl_angle![int $t:$f];
#[doc = concat!("# Methods for angles represented using `", stringify!($t), "`, signed.")]
impl Angle<$t> {
pub const fn direction(self) -> AngleDirection {
use AngleDirection as D;
if self.turn == 0 {
D::Undefined
} else if self.turn > 0 {
D::Positive
} else {
D::Negative
}
}
pub const fn with_direction(self, direction: AngleDirection) -> Self {
use AngleDirection as D;
match direction {
D::Positive | D::Undefined => Self::new(self.turn.saturating_abs()),
D::Negative => Self::new(-self.turn.saturating_abs()),
}
}
pub fn set_direction(&mut self, direction: AngleDirection) {
use AngleDirection as D;
match direction {
D::Positive | D::Undefined => self.turn = self.turn.saturating_abs(),
D::Negative => self.turn = -self.turn.saturating_abs(),
}
}
pub const fn invert_direction(self) -> Self {
Self::new(self.turn.saturating_neg())
}
pub const fn negative(self) -> Self { Self::new(-self.turn.saturating_abs()) }
pub fn set_negative(&mut self) { self.turn = -self.turn.saturating_abs(); }
pub const fn positive(self) -> Self { Self::new(self.turn.saturating_abs()) }
pub fn set_positive(&mut self) { self.turn = self.turn.saturating_abs(); }
}
};
(uint $($t:ty : $f:ty),+) => {
$( impl_angle![@uint $t:$f]; )+
};
(@uint $t:ty : $f:ty) => {
impl_angle![int $t:$f];
#[doc = concat!("# Methods for angles represented using `", stringify!($t), "`, unsigned.")]
impl Angle<$t> {
pub const fn direction(self) -> AngleDirection { AngleDirection::Positive }
pub const fn with_direction(self, _direction: AngleDirection) -> Self { self }
pub const fn set_direction(self, _direction: AngleDirection) {}
pub const fn invert_direction(self) -> Self { self }
pub const fn negative(self) -> Self { self }
pub fn set_negative(&mut self) {}
pub const fn positive(self) -> Self { self }
pub fn set_positive(&mut self) {}
}
};
}
impl_angle!();