Skip to content

Commit

Permalink
Simplify arc drawing
Browse files Browse the repository at this point in the history
  • Loading branch information
bash committed Jul 8, 2024
1 parent 6c4ed36 commit ecda534
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 48 deletions.
53 changes: 14 additions & 39 deletions crates/egui/src/widgets/theme_switch/arc.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,26 @@
use crate::{vec2, Color32, Painter, Pos2, Shape, Stroke, Vec2};
use epaint::CubicBezierShape;
use emath::{vec2, Pos2, Vec2};
use epaint::{Color32, CubicBezierShape, Stroke};
use std::f32::consts::FRAC_PI_2;
use std::ops::RangeInclusive;

#[derive(Debug, Clone, PartialEq)]
pub struct ArcShape {
center: Pos2,
radius: f32,
range: RangeInclusive<f32>,
fill: Color32,
stroke: Stroke,
}

impl ArcShape {
pub fn new(
center: impl Into<Pos2>,
radius: impl Into<f32>,
range: impl Into<RangeInclusive<f32>>,
fill: impl Into<Color32>,
stroke: impl Into<Stroke>,
) -> Self {
Self {
center: center.into(),
radius: radius.into(),
range: range.into(),
fill: fill.into(),
stroke: stroke.into(),
}
}

pub fn approximate_as_beziers(&self) -> impl Iterator<Item = CubicBezierShape> + Clone {
let fill = self.fill;
let stroke = self.stroke;
approximate_with_beziers(self.center, self.radius, self.range.clone())
.map(move |p| CubicBezierShape::from_points_stroke(p, false, fill, stroke))
}

pub fn paint(&self, painter: &Painter) {
painter.extend(self.approximate_as_beziers().map(Shape::from));
}
pub(crate) fn approximate_with_beziers(
center: impl Into<Pos2>,
radius: impl Into<f32>,
range: impl Into<RangeInclusive<f32>>,
fill: impl Into<Color32>,
stroke: impl Into<Stroke>,
) -> impl Iterator<Item = CubicBezierShape> + Clone {
let fill = fill.into();
let stroke = stroke.into();
approximate_with_beziers_impl(center.into(), radius.into(), range.into())
.map(move |p| CubicBezierShape::from_points_stroke(p, false, fill, stroke))
}

// Implementation based on:
// Riškus, Aleksas. (2006). Approximation of a cubic bezier curve by circular arcs and vice versa.
// Information Technology and Control. 35.

fn approximate_with_beziers(
fn approximate_with_beziers_impl(
center: Pos2,
radius: f32,
range: RangeInclusive<f32>,
Expand Down
2 changes: 2 additions & 0 deletions crates/egui/src/widgets/theme_switch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ impl<'a> ThemeSwitch<'a> {
}
}

/// Disables the "Follow System" option. Intentionally internal.
/// Should be removed once https://github.com/emilk/egui/issues/4490 is done.
pub(crate) fn show_follow_system(mut self, show_follow_system: bool) -> Self {
self.show_follow_system = show_follow_system;
self
Expand Down
13 changes: 4 additions & 9 deletions crates/egui/src/widgets/theme_switch/moon.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::arc::ArcShape;
use super::arc;
use crate::epaint::{CubicBezierShape, PathShape, PathStroke};
use crate::{Color32, Painter, Pos2, Vec2};
use std::f32::consts::{PI, TAU};
Expand Down Expand Up @@ -27,14 +27,14 @@ pub(crate) fn moon(painter: &Painter, center: Pos2, radius: f32, color: Color32)
let occlusion_start = direction_angle + PI - angle / 2.;
let occlusion_end = direction_angle + PI + angle / 2.;

let main_arc = ArcShape::new(
let main_arc = arc::approximate_with_beziers(
center,
radius,
start..=(start + size),
Color32::TRANSPARENT,
(stroke_width, color),
);
let occluding_arc = ArcShape::new(
let occluding_arc = arc::approximate_with_beziers(
occluding_center,
radius,
occlusion_end..=occlusion_start,
Expand All @@ -44,12 +44,7 @@ pub(crate) fn moon(painter: &Painter, center: Pos2, radius: f32, color: Color32)

// We join the beziers together to a path which improves
// the drawing of the joints somewhat.
let path = to_path(
main_arc
.approximate_as_beziers()
.chain(occluding_arc.approximate_as_beziers()),
(stroke_width, color),
);
let path = to_path(main_arc.chain(occluding_arc), (stroke_width, color));

painter.add(path);
}
Expand Down

0 comments on commit ecda534

Please sign in to comment.