Draws a circle via `rasops` with `center` and `radius`. This implements the [Midpoint circle algorithm](https://en.wikipedia.org/wiki/Midpoint_circle_algorithm).
(rasops: &mut R, center: PixelsXY, radius: u16)
| 223 | /// This implements the [Midpoint circle |
| 224 | /// algorithm](https://en.wikipedia.org/wiki/Midpoint_circle_algorithm). |
| 225 | pub fn draw_circle_filled<R>(rasops: &mut R, center: PixelsXY, radius: u16) -> io::Result<()> |
| 226 | where |
| 227 | R: RasterOps, |
| 228 | { |
| 229 | fn line<R: RasterOps>(rasops: &mut R, x1: i16, y1: i16, x2: i16, y2: i16) -> io::Result<()> { |
| 230 | rasops.draw_line(PixelsXY { x: x1, y: y1 }, PixelsXY { x: x2, y: y2 }) |
| 231 | } |
| 232 | |
| 233 | if radius == 0 { |
| 234 | return Ok(()); |
| 235 | } else if radius == 1 { |
| 236 | return rasops.draw_pixel(center); |
| 237 | } |
| 238 | |
| 239 | let (diameter, radius): (i16, i16) = match radius.checked_mul(2) { |
| 240 | Some(d) => match i16::try_from(d) { |
| 241 | Ok(d) => (d, radius as i16), |
| 242 | |
| 243 | Err(_) => return Err(io::Error::new(io::ErrorKind::InvalidInput, "Radius is too big")), |
| 244 | }, |
| 245 | None => return Err(io::Error::new(io::ErrorKind::InvalidInput, "Radius is too big")), |
| 246 | }; |
| 247 | |
| 248 | let mut x: i16 = radius - 1; |
| 249 | let mut y: i16 = 0; |
| 250 | let mut tx: i16 = 1; |
| 251 | let mut ty: i16 = 1; |
| 252 | let mut e: i16 = tx - diameter; |
| 253 | |
| 254 | while x >= y { |
| 255 | line(rasops, center.x + x, center.y - y, center.x + x, center.y + y)?; |
| 256 | line(rasops, center.x - x, center.y - y, center.x - x, center.y + y)?; |
| 257 | line(rasops, center.x + y, center.y - x, center.x + y, center.y + x)?; |
| 258 | line(rasops, center.x - y, center.y - x, center.x - y, center.y + x)?; |
| 259 | |
| 260 | if e <= 0 { |
| 261 | y += 1; |
| 262 | e += ty; |
| 263 | ty += 2; |
| 264 | } |
| 265 | |
| 266 | if e > 0 { |
| 267 | x -= 1; |
| 268 | tx += 2; |
| 269 | e += tx - diameter; |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | Ok(()) |
| 274 | } |
| 275 | |
| 276 | /// Draws a polygon via `rasops`. |
| 277 | pub fn draw_poly<R>(rasops: &mut R, points: &[PixelsXY]) -> io::Result<()> |