mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 21:30:03 -04:00
epaint: Introduce ArcPieShape for Simplified Arc and Pie Rendering
Enables straightforward painting of arcs and pies using specified start and end angles.
This commit is contained in:
107
crates/epaint/src/shapes/arc_pie_shape.rs
Normal file
107
crates/epaint/src/shapes/arc_pie_shape.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use crate::*;
|
||||
|
||||
/// A arc or pie slice with a given start and end angle.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct ArcPieShape {
|
||||
pub center: Pos2,
|
||||
pub radius: f32,
|
||||
pub start_angle: f32,
|
||||
pub end_angle: f32,
|
||||
pub closed: bool,
|
||||
pub fill: Color32,
|
||||
pub stroke: PathStroke,
|
||||
}
|
||||
|
||||
impl ArcPieShape {
|
||||
/// Create a new arc or pie shape.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `center` - The center of the arc or pie.
|
||||
/// * `radius` - The radius of the arc or pie.
|
||||
/// * `start_angle` - The start angle of the arc or pie, in radians.
|
||||
/// * `end_angle` - The end angle of the arc or pie, in radians.
|
||||
/// * `closed` - If true, connect the center with the start and end points.
|
||||
/// * `fill` - The fill color of the arc or pie.
|
||||
/// * `stroke` - The stroke of the arc or pie.
|
||||
pub fn new(
|
||||
center: Pos2,
|
||||
radius: f32,
|
||||
start_angle: f32,
|
||||
end_angle: f32,
|
||||
closed: bool,
|
||||
fill: impl Into<Color32>,
|
||||
stroke: impl Into<PathStroke>,
|
||||
) -> Self {
|
||||
Self {
|
||||
center,
|
||||
radius,
|
||||
start_angle,
|
||||
end_angle,
|
||||
closed,
|
||||
fill: fill.into(),
|
||||
stroke: stroke.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new arc shape.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `center` - The center of the arc.
|
||||
/// * `radius` - The radius of the arc.
|
||||
/// * `start_angle` - The start angle of the arc, in radians.
|
||||
/// * `end_angle` - The end angle of the arc, in radians.
|
||||
/// * `stroke` - The stroke of the arc.
|
||||
pub fn arc(
|
||||
center: Pos2,
|
||||
radius: f32,
|
||||
start_angle: f32,
|
||||
end_angle: f32,
|
||||
stroke: impl Into<PathStroke>,
|
||||
) -> Self {
|
||||
Self::new(
|
||||
center,
|
||||
radius,
|
||||
start_angle,
|
||||
end_angle,
|
||||
false,
|
||||
Color32::TRANSPARENT,
|
||||
stroke,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new pie shape.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `center` - The center of the pie.
|
||||
/// * `radius` - The radius of the pie.
|
||||
/// * `start_angle` - The start angle of the pie, in radians.
|
||||
/// * `end_angle` - The end angle of the pie, in radians.
|
||||
/// * `fill` - The fill color of the pie.
|
||||
/// * `stroke` - The stroke of the pie.
|
||||
pub fn pie(
|
||||
center: Pos2,
|
||||
radius: f32,
|
||||
start_angle: f32,
|
||||
end_angle: f32,
|
||||
fill: impl Into<Color32>,
|
||||
stroke: impl Into<PathStroke>,
|
||||
) -> Self {
|
||||
Self::new(center, radius, start_angle, end_angle, true, fill, stroke)
|
||||
}
|
||||
|
||||
/// The visual bounding rectangle (includes stroke width)
|
||||
pub fn visual_bounding_rect(&self) -> Rect {
|
||||
if self.fill == Color32::TRANSPARENT && self.stroke.is_empty() {
|
||||
Rect::NOTHING
|
||||
} else {
|
||||
let rect = Rect::from_center_size(self.center, vec2(self.radius, self.radius));
|
||||
let start =
|
||||
self.center + vec2(self.start_angle.cos(), self.start_angle.sin()) * self.radius;
|
||||
let end = self.center + vec2(self.end_angle.cos(), self.end_angle.sin()) * self.radius;
|
||||
rect.union(Rect::from_two_pos(start, end))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod arc_pie_shape;
|
||||
mod bezier_shape;
|
||||
mod circle_shape;
|
||||
mod ellipse_shape;
|
||||
@@ -8,6 +9,7 @@ mod shape;
|
||||
mod text_shape;
|
||||
|
||||
pub use self::{
|
||||
arc_pie_shape::ArcPieShape,
|
||||
bezier_shape::{CubicBezierShape, QuadraticBezierShape},
|
||||
circle_shape::CircleShape,
|
||||
ellipse_shape::EllipseShape,
|
||||
|
||||
@@ -11,8 +11,8 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
CircleShape, CubicBezierShape, EllipseShape, PaintCallback, PathShape, QuadraticBezierShape,
|
||||
RectShape, TextShape,
|
||||
ArcPieShape, CircleShape, CubicBezierShape, EllipseShape, PaintCallback, PathShape,
|
||||
QuadraticBezierShape, RectShape, TextShape,
|
||||
};
|
||||
|
||||
/// A paint primitive such as a circle or a piece of text.
|
||||
@@ -32,6 +32,9 @@ pub enum Shape {
|
||||
/// For performance reasons it is better to avoid it.
|
||||
Vec(Vec<Shape>),
|
||||
|
||||
/// An arc or pie with a given start and end angle.
|
||||
ArcPie(ArcPieShape),
|
||||
|
||||
/// Circle with optional outline and fill.
|
||||
Circle(CircleShape),
|
||||
|
||||
@@ -255,6 +258,80 @@ impl Shape {
|
||||
Self::Path(PathShape::convex_polygon(points, fill, stroke))
|
||||
}
|
||||
|
||||
/// Generates an arc with a given start and end angle.
|
||||
///
|
||||
/// This function creates an arc centered at a specified point, with a specified radius.
|
||||
/// The arc starts at the `start_angle` and ends at the `end_angle`.
|
||||
/// Angles are specified in radians, with positive angles indicating clockwise rotation and negative angles indicating counterclockwise rotation.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `center` - The center point of the arc.
|
||||
/// * `radius` - The radius of the arc.
|
||||
/// * `start_angle` - The start angle of the arc, in radians.
|
||||
/// * `end_angle` - The end angle of the arc, in radians.
|
||||
/// * `stroke` - The stroke of the arc.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use epaint::{pos2, Color32, Shape, Stroke};
|
||||
/// let arc = Shape::arc(pos2(100.0, 100.0), 50.0, 0.0, std::f32::consts::PI, Stroke::new(3.0, Color32::RED));
|
||||
/// ```
|
||||
pub fn arc(
|
||||
center: Pos2,
|
||||
radius: f32,
|
||||
start_angle: f32,
|
||||
end_angle: f32,
|
||||
stroke: impl Into<PathStroke>,
|
||||
) -> Self {
|
||||
Self::ArcPie(ArcPieShape::arc(
|
||||
center,
|
||||
radius,
|
||||
start_angle,
|
||||
end_angle,
|
||||
stroke,
|
||||
))
|
||||
}
|
||||
|
||||
/// Generates an pie with a given start and end angle.
|
||||
///
|
||||
/// This function creates an arc centered at a specified point, with a specified radius.
|
||||
/// The pie starts at the `start_angle` and ends at the `end_angle`.
|
||||
/// Angles are specified in radians, with positive angles indicating clockwise rotation and negative angles indicating counterclockwise rotation.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `center` - The center point of the pie.
|
||||
/// * `radius` - The radius of the pie.
|
||||
/// * `start_angle` - The start angle of the pie, in radians.
|
||||
/// * `end_angle` - The end angle of the pie, in radians.
|
||||
/// * `stroke` - The stroke of the pie.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use epaint::{pos2, Color32, Shape, Stroke};
|
||||
/// let pie = Shape::pie(pos2(100.0, 100.0), 50.0, 0.0, std::f32::consts::PI, Color32::BLUE, Stroke::new(3.0, Color32::RED));
|
||||
/// ```
|
||||
pub fn pie(
|
||||
center: Pos2,
|
||||
radius: f32,
|
||||
start_angle: f32,
|
||||
end_angle: f32,
|
||||
fill: impl Into<Color32>,
|
||||
stroke: impl Into<PathStroke>,
|
||||
) -> Self {
|
||||
Self::ArcPie(ArcPieShape::pie(
|
||||
center,
|
||||
radius,
|
||||
start_angle,
|
||||
end_angle,
|
||||
fill,
|
||||
stroke,
|
||||
))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn circle_filled(center: Pos2, radius: f32, fill_color: impl Into<Color32>) -> Self {
|
||||
Self::Circle(CircleShape::filled(center, radius, fill_color))
|
||||
@@ -366,6 +443,7 @@ impl Shape {
|
||||
}
|
||||
rect
|
||||
}
|
||||
Self::ArcPie(arc_pie_shape) => arc_pie_shape.visual_bounding_rect(),
|
||||
Self::Circle(circle_shape) => circle_shape.visual_bounding_rect(),
|
||||
Self::Ellipse(ellipse_shape) => ellipse_shape.visual_bounding_rect(),
|
||||
Self::LineSegment { points, stroke } => {
|
||||
@@ -427,6 +505,11 @@ impl Shape {
|
||||
shape.transform(transform);
|
||||
}
|
||||
}
|
||||
Self::ArcPie(arc_pie_shape) => {
|
||||
arc_pie_shape.center = transform * arc_pie_shape.center;
|
||||
arc_pie_shape.radius *= transform.scaling;
|
||||
arc_pie_shape.stroke.width *= transform.scaling;
|
||||
}
|
||||
Self::Circle(circle_shape) => {
|
||||
circle_shape.center = transform * circle_shape.center;
|
||||
circle_shape.radius *= transform.scaling;
|
||||
|
||||
Reference in New Issue
Block a user