1use std::f32::consts::PI as PI_F32;
4use std::f64::consts::PI as PI_F64;
5
6pub const DEGREE_90: f32 = 90.0;
8pub const DEGREE_180: f32 = 180.0;
10pub const DEGREE_270: f32 = 270.0;
12pub const DEGREE_360: f32 = 360.0;
14
15pub const DEG_TO_RAD: f32 = PI_F32 / DEGREE_180;
19pub const RAD_TO_DEG: f32 = DEGREE_180 / PI_F32;
23
24pub const DEG_TO_RAD_F64: f64 = PI_F64 / DEGREE_180 as f64;
26pub const RAD_TO_DEG_F64: f64 = DEGREE_180 as f64 / PI_F64;
28
29#[must_use]
31pub fn wrap_degrees(mut degrees: f32) -> f32 {
32 degrees %= DEGREE_360;
33 if degrees >= DEGREE_180 {
34 degrees -= DEGREE_360;
35 }
36 if degrees < -DEGREE_180 {
37 degrees += DEGREE_360;
38 }
39 degrees
40}
41
42#[must_use]
44pub fn convert_to_rotation_segment(degrees: f32) -> u8 {
45 (((degrees.rem_euclid(DEGREE_360) / (DEGREE_360 / 16.0)) + 0.5) as u8) & 15
46}
47
48#[cfg(test)]
49mod tests {
50 use super::{convert_to_rotation_segment, wrap_degrees};
51
52 #[test]
53 fn wrap_degrees_matches_vanilla_range() {
54 assert_eq!(wrap_degrees(181.0).to_bits(), (-179.0_f32).to_bits());
55 assert_eq!(wrap_degrees(-181.0).to_bits(), 179.0_f32.to_bits());
56 assert_eq!(wrap_degrees(90.0).to_bits(), 90.0_f32.to_bits());
57 assert_eq!(wrap_degrees(540.0).to_bits(), (-180.0_f32).to_bits());
58 }
59
60 #[test]
61 fn rotation_segment_wraps_and_rounds_to_nearest_segment() {
62 assert_eq!(convert_to_rotation_segment(11.24), 0);
63 assert_eq!(convert_to_rotation_segment(11.25), 1);
64 assert_eq!(convert_to_rotation_segment(-90.0), 12);
65 assert_eq!(convert_to_rotation_segment(360.0), 0);
66 }
67}