From eb6207e1198e7a4b06531e70baefc0a32f3cf407 Mon Sep 17 00:00:00 2001 From: "0m.ax" Date: Sat, 19 Jul 2025 02:19:11 +0200 Subject: [PATCH] squircle --- src/main.rs | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/main.rs b/src/main.rs index d00d10e..87307df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -119,6 +119,80 @@ impl Drawable for BouncingImage { } } +struct Circle { + x: u32, + y: u32, + radius: i32 +} +impl Circle { + + fn new(x:u32, y: u32,radius:i32) -> Self { + Circle { + x, + y, + radius + } + } + + /// This exploits the eight-way symmetry of a circle. + fn draw_circle_octants(&mut self, display: &mut Display, cx: u16, cy: u16, x: u16, y: u16, r: u8, g: u8, b: u8) { + display.set_pixel(cx + x, cy + y, r, g, b); + display.set_pixel(cx - x, cy + y, r, g, b); + display.set_pixel(cx + x, cy - y, r, g, b); + display.set_pixel(cx - x, cy - y, r, g, b); + display.set_pixel(cx + y, cy + x, r, g, b); + display.set_pixel(cx - y, cy + x, r, g, b); + display.set_pixel(cx + y, cy - x, r, g, b); + display.set_pixel(cx - y, cy - x, r, g, b); + } + + /// Draws a circle using the Midpoint Circle Algorithm. + /// + /// # Arguments + /// * `center_x`: The x-coordinate of the circle's center. + /// * `center_y`: The y-coordinate of the circle's center. + /// * `radius`: The radius of the circle. Must be non-negative. + /// * `r`, `g`, `b`: The RGB color components for the circle. + pub fn draw_circle(&mut self, display: &mut Display, center_x: u32, center_y: u32, radius: i32, r: u8, g: u8, b: u8) { + if radius < 0 { + // Or return an error: Err("Radius cannot be negative".into()) + return; + } + + let mut x = 0; + let mut y = radius; + // Initial decision parameter + let mut d = 3 - 2 * radius; + + // Iterate through the first octant and draw points in all 8 octants + while y >= x { + self.draw_circle_octants(display,center_x.try_into().unwrap(), center_y.try_into().unwrap(), x.try_into().unwrap(), y.try_into().unwrap(), r, g, b); + + x += 1; + + // Update the decision parameter + if d > 0 { + y -= 1; + d = d + 4 * (x - y) + 10; + } else { + d = d + 4 * x + 6; + } + } + } + +} +impl Drawable for Circle { + + fn rate(&self) -> u32 { + 1 + } + + /// Helper method to draw the 8 symmetric points for a given (x, y) offset. + fn draw_and_move(&mut self, display: &mut Display) { + self.draw_circle(display,self.x,self.y,self.radius,255,255,255); + } +} + /// Manages the connection and data sent to the display. struct Display { socket: UdpSocket, @@ -202,6 +276,7 @@ fn main() { Box::new(BouncingImage::new("images/spade.png", 32, -12, 1, 0, 0)), Box::new(BouncingImage::new("images/dvdvideo.png", 20, 6, 5, 1000, 800)), Box::new(BouncingImage::new("images/hackaday.png", 40, 18, 3, 500, 800)), + Box::new(Circle::new(1920/2,1080/2,128)) ]; let mut display = Display::new(DISPLAY_HOST, DISPLAY_PORT);