Midpoint Circle Algorithm
The midpoint circle algorithm determines the pixel points needed to draw a circle. Circles are a frequently used component in pictures and graphs.
Given a center and radius:
Center position : (xc, yc)
Radius : rCircle equation approaches
The Pythagorean theorem expresses the circle distance relationship in Cartesian coordinates as:
(x - xc)^2 + (y - yc)^2 = r^2That equation can calculate successive y values by stepping x:
y = yc ± sqrt( r^2 - (xc - x)^2 )This approach is slow, and spacing between pixels is not uniform. One way to eliminate unequal spacing is to use polar coordinates r and θ:
x = xc + r cos θ
y = yc + r sin θThe step size for θ depends on the display device.
Computations can be reduced by considering circle symmetry. The shape is similar in each quadrant — and in each octant. Once pixel positions for one octant are calculated, their reflections fill the rest of the circle.
Floating-point methods still cost too much computation time. The midpoint circle algorithm reduces that cost with integer decision parameters.
The midpoint circle algorithm
Screen center point : (xc, yc)
Calculated pixel offset : (x, y)
Screen position : (xc + x, yc + y)The circle function is defined as:
fcircle(x, y) = x^2 + y^2 - r^2Any point (x, y) on the boundary of a circle with radius r satisfies fcircle(x, y) = 0:
fcircle(x, y) < 0 → (x, y) is inside the circle boundary
fcircle(x, y) = 0 → (x, y) is on the circle boundary
fcircle(x, y) > 0 → (x, y) is outside the circle boundaryDecision parameter
Sampling position:
(xk, yk)Next pixel candidates:
(xk+1, yk) or (xk+1, yk-1)The circle-function tests are performed at the midpoint between those two pixels. Assuming the pixel at (xk, yk) was just plotted, decide whether (xk+1, yk) or (xk+1, yk-1) is closer to the circle:
pk = fcircle(xk+1, yk - 1/2)
= (xk + 1)^2 + (yk - 1/2)^2 - r^2- If
pk < 0, the midpoint is inside the circle → choose(xk+1, yk) - Otherwise the midpoint is outside or on the boundary → choose
(xk+1, yk-1)
Incremental updates
Successive decision parameters use incremental calculations:
pk+1 = fcircle(xk+1 + 1, yk+1 - 1/2)
= [(xk + 1) + 1]^2 + [yk+1 - 1/2]^2 - r^2
pk+1 = pk + 2(xk+1) + (yk+1^2 - yk^2) - (yk+1 - yk) + 1where yk+1 is either yk or yk-1, depending on the sign of pk.
Increments for pk+1:
if pk < 0: pk+1 = pk + 2xk+1 + 1
otherwise: pk+1 = pk + 2xk+1 + 1 - 2yk+1The doubled terms also update incrementally:
2xk+1 = 2xk + 2
2yk+1 = 2yk - 2Initial decision parameter
Start at (x0, y0) = (0, r):
p0 = fcircle(1, r - 1/2)
= 1 + (r - 1/2)^2 - r^2
= 5/4 - rIf radius r is an integer, round to:
p0 = 1 - rsince all later increments are integers.
Algorithm steps
- Input radius
rand center(xc, yc). Obtain the first point on the origin-centered circle as(x0, y0) = (0, r). - Calculate the initial decision parameter:
p0 = 5/4 - r- At each
xkposition, starting atk = 0:
if pk < 0:
next point = (xk+1, yk)
pk+1 = pk + 2xk+1 + 1
else:
next point = (xk+1, yk-1)
pk+1 = pk + 2xk+1 + 1 - 2yk+1
where:
2xk+1 = 2xk + 2
2yk+1 = 2yk - 2- Determine symmetry points in the other seven octants.
- Move each calculated pixel
(x, y)onto the circular path centered on(xc, yc):
plot(x + xc, y + yc)- Repeat steps 3–5 until
x ≥ y.
Pseudocode
Input: xc, yc, r
x ← 0
y ← r
p ← 1 - r
plotEightWay(xc, yc, x, y)
while x < y:
x ← x + 1
if p < 0:
p ← p + 2x + 1
else:
y ← y - 1
p ← p + 2(x - y) + 1
plotEightWay(xc, yc, x, y)Eight-way symmetry plots:
(xc + x, yc + y) (xc - x, yc + y)
(xc + x, yc - y) (xc - x, yc - y)
(xc + y, yc + x) (xc - y, yc + x)
(xc + y, yc - x) (xc - y, yc - x)Circle Algorithm Using C Programming
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
void cliplot(int xctr, int yctr, int x, int y);
void Drawcircle(int x1, int y1, int r);
void main() {
int gd = DETECT, gm;
int x, y, r;
printf("Enter the Mid points and Radius: ");
scanf("%d%d%d", &x, &y, &r);
initgraph(&gd, &gm, "");
Drawcircle(x, y, r);
getch();
closegraph();
}
void Drawcircle(int x1, int y1, int r) {
int x = 0, y = r, p = 1 - r;
cliplot(x1, y1, x, y);
while (x < y) {
x++;
if (p < 0)
p += 2 * x + 1;
else {
y--;
p += 2 * (x - y) + 1;
}
cliplot(x1, y1, x, y);
}
}
void cliplot(int xctr, int yctr, int x, int y) {
putpixel(xctr + x, yctr + y, 1);
putpixel(xctr - x, yctr + y, 1);
putpixel(xctr + x, yctr - y, 1);
putpixel(xctr - x, yctr - y, 1);
putpixel(xctr + y, yctr + x, 1);
putpixel(xctr - y, yctr + x, 1);
putpixel(xctr + y, yctr - x, 1);
putpixel(xctr - y, yctr - x, 1);
}Sample Output
Enter the Mid points and Radius: 200 200 80
(draws a circle centered at (200, 200) with radius 80)