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)
| 165 | /// This implements the [Midpoint circle |
| 166 | /// algorithm](https://en.wikipedia.org/wiki/Midpoint_circle_algorithm). |
| 167 | pub fn draw_circle<R>(rasops: &mut R, center: PixelsXY, radius: u16) -> io::Result<()> |
| 168 | where |
| 169 | R: RasterOps, |
| 170 | { |
| 171 | fn point<R: RasterOps>(rasops: &mut R, x: i16, y: i16) -> io::Result<()> { |
| 172 | rasops.draw_pixel(PixelsXY { x, y }) |
| 173 | } |
| 174 | |
| 175 | if radius == 0 { |
| 176 | return Ok(()); |
| 177 | } else if radius == 1 { |
| 178 | return rasops.draw_pixel(center); |
| 179 | } |
| 180 | |
| 181 | let (diameter, radius): (i16, i16) = match radius.checked_mul(2) { |
| 182 | Some(d) => match i16::try_from(d) { |
| 183 | Ok(d) => (d, radius as i16), |
| 184 | Err(_) => return Err(io::Error::new(io::ErrorKind::InvalidInput, "Radius is too big")), |
| 185 | }, |
| 186 | None => return Err(io::Error::new(io::ErrorKind::InvalidInput, "Radius is too big")), |
| 187 | }; |
| 188 | |
| 189 | let mut x: i16 = radius - 1; |
| 190 | let mut y: i16 = 0; |
| 191 | let mut tx: i16 = 1; |
| 192 | let mut ty: i16 = 1; |
| 193 | let mut e: i16 = tx - diameter; |
| 194 | |
| 195 | while x >= y { |
| 196 | point(rasops, center.x + x, center.y - y)?; |
| 197 | point(rasops, center.x + x, center.y + y)?; |
| 198 | point(rasops, center.x - x, center.y - y)?; |
| 199 | point(rasops, center.x - x, center.y + y)?; |
| 200 | point(rasops, center.x + y, center.y - x)?; |
| 201 | point(rasops, center.x + y, center.y + x)?; |
| 202 | point(rasops, center.x - y, center.y - x)?; |
| 203 | point(rasops, center.x - y, center.y + x)?; |
| 204 | |
| 205 | if e <= 0 { |
| 206 | y += 1; |
| 207 | e += ty; |
| 208 | ty += 2; |
| 209 | } |
| 210 | |
| 211 | if e > 0 { |
| 212 | x -= 1; |
| 213 | tx += 2; |
| 214 | e += tx - diameter; |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | Ok(()) |
| 219 | } |
| 220 | |
| 221 | /// Draws a circle via `rasops` with `center` and `radius`. |
| 222 | /// |