autd3_core/common/
angle.rs1#[allow(non_camel_case_types)]
3pub struct deg;
4
5#[allow(non_camel_case_types)]
7pub struct rad;
8
9#[repr(C)]
11#[derive(Clone, Copy, PartialEq)]
12pub struct Angle {
13 radian: f32,
14}
15
16impl core::fmt::Debug for Angle {
17 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18 write!(f, "{} rad", self.radian)
19 }
20}
21
22impl Angle {
23 pub const ZERO: Self = Self { radian: 0.0 };
25
26 pub const PI: Self = Self {
28 radian: core::f32::consts::PI,
29 };
30
31 #[must_use]
33 pub const fn from_radian(radian: f32) -> Self {
34 Self { radian }
35 }
36
37 #[must_use]
39 pub const fn from_degree(degree: f32) -> Self {
40 Self {
41 radian: degree.to_radians(),
42 }
43 }
44
45 #[must_use]
47 pub const fn radian(self) -> f32 {
48 self.radian
49 }
50
51 #[must_use]
53 pub const fn degree(self) -> f32 {
54 self.radian.to_degrees()
55 }
56}
57
58impl core::ops::Mul<deg> for f32 {
59 type Output = Angle;
60
61 fn mul(self, _rhs: deg) -> Self::Output {
62 Self::Output::from_degree(self)
63 }
64}
65
66impl core::ops::Mul<rad> for f32 {
67 type Output = Angle;
68
69 fn mul(self, _rhs: rad) -> Self::Output {
70 Self::Output::from_radian(self)
71 }
72}
73
74impl core::ops::Neg for Angle {
75 type Output = Angle;
76
77 fn neg(self) -> Self::Output {
78 Angle {
79 radian: -self.radian,
80 }
81 }
82}
83
84impl core::ops::Add<Angle> for Angle {
85 type Output = Angle;
86
87 fn add(self, rhs: Angle) -> Self::Output {
88 Angle {
89 radian: self.radian + rhs.radian,
90 }
91 }
92}
93
94impl core::ops::Sub<Angle> for Angle {
95 type Output = Angle;
96
97 fn sub(self, rhs: Angle) -> Self::Output {
98 Angle {
99 radian: self.radian - rhs.radian,
100 }
101 }
102}
103
104impl core::ops::Mul<f32> for Angle {
105 type Output = Angle;
106
107 fn mul(self, rhs: f32) -> Self::Output {
108 Angle {
109 radian: self.radian * rhs,
110 }
111 }
112}
113
114impl core::ops::Div<f32> for Angle {
115 type Output = Angle;
116
117 fn div(self, rhs: f32) -> Self::Output {
118 Angle {
119 radian: self.radian / rhs,
120 }
121 }
122}
123
124impl core::ops::Mul<Angle> for f32 {
125 type Output = Angle;
126
127 fn mul(self, rhs: Angle) -> Self::Output {
128 Angle {
129 radian: rhs.radian * self,
130 }
131 }
132}
133
134impl core::ops::AddAssign for Angle {
135 fn add_assign(&mut self, rhs: Angle) {
136 self.radian += rhs.radian;
137 }
138}
139
140impl core::ops::SubAssign for Angle {
141 fn sub_assign(&mut self, rhs: Angle) {
142 self.radian -= rhs.radian;
143 }
144}
145
146impl core::ops::MulAssign<f32> for Angle {
147 fn mul_assign(&mut self, rhs: f32) {
148 self.radian *= rhs;
149 }
150}
151
152impl core::ops::DivAssign<f32> for Angle {
153 fn div_assign(&mut self, rhs: f32) {
154 self.radian /= rhs;
155 }
156}
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161
162 #[test]
163 fn dbg() {
164 assert_eq!(format!("{:?}", 1.0 * rad), "1 rad");
165 }
166
167 #[test]
168 fn ops() {
169 let mut a = 1.0 * rad;
170 let b = 2.0 * rad;
171
172 assert_eq!((-a).radian(), -1.0);
173 assert_eq!((a + b).radian(), 3.0);
174 assert_eq!((a - b).radian(), -1.0);
175 assert_eq!((a * 2.0).radian(), 2.0);
176 assert_eq!((a / 2.0).radian(), 0.5);
177 assert_eq!((2.0 * a).radian(), 2.0);
178
179 a += b;
180 assert_eq!(a.radian(), 3.0);
181
182 a -= b;
183 assert_eq!(a.radian(), 1.0);
184
185 a *= 2.0;
186 assert_eq!(a.radian(), 2.0);
187
188 a /= 2.0;
189 assert_eq!(a.radian(), 1.0);
190 }
191}