epaint/shapes/
ellipse_shape.rs1use crate::*;
2
3#[derive(Copy, Clone, Debug, PartialEq)]
5#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
6pub struct EllipseShape {
7 pub center: Pos2,
8
9 pub radius: Vec2,
11 pub fill: Color32,
12 pub stroke: Stroke,
13
14 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 #[inline]
44 pub fn with_angle(mut self, angle: f32) -> Self {
45 self.angle = angle;
46 self
47 }
48
49 #[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 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}