Skip to content

Commit 66c8a80

Browse files
authored
Merge pull request #2029 from ua-kxie/arc-and-ellipse-radians-type
use radians type in arc and ellipse
2 parents 8ed3490 + b193298 commit 66c8a80

5 files changed

Lines changed: 114 additions & 41 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4545
- Update `wgpu` to `0.17`. [#2065](https://github.com/iced-rs/iced/pull/2065)
4646
- Support automatic style type casting for `Button`. [#2046](https://github.com/iced-rs/iced/pull/2046)
4747
- `with_clip` and `with_save` in `Frame` can now return the data of the provided closure. [#1994](https://github.com/iced-rs/iced/pull/1994)
48+
- `Arc` and `arc::Elliptical` now use `Radians` for angle fields. [#2027](https://github.com/iced-rs/iced/pull/2027)
4849

4950
### Fixed
5051
- Clipping of `TextInput` selection. [#2199](https://github.com/iced-rs/iced/pull/2199)

core/src/angle.rs

Lines changed: 83 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{Point, Rectangle, Vector};
22

33
use std::f32::consts::{FRAC_PI_2, PI};
4-
use std::ops::RangeInclusive;
4+
use std::ops::{Add, AddAssign, Div, Mul, RangeInclusive, Sub, SubAssign};
55

66
/// Degrees
77
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
@@ -13,7 +13,26 @@ pub struct Radians(pub f32);
1313

1414
impl Radians {
1515
/// The range of radians of a circle.
16-
pub const RANGE: RangeInclusive<Radians> = Radians(0.0)..=Radians(2.0 * PI);
16+
pub const RANGE: RangeInclusive<Self> = Self(0.0)..=Self(2.0 * PI);
17+
18+
/// The amount of radians in half a circle.
19+
pub const PI: Self = Self(PI);
20+
21+
/// Calculates the line in which the angle intercepts the `bounds`.
22+
pub fn to_distance(&self, bounds: &Rectangle) -> (Point, Point) {
23+
let angle = self.0 - FRAC_PI_2;
24+
let r = Vector::new(f32::cos(angle), f32::sin(angle));
25+
26+
let distance_to_rect = f32::max(
27+
f32::abs(r.x * bounds.width / 2.0),
28+
f32::abs(r.y * bounds.height / 2.0),
29+
);
30+
31+
let start = bounds.center() - r * distance_to_rect;
32+
let end = bounds.center() + r * distance_to_rect;
33+
34+
(start, end)
35+
}
1736
}
1837

1938
impl From<Degrees> for Radians {
@@ -54,20 +73,70 @@ impl num_traits::FromPrimitive for Radians {
5473
}
5574
}
5675

57-
impl Radians {
58-
/// Calculates the line in which the angle intercepts the `bounds`.
59-
pub fn to_distance(&self, bounds: &Rectangle) -> (Point, Point) {
60-
let angle = self.0 - FRAC_PI_2;
61-
let r = Vector::new(f32::cos(angle), f32::sin(angle));
76+
impl Sub for Radians {
77+
type Output = Self;
6278

63-
let distance_to_rect = f32::max(
64-
f32::abs(r.x * bounds.width / 2.0),
65-
f32::abs(r.y * bounds.height / 2.0),
66-
);
79+
fn sub(self, rhs: Self) -> Self::Output {
80+
Self(self.0 - rhs.0)
81+
}
82+
}
6783

68-
let start = bounds.center() - r * distance_to_rect;
69-
let end = bounds.center() + r * distance_to_rect;
84+
impl SubAssign for Radians {
85+
fn sub_assign(&mut self, rhs: Self) {
86+
self.0 = self.0 - rhs.0;
87+
}
88+
}
7089

71-
(start, end)
90+
impl Add for Radians {
91+
type Output = Self;
92+
93+
fn add(self, rhs: Self) -> Self::Output {
94+
Self(self.0 + rhs.0)
95+
}
96+
}
97+
98+
impl AddAssign for Radians {
99+
fn add_assign(&mut self, rhs: Radians) {
100+
self.0 = self.0 + rhs.0;
101+
}
102+
}
103+
104+
impl Mul for Radians {
105+
type Output = Self;
106+
107+
fn mul(self, rhs: Radians) -> Self::Output {
108+
Radians(self.0 * rhs.0)
109+
}
110+
}
111+
112+
impl Mul<f32> for Radians {
113+
type Output = Self;
114+
115+
fn mul(self, rhs: f32) -> Self::Output {
116+
Self(self.0 * rhs)
117+
}
118+
}
119+
120+
impl Mul<Radians> for f32 {
121+
type Output = Radians;
122+
123+
fn mul(self, rhs: Radians) -> Self::Output {
124+
Radians(self * rhs.0)
125+
}
126+
}
127+
128+
impl Div<f32> for Radians {
129+
type Output = Self;
130+
131+
fn div(self, rhs: f32) -> Self::Output {
132+
Radians(self.0 / rhs)
133+
}
134+
}
135+
136+
impl Div for Radians {
137+
type Output = Self;
138+
139+
fn div(self, rhs: Self) -> Self::Output {
140+
Self(self.0 / rhs.0)
72141
}
73142
}

examples/loading_spinners/src/circular.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ use iced::time::Instant;
99
use iced::widget::canvas;
1010
use iced::window::{self, RedrawRequest};
1111
use iced::{
12-
Background, Color, Element, Event, Length, Rectangle, Renderer, Size,
13-
Vector,
12+
Background, Color, Element, Event, Length, Radians, Rectangle, Renderer,
13+
Size, Vector,
1414
};
1515

1616
use super::easing::{self, Easing};
1717

1818
use std::f32::consts::PI;
1919
use std::time::Duration;
2020

21-
const MIN_RADIANS: f32 = PI / 8.0;
22-
const WRAP_RADIANS: f32 = 2.0 * PI - PI / 4.0;
21+
const MIN_ANGLE: Radians = Radians(PI / 8.0);
22+
const WRAP_ANGLE: Radians = Radians(2.0 * PI - PI / 4.0);
2323
const BASE_ROTATION_SPEED: u32 = u32::MAX / 80;
2424

2525
#[allow(missing_debug_implementations)]
@@ -139,7 +139,8 @@ impl Animation {
139139
progress: 0.0,
140140
rotation: rotation.wrapping_add(
141141
BASE_ROTATION_SPEED.wrapping_add(
142-
((WRAP_RADIANS / (2.0 * PI)) * u32::MAX as f32) as u32,
142+
(f64::from(WRAP_ANGLE / (2.0 * Radians::PI)) * f64::MAX)
143+
as u32,
143144
),
144145
),
145146
last: now,
@@ -318,7 +319,7 @@ where
318319

319320
let mut builder = canvas::path::Builder::new();
320321

321-
let start = state.animation.rotation() * 2.0 * PI;
322+
let start = Radians(state.animation.rotation() * 2.0 * PI);
322323

323324
match state.animation {
324325
Animation::Expanding { progress, .. } => {
@@ -327,17 +328,17 @@ where
327328
radius: track_radius,
328329
start_angle: start,
329330
end_angle: start
330-
+ MIN_RADIANS
331-
+ WRAP_RADIANS * (self.easing.y_at_x(progress)),
331+
+ MIN_ANGLE
332+
+ WRAP_ANGLE * (self.easing.y_at_x(progress)),
332333
});
333334
}
334335
Animation::Contracting { progress, .. } => {
335336
builder.arc(canvas::path::Arc {
336337
center: frame.center(),
337338
radius: track_radius,
338339
start_angle: start
339-
+ WRAP_RADIANS * (self.easing.y_at_x(progress)),
340-
end_angle: start + MIN_RADIANS + WRAP_RADIANS,
340+
+ WRAP_ANGLE * (self.easing.y_at_x(progress)),
341+
end_angle: start + MIN_ANGLE + WRAP_ANGLE,
341342
});
342343
}
343344
}

graphics/src/geometry/path/arc.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Build and draw curves.
2-
use iced_core::{Point, Vector};
2+
use iced_core::{Point, Radians, Vector};
33

44
/// A segment of a differentiable curve.
55
#[derive(Debug, Clone, Copy)]
@@ -8,10 +8,10 @@ pub struct Arc {
88
pub center: Point,
99
/// The radius of the arc.
1010
pub radius: f32,
11-
/// The start of the segment's angle in radians, clockwise rotation from positive x-axis.
12-
pub start_angle: f32,
13-
/// The end of the segment's angle in radians, clockwise rotation from positive x-axis.
14-
pub end_angle: f32,
11+
/// The start of the segment's angle, clockwise rotation from positive x-axis.
12+
pub start_angle: Radians,
13+
/// The end of the segment's angle, clockwise rotation from positive x-axis.
14+
pub end_angle: Radians,
1515
}
1616

1717
/// An elliptical [`Arc`].
@@ -22,19 +22,19 @@ pub struct Elliptical {
2222
/// The radii of the arc's ellipse. The horizontal and vertical half-dimensions of the ellipse will match the x and y values of the radii vector.
2323
pub radii: Vector,
2424
/// The clockwise rotation of the arc's ellipse.
25-
pub rotation: f32,
26-
/// The start of the segment's angle in radians, clockwise rotation from positive x-axis.
27-
pub start_angle: f32,
28-
/// The end of the segment's angle in radians, clockwise rotation from positive x-axis.
29-
pub end_angle: f32,
25+
pub rotation: Radians,
26+
/// The start of the segment's angle, clockwise rotation from positive x-axis.
27+
pub start_angle: Radians,
28+
/// The end of the segment's angle, clockwise rotation from positive x-axis.
29+
pub end_angle: Radians,
3030
}
3131

3232
impl From<Arc> for Elliptical {
3333
fn from(arc: Arc) -> Elliptical {
3434
Elliptical {
3535
center: arc.center,
3636
radii: Vector::new(arc.radius, arc.radius),
37-
rotation: 0.0,
37+
rotation: Radians(0.0),
3838
start_angle: arc.start_angle,
3939
end_angle: arc.end_angle,
4040
}

graphics/src/geometry/path/builder.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::geometry::path::{arc, Arc, Path};
22

3-
use iced_core::{Point, Size};
3+
use iced_core::{Point, Radians, Size};
44

55
use lyon_path::builder::{self, SvgPathBuilder};
66
use lyon_path::geom;
@@ -106,9 +106,11 @@ impl Builder {
106106
let arc = geom::Arc {
107107
center: math::Point::new(arc.center.x, arc.center.y),
108108
radii: math::Vector::new(arc.radii.x, arc.radii.y),
109-
x_rotation: math::Angle::radians(arc.rotation),
110-
start_angle: math::Angle::radians(arc.start_angle),
111-
sweep_angle: math::Angle::radians(arc.end_angle - arc.start_angle),
109+
x_rotation: math::Angle::radians(arc.rotation.0),
110+
start_angle: math::Angle::radians(arc.start_angle.0),
111+
sweep_angle: math::Angle::radians(
112+
(arc.end_angle - arc.start_angle).0,
113+
),
112114
};
113115

114116
let _ = self.raw.move_to(arc.sample(0.0));
@@ -165,8 +167,8 @@ impl Builder {
165167
self.arc(Arc {
166168
center,
167169
radius,
168-
start_angle: 0.0,
169-
end_angle: 2.0 * std::f32::consts::PI,
170+
start_angle: Radians(0.0),
171+
end_angle: Radians(2.0 * std::f32::consts::PI),
170172
});
171173
}
172174

0 commit comments

Comments
 (0)