Rebol3 Code Examplex
Bitmap/Midpoint circle algorithm
Draw circles with the midpoint circle algorithm.
Rebol [
title: "Rosetta code: Bitmap/Midpoint circle algorithm"
file: %Bitmap-Midpoint_circle_algorithm.r3
url: https://rosettacode.org/wiki/Bitmap/Midpoint_circle_algorithm
]
draw-circle: func [
"Draw a circle on an image using the Midpoint Circle Algorithm."
bitmap [image!] center [pair!] radius [integer!] color [tuple!]
][
x: center/x ;; unpack center coords from pair for arithmetic
y: center/y
dx: radius dy: 0
err: 1 - radius ;; initial error term for midpoint decision
while [dx >= dy] [ ;; iterate through the first octant only
;; Mirror the single computed point into all 8 octants at once,
;; exploiting the 8-fold symmetry of the circle.
bitmap/(as-pair x + dx y + dy): color ; octant 1
bitmap/(as-pair x - dx y + dy): color ; octant 2
bitmap/(as-pair x + dx y - dy): color ; octant 8
bitmap/(as-pair x - dx y - dy): color ; octant 7
bitmap/(as-pair x + dy y + dx): color ; octant 3
bitmap/(as-pair x - dy y + dx): color ; octant 4 (swapped dx/dy)
bitmap/(as-pair x + dy y - dx): color ; octant 5
bitmap/(as-pair x - dy y - dx): color ; octant 6
dy: dy + 1 ;; advance one step along the minor axis
;; Update the error term and conditionally step inward on dx.
;; err < 0 means we are still inside the circle boundary
either err < 0 [
err: err + (2 * dy) + 1 ;; correct error for dy step
][
dx: dx - 1 ;; step inward on major axis
err: err + (2 * (dy - dx)) + 1 ;; correct error for both steps
]
]
]
img: make image! 29x29 ;; create a blank 29x29 canvas (white by default)
draw-circle img 15x15 5 black ;; small inner circle
draw-circle img 15x15 10 red ;; mid-size red ring
draw-circle img 15x15 14 green ;; large green ring, nearly fills the canvas
;; scale up 10x with nearest-neighbour (Box) to keep pixel edges sharp
img: resize/filter img 290 'Box
save %midpoint-circles.png img
try [view img]