

In computer graphics, the midpoint circle algorithm is an algorithm used to determine the points needed for rasterizing a circle. It is a generalization of Bresenham's line algorithm. The algorithm can be further generalized to conic sections.[1][2][3]
Summary
editThis algorithm draws all eight octants simultaneously, starting from each cardinal direction (0°, 90°, 180°, 270°) and extends both ways to reach the nearest multiple of 45° (45°, 135°, 225°, 315°). It can determine where to stop because, when y = x, it has reached 45°. The reason for using these angles is shown in the above picture: As x increases, it neither skips nor repeats any x value until reaching 45°. So during the while loop, x increments by 1 with each iteration, and y decrements by 1 on occasion, never exceeding 1 in one iteration. This changes at 45° because that is the point where the tangent is rise=run. Whereas rise>run before and rise<run after.
The second part of the problem, the determinant, is far trickier. This determines when to decrement y. It usually comes after drawing the pixels in each iteration, because it never goes below the radius on the first pixel. Because in a continuous function, the function for a sphere is the function for a circle with the radius dependent on z (or whatever the third variable is), it stands to reason that the algorithm for a discrete (voxel) sphere would also rely on the midpoint circle algorithm. But when looking at a sphere, the integer radius of some adjacent circles is the same, but it is not expected to have the same exact circle adjacent to itself in the same hemisphere. Instead, a circle of the same radius needs a different determinant, to allow the curve to come in slightly closer to the center or extend out farther.
- One hundred fifty concentric circles drawn with the midpoint circle algorithm.
-
On left, all circles are drawn black.
-
On right, red, black and blue are used together to demonstrate the concentricity of the circles.
Algorithm
editThe objective of the algorithm is to approximate a circle or, more formally, the curve using pixels. For simplicity, we aim to approximate a circle of center and integer radius . Furthermore, we only draw to the first octant of the plane, for which we draw a curve from the point and proceed counterclockwise until an angle of 45°; the remaining octants can be trivially filled by rotating and/or mirroring that first segment of the curve around the center. At each step, the path is extended by choosing the adjacent pixel which best satisfies .
The "fast" direction in the first octant (the basis vector with the greater increase in value) is the -direction (see differentiation of trigonometric functions). In practice, this means that the algorithm always takes a step in the positive direction (upwards), and occasionally takes a step in the "slow" direction (the negative direction, leftwards). If the point drawn at step is , we thus impose and have to decide whether to set to or .
The choice is made by computing the distance between the decision midpoint to the center of the circle, hence the name of the algorithm. With the above assumption of a circle of center , this distance is equal to . If the midpoint mathematically lies outside the circle, and the innermost candidate point at should be drawn. Inversely if , the midpoint lies inside the circle and the candidate point best satisfies the circle equation. The full iteration for the first octant is as follows:
The iteration ends once the 45° slope line is crossed, therefore as soon as the condition is met.
Variant with integer-based arithmetic
editJust as with the parent Bresenham's line algorithm, this algorithm can be optimized to use only integer-based math. We start by defining the radius error as the difference between and the squared radius to avoid having to compute an expensive and non-integer square-root. This also slightly changes the condition for determining :
To eliminate the term, the radius error can be computed recursively:
Together with the condition on , computing becomes
An initial value for is found by approximation:
This optimized algorithm can be implemented in Python as follows:
import numpy as np # only for the image array
r = 67 # radius of the circle
img = np.zeros([2 * r + 1]*2, dtype=int) # image of size (2r + 1) x (2r + 1) to fit the circle
x, y, p = r, 0, 1 - r # initial values x0 = r, y0 = 0, p0 = 1 - r
while x >= y: # while the point (x, y) is in the first octant
for j, k in [(1, 1), (1, -1), (-1, 1), (-1, -1)]: # draw to all quadrants
img[j * x + r, k * y + r] = 1
img[k * y + r, j * x + r] = 1
x, y = x - (1 if p > 0 else 0), y + 1 # update x and y according to the radius error p
p += 1 - 2 * x + 2 * y if p > 0 else 1 + 2 * y # update the radius error p with updated x and y
Jesko's method
editAn improved midpoint circle algorithm[4] only requires 5 arithmetic operations per step (for 8 pixels) and is thus best suitable for low-performance systems. The counted operations in the main loop are:
- The comparison x >= y (is counted as a subtraction: x - y >= 0)
- y=y+1 [y++]
- t1 + y
- t1 - x
- The comparison t2 >= 0 is not counted as no real arithmetic takes place. In two's complement representation of the variables, only the sign bit has to be compared.
- x=x-1 [x--]
Operations: 5
t1 = r / 16
x = r
y = 0
Repeat Until x < y
Pixel (x, y) and all symmetric pixels are colored (8 times)
y = y + 1
t1 = t1 + y
t2 = t1 - x
If t2 >= 0
t1 = t2
x = x - 1
Drawing incomplete octants
editThe implementations above always draw only complete octants or circles. To draw only a certain arc from an angle to an angle , the algorithm needs first to calculate the and coordinates of these end points, where it is necessary to resort to trigonometric or square root computations (see methods of computing square roots). Then the Bresenham algorithm is run over the complete octant or circle and sets the pixels only if they fall into the wanted interval. After finishing this arc, the algorithm can be ended prematurely.
If the angles are given as slopes, then no trigonometry or square roots are necessary: simply check that is between the desired slopes.
Generalizations
editIt is also possible to use the same concept to rasterize a parabola, ellipse, or any other two-dimensional curve.[5]
References
edit- ^ Donald Hearn; M. Pauline Baker (1994). Computer graphics. Prentice-Hall. ISBN 978-0-13-161530-4.
- ^ Pitteway, M.L.V., "Algorithm for Drawing Ellipses or Hyperbolae with a Digital Plotter", Computer J., 10(3) November 1967, pp 282–289
- ^ Van Aken, J.R., "An Efficient Ellipse Drawing Algorithm", CG&A, 4(9), September 1984, pp 24–35
- ^ For the history of the publication of this algorithm see https://schwarzers.com/algorithms
- ^ Zingl, Alois (December 2014). "The Beauty of Bresenham's Algorithm: A simple implementation to plot lines, circles, ellipses and Bézier curves". easy.Filter. Alois Zingl. Retrieved 16 February 2017.
External links
edit- Drawing circles - An article on drawing circles, that derives from a simple scheme to an efficient one
- Midpoint Circle Algorithm in several programming languages

