ratatui_widgets/canvas/
circle.rs1use ratatui_core::style::Color;
2
3use crate::canvas::{Painter, Shape};
4#[cfg(not(feature = "std"))]
5use crate::polyfills::F64Polyfills;
6
7#[derive(Debug, Default, Clone, PartialEq)]
9pub struct Circle {
10 pub x: f64,
12 pub y: f64,
14 pub radius: f64,
16 pub color: Color,
18}
19
20impl Circle {
21 pub const fn new(x: f64, y: f64, radius: f64, color: Color) -> Self {
23 Self {
24 x,
25 y,
26 radius,
27 color,
28 }
29 }
30}
31
32impl Shape for Circle {
33 fn draw(&self, painter: &mut Painter<'_, '_>) {
34 for angle in 0..360 {
35 let radians = f64::from(angle).to_radians();
36 let circle_x = self.radius.mul_add(radians.cos(), self.x);
37 let circle_y = self.radius.mul_add(radians.sin(), self.y);
38 if let Some((x, y)) = painter.get_point(circle_x, circle_y) {
39 painter.paint(x, y, self.color);
40 }
41 }
42 }
43}
44
45#[cfg(test)]
46mod tests {
47 use ratatui_core::buffer::Buffer;
48 use ratatui_core::layout::Rect;
49 use ratatui_core::style::Color;
50 use ratatui_core::symbols::Marker;
51 use ratatui_core::widgets::Widget;
52
53 use crate::canvas::{Canvas, Circle};
54
55 #[test]
56 fn test_it_draws_a_circle() {
57 let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 5));
58 let canvas = Canvas::default()
59 .paint(|ctx| {
60 ctx.draw(&Circle {
61 x: 5.0,
62 y: 2.0,
63 radius: 5.0,
64 color: Color::Reset,
65 });
66 })
67 .marker(Marker::Braille)
68 .x_bounds([-10.0, 10.0])
69 .y_bounds([-10.0, 10.0]);
70 canvas.render(buffer.area, &mut buffer);
71 let expected = Buffer::with_lines([
72 " ⣀⣀⣀ ",
73 " ⡞⠁ ⠈⢣",
74 " ⢇⡀ ⢀⡼",
75 " ⠉⠉⠉ ",
76 " ",
77 ]);
78 assert_eq!(buffer, expected);
79 }
80}