epaint/shapes/
ellipse_shape.rs

1use crate::*;
2
3/// How to paint an ellipse.
4#[derive(Copy, Clone, Debug, PartialEq)]
5#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
6pub struct EllipseShape {
7    pub center: Pos2,
8
9    /// Radius is the vector (a, b) where the width of the Ellipse is 2a and the height is 2b
10    pub radius: Vec2,
11    pub fill: Color32,
12    pub stroke: Stroke,
13
14    /// Rotate ellipse by this many radians clockwise around its center.
15    pub angle: f32,
16}
17
18impl EllipseShape {
19    #[inline]
20    pub fn filled(center: Pos2, radius: Vec2, fill_color: impl Into<Color32>) -> Self {
21        Self {
22            center,
23            radius,
24            fill: fill_color.into(),
25            stroke: Default::default(),
26            angle: 0.0,
27        }
28    }
29
30    #[inline]
31    pub fn stroke(center: Pos2, radius: Vec2, stroke: impl Into<Stroke>) -> Self {
32        Self {
33            center,
34            radius,
35            fill: Default::default(),
36            stroke: stroke.into(),
37            angle: 0.0,
38        }
39    }
40
41    /// Set the rotation of the ellipse (in radians, clockwise).
42    /// The ellipse rotates around its center.
43    #[inline]
44    pub fn with_angle(mut self, angle: f32) -> Self {
45        self.angle = angle;
46        self
47    }
48
49    /// Set the rotation of the ellipse (in radians, clockwise) around a custom pivot point.
50    #[inline]
51    pub fn with_angle_and_pivot(mut self, angle: f32, pivot: Pos2) -> Self {
52        self.angle = angle;
53        let rot = emath::Rot2::from_angle(angle);
54        self.center = pivot + rot * (self.center - pivot);
55        self
56    }
57
58    /// The visual bounding rectangle (includes stroke width)
59    pub fn visual_bounding_rect(&self) -> Rect {
60        if self.fill == Color32::TRANSPARENT && self.stroke.is_empty() {
61            Rect::NOTHING
62        } else {
63            let rect = Rect::from_center_size(
64                Pos2::ZERO,
65                self.radius * 2.0 + Vec2::splat(self.stroke.width),
66            );
67            rect.rotate_bb(emath::Rot2::from_angle(self.angle))
68                .translate(self.center.to_vec2())
69        }
70    }
71}
72
73impl From<EllipseShape> for Shape {
74    #[inline(always)]
75    fn from(shape: EllipseShape) -> Self {
76        Self::Ellipse(shape)
77    }
78}