Skip to main content

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/// Degrees
8#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
9pub struct Degrees(pub f32);
10
11impl Degrees {
12    /// The range of degrees of a circle.
13    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
74impl num_traits::AsPrimitive<f32> for Degrees {
75    fn as_(self) -> f32 {
76        self.0
77    }
78}
79
80impl num_traits::AsPrimitive<f64> for Degrees {
81    fn as_(self) -> f64 {
82        f64::from(self.0)
83    }
84}
85
86/// Radians
87#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
88pub struct Radians(pub f32);
89
90impl Radians {
91    /// The range of radians of a circle.
92    pub const RANGE: RangeInclusive<Self> = Self(0.0)..=Self(2.0 * PI);
93
94    /// The amount of radians in half a circle.
95    pub const PI: Self = Self(PI);
96
97    /// Calculates the line in which the angle intercepts the `bounds`.
98    pub fn to_distance(&self, bounds: &Rectangle) -> (Point, Point) {
99        let angle = self.0 - FRAC_PI_2;
100        let r = Vector::new(f32::cos(angle), f32::sin(angle));
101
102        let distance_to_rect = f32::max(
103            f32::abs(r.x * bounds.width / 2.0),
104            f32::abs(r.y * bounds.height / 2.0),
105        );
106
107        let start = bounds.center() - r * distance_to_rect;
108        let end = bounds.center() + r * distance_to_rect;
109
110        (start, end)
111    }
112}
113
114impl From<Degrees> for Radians {
115    fn from(degrees: Degrees) -> Self {
116        Self(degrees.0 * PI / 180.0)
117    }
118}
119
120impl From<f32> for Radians {
121    fn from(radians: f32) -> Self {
122        Self(radians)
123    }
124}
125
126impl From<u8> for Radians {
127    fn from(radians: u8) -> Self {
128        Self(f32::from(radians))
129    }
130}
131
132impl From<Radians> for f32 {
133    fn from(radians: Radians) -> Self {
134        radians.0
135    }
136}
137
138impl From<Radians> for f64 {
139    fn from(radians: Radians) -> Self {
140        Self::from(radians.0)
141    }
142}
143
144impl num_traits::FromPrimitive for Radians {
145    fn from_i64(n: i64) -> Option<Self> {
146        Some(Self(n as f32))
147    }
148
149    fn from_u64(n: u64) -> Option<Self> {
150        Some(Self(n as f32))
151    }
152
153    fn from_f64(n: f64) -> Option<Self> {
154        Some(Self(n as f32))
155    }
156}
157
158impl num_traits::AsPrimitive<f32> for Radians {
159    fn as_(self) -> f32 {
160        self.0
161    }
162}
163
164impl num_traits::AsPrimitive<f64> for Radians {
165    fn as_(self) -> f64 {
166        f64::from(self.0)
167    }
168}
169
170impl Sub for Radians {
171    type Output = Self;
172
173    fn sub(self, rhs: Self) -> Self::Output {
174        Self(self.0 - rhs.0)
175    }
176}
177
178impl SubAssign for Radians {
179    fn sub_assign(&mut self, rhs: Self) {
180        self.0 = self.0 - rhs.0;
181    }
182}
183
184impl Add for Radians {
185    type Output = Self;
186
187    fn add(self, rhs: Self) -> Self::Output {
188        Self(self.0 + rhs.0)
189    }
190}
191
192impl Add<Degrees> for Radians {
193    type Output = Self;
194
195    fn add(self, rhs: Degrees) -> Self::Output {
196        Self(self.0 + rhs.0.to_radians())
197    }
198}
199
200impl AddAssign for Radians {
201    fn add_assign(&mut self, rhs: Radians) {
202        self.0 = self.0 + rhs.0;
203    }
204}
205
206impl Mul for Radians {
207    type Output = Self;
208
209    fn mul(self, rhs: Radians) -> Self::Output {
210        Radians(self.0 * rhs.0)
211    }
212}
213
214impl Mul<f32> for Radians {
215    type Output = Self;
216
217    fn mul(self, rhs: f32) -> Self::Output {
218        Self(self.0 * rhs)
219    }
220}
221
222impl Mul<Radians> for f32 {
223    type Output = Radians;
224
225    fn mul(self, rhs: Radians) -> Self::Output {
226        Radians(self * rhs.0)
227    }
228}
229
230impl Div<f32> for Radians {
231    type Output = Self;
232
233    fn div(self, rhs: f32) -> Self::Output {
234        Radians(self.0 / rhs)
235    }
236}
237
238impl Div for Radians {
239    type Output = Self;
240
241    fn div(self, rhs: Self) -> Self::Output {
242        Self(self.0 / rhs.0)
243    }
244}
245
246impl Rem for Radians {
247    type Output = Self;
248
249    fn rem(self, rhs: Self) -> Self::Output {
250        Self(self.0 % rhs.0)
251    }
252}
253
254impl PartialEq<f32> for Radians {
255    fn eq(&self, other: &f32) -> bool {
256        self.0.eq(other)
257    }
258}
259
260impl PartialOrd<f32> for Radians {
261    fn partial_cmp(&self, other: &f32) -> Option<std::cmp::Ordering> {
262        self.0.partial_cmp(other)
263    }
264}
265
266impl Display for Radians {
267    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268        write!(f, "{} rad", self.0)
269    }
270}