The Midpoint Ellipse Algorithm is a computer graphics algorithm used to draw an ellipse on a digital display (raster grid). It efficiently calculates the pixels to plot an ellipse given its center (xc, yc)
and semi-major and semi-minor axes rx
and ry
. The algorithm leverages the ellipse's symmetry and uses a decision parameter to select pixels, minimizing computational complexity.
(xc, yc)
with semi-axes rx
and ry
on a discrete grid.(xc, yc)
, semi-major axis rx
, and semi-minor axis ry
.rx2
, ry2
, and their products: 2rx2
, 2ry2
.(x, y) = (0, ry)
.p1 = ry2 - rx2ry + (rx2/4)
.(xc+x, yc+y)
, (xc-x, yc+y)
, (xc+x, yc-y)
, (xc-x, yc-y)
.p1 < 0
: Increment x
, update p1 = p1 + 2ry2x + ry2
.x
, decrement y
, update p1 = p1 + 2ry2x - 2rx2y + ry2
.2ry2x ≥ 2rx2y
.p2 = ry2(x + 1/2)2 + rx2(y - 1)2 - rx2ry2
.p2 > 0
: Decrement y
, update p2 = p2 - 2rx2y + rx2
.x
, decrement y
, update p2 = p2 + 2ry2x - 2rx2y + rx2
.y ≤ 0
.Draw an ellipse with center (0, 0)
, rx = 4
, ry = 3
:
(xc, yc) = (0, 0)
, rx = 4
, ry = 3
.rx2 = 16
, ry2 = 9
, 2rx2 = 32
, 2ry2 = 18
.(x, y) = (0, 3)
, p1 = 9 - 16×3 + 16/4 = -35
.(0, 3)
, (0, -3)
, (0, 3)
, (0, -3)
(overlapping).p1 = -35 < 0
, x = 1
, p1 = -35 + 18×1 + 9 = -8
, plot (±1, ±3)
.p1 = -8 < 0
, x = 2
, p1 = -8 + 18×2 + 9 = 37
, plot (±2, ±3)
.p1 = 37 > 0
, x = 3
, y = 2
, p1 = 37 + 18×3 - 32×2 + 9 = -14
, plot (±3, ±2)
.2×9×3 = 54 ≥ 32×2 = 64
(close enough, transition to Region 2).(x, y) = (3, 2)
, p2 = 9(3+0.5)2 + 16(2-1)2 - 16×9 = -83.25
.(±3, ±2)
.p2 < 0
, x = 4
, y = 1
, p2 = -83.25 + 18×4 - 32×1 + 16 = -27.25
, plot (±4, ±1)
.p2 < 0
, x = 4
, y = 0
, p2 = -27.25 - 32×0 + 16 = -11.25
, plot (±4, 0)
.y = 0
.(0, ±3)
, (±1, ±3)
, (±2, ±3)
, (±3, ±2)
, (±4, ±1)
, (±4, 0)
.rx = ry
. The ellipse algorithm is more complex due to handling different axes.void MidpointEllipse(int xc, int yc, int rx, int ry) {
int rx2 = rx * rx, ry2 = ry * ry;
int twoRx2 = 2 * rx2, twoRy2 = 2 * ry2;
int x = 0, y = ry;
int p1 = ry2 - rx2 * ry + rx2 / 4;
// Region 1
while (twoRy2 * x <= twoRx2 * y) {
plot(xc + x, yc + y); plot(xc - x, yc + y);
plot(xc + x, yc - y); plot(xc - x, yc - y);
if (p1 < 0) {
x++;
p1 = p1 + twoRy2 * x + ry2;
} else {
x++; y--;
p1 = p1 + twoRy2 * x - twoRx2 * y + ry2;
}
}
// Region 2
int p2 = ry2 * (x + 0.5) * (x + 0.5) + rx2 * (y - 1) * (y - 1) - rx2 * ry2;
while (y >= 0) {
plot(xc + x, yc + y); plot(xc - x, yc + y);
plot(xc + x, yc - y); plot(xc - x, yc - y);
if (p2 > 0) {
y--;
p2 = p2 - twoRx2 * y + rx2;
} else {
x++; y--;
p2 = p2 + twoRy2 * x - twoRx2 * y + rx2;
}
}
}