iced_core/
angle.rs
1use crate::{Point, Rectangle, Vector};
2
3use std::f32::consts::{FRAC_PI_2, PI};
4use std::fmt::Display;
5use std::ops::{Add, AddAssign, Div, Mul, RangeInclusive, Rem, Sub, SubAssign};
6
7#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
9pub struct Degrees(pub f32);
10
11impl Degrees {
12 pub const RANGE: RangeInclusive<Self> = Self(0.0)..=Self(360.0);
14}
15
16impl PartialEq<f32> for Degrees {
17 fn eq(&self, other: &f32) -> bool {
18 self.0.eq(other)
19 }
20}
21
22impl PartialOrd<f32> for Degrees {
23 fn partial_cmp(&self, other: &f32) -> Option<std::cmp::Ordering> {
24 self.0.partial_cmp(other)
25 }
26}
27
28impl From<f32> for Degrees {
29 fn from(degrees: f32) -> Self {
30 Self(degrees)
31 }
32}
33
34impl From<u8> for Degrees {
35 fn from(degrees: u8) -> Self {
36 Self(f32::from(degrees))
37 }
38}
39
40impl From<Degrees> for f32 {
41 fn from(degrees: Degrees) -> Self {
42 degrees.0
43 }
44}
45
46impl From<Degrees> for f64 {
47 fn from(degrees: Degrees) -> Self {
48 Self::from(degrees.0)
49 }
50}
51
52impl Mul<f32> for Degrees {
53 type Output = Degrees;
54
55 fn mul(self, rhs: f32) -> Self::Output {
56 Self(self.0 * rhs)
57 }
58}
59
60impl num_traits::FromPrimitive for Degrees {
61 fn from_i64(n: i64) -> Option<Self> {
62 Some(Self(n as f32))
63 }
64
65 fn from_u64(n: u64) -> Option<Self> {
66 Some(Self(n as f32))
67 }
68
69 fn from_f64(n: f64) -> Option<Self> {
70 Some(Self(n as f32))
71 }
72}
73
74#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
76pub struct Radians(pub f32);
77
78impl Radians {
79 pub const RANGE: RangeInclusive<Self> = Self(0.0)..=Self(2.0 * PI);
81
82 pub const PI: Self = Self(PI);
84
85 pub fn to_distance(&self, bounds: &Rectangle) -> (Point, Point) {
87 let angle = self.0 - FRAC_PI_2;
88 let r = Vector::new(f32::cos(angle), f32::sin(angle));
89
90 let distance_to_rect = f32::max(
91 f32::abs(r.x * bounds.width / 2.0),
92 f32::abs(r.y * bounds.height / 2.0),
93 );
94
95 let start = bounds.center() - r * distance_to_rect;
96 let end = bounds.center() + r * distance_to_rect;
97
98 (start, end)
99 }
100}
101
102impl From<Degrees> for Radians {
103 fn from(degrees: Degrees) -> Self {
104 Self(degrees.0 * PI / 180.0)
105 }
106}
107
108impl From<f32> for Radians {
109 fn from(radians: f32) -> Self {
110 Self(radians)
111 }
112}
113
114impl From<u8> for Radians {
115 fn from(radians: u8) -> Self {
116 Self(f32::from(radians))
117 }
118}
119
120impl From<Radians> for f32 {
121 fn from(radians: Radians) -> Self {
122 radians.0
123 }
124}
125
126impl From<Radians> for f64 {
127 fn from(radians: Radians) -> Self {
128 Self::from(radians.0)
129 }
130}
131
132impl num_traits::FromPrimitive for Radians {
133 fn from_i64(n: i64) -> Option<Self> {
134 Some(Self(n as f32))
135 }
136
137 fn from_u64(n: u64) -> Option<Self> {
138 Some(Self(n as f32))
139 }
140
141 fn from_f64(n: f64) -> Option<Self> {
142 Some(Self(n as f32))
143 }
144}
145
146impl Sub for Radians {
147 type Output = Self;
148
149 fn sub(self, rhs: Self) -> Self::Output {
150 Self(self.0 - rhs.0)
151 }
152}
153
154impl SubAssign for Radians {
155 fn sub_assign(&mut self, rhs: Self) {
156 self.0 = self.0 - rhs.0;
157 }
158}
159
160impl Add for Radians {
161 type Output = Self;
162
163 fn add(self, rhs: Self) -> Self::Output {
164 Self(self.0 + rhs.0)
165 }
166}
167
168impl Add<Degrees> for Radians {
169 type Output = Self;
170
171 fn add(self, rhs: Degrees) -> Self::Output {
172 Self(self.0 + rhs.0.to_radians())
173 }
174}
175
176impl AddAssign for Radians {
177 fn add_assign(&mut self, rhs: Radians) {
178 self.0 = self.0 + rhs.0;
179 }
180}
181
182impl Mul for Radians {
183 type Output = Self;
184
185 fn mul(self, rhs: Radians) -> Self::Output {
186 Radians(self.0 * rhs.0)
187 }
188}
189
190impl Mul<f32> for Radians {
191 type Output = Self;
192
193 fn mul(self, rhs: f32) -> Self::Output {
194 Self(self.0 * rhs)
195 }
196}
197
198impl Mul<Radians> for f32 {
199 type Output = Radians;
200
201 fn mul(self, rhs: Radians) -> Self::Output {
202 Radians(self * rhs.0)
203 }
204}
205
206impl Div<f32> for Radians {
207 type Output = Self;
208
209 fn div(self, rhs: f32) -> Self::Output {
210 Radians(self.0 / rhs)
211 }
212}
213
214impl Div for Radians {
215 type Output = Self;
216
217 fn div(self, rhs: Self) -> Self::Output {
218 Self(self.0 / rhs.0)
219 }
220}
221
222impl Rem for Radians {
223 type Output = Self;
224
225 fn rem(self, rhs: Self) -> Self::Output {
226 Self(self.0 % rhs.0)
227 }
228}
229
230impl PartialEq<f32> for Radians {
231 fn eq(&self, other: &f32) -> bool {
232 self.0.eq(other)
233 }
234}
235
236impl PartialOrd<f32> for Radians {
237 fn partial_cmp(&self, other: &f32) -> Option<std::cmp::Ordering> {
238 self.0.partial_cmp(other)
239 }
240}
241
242impl Display for Radians {
243 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244 write!(f, "{} rad", self.0)
245 }
246}