Midpoint Ellipse Algorithm

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.

Key Concepts

  1. Purpose: To determine the coordinates of pixels forming an ellipse centered at (xc, yc) with semi-axes rx and ry on a discrete grid.
  2. Basis: Uses the midpoint between candidate pixels to decide which pixel to plot, based on the ellipse equation.
  3. Symmetry: Exploits the four-way symmetry of an ellipse to reduce calculations, plotting pixels in all four quadrants.
  4. Efficiency: Avoids direct computation of the ellipse equation for every pixel, using incremental decision parameters.

Steps of the Midpoint Ellipse Algorithm

  1. Input: Take the center (xc, yc), semi-major axis rx, and semi-minor axis ry.
  2. Initialize Parameters:
    • Compute rx2, ry2, and their products: 2rx2, 2ry2.
    • Divide the ellipse into two regions based on the slope of the tangent (Region 1: |slope| < 1, Region 2: |slope| > 1).
  3. Region 1 (Top part of ellipse):
    • Start at (x, y) = (0, ry).
    • Initialize decision parameter: p1 = ry2 - rx2ry + (rx2/4).
    • For each step:
      • Plot symmetric points: (xc+x, yc+y), (xc-x, yc+y), (xc+x, yc-y), (xc-x, yc-y).
      • If p1 < 0: Increment x, update p1 = p1 + 2ry2x + ry2.
      • Else: Increment x, decrement y, update p1 = p1 + 2ry2x - 2rx2y + ry2.
    • Stop when 2ry2x ≥ 2rx2y.
  4. Region 2 (Side part of ellipse):
    • Start from the last point of Region 1.
    • Initialize decision parameter: p2 = ry2(x + 1/2)2 + rx2(y - 1)2 - rx2ry2.
    • For each step:
      • Plot symmetric points as above.
      • If p2 > 0: Decrement y, update p2 = p2 - 2rx2y + rx2.
      • Else: Increment x, decrement y, update p2 = p2 + 2ry2x - 2rx2y + rx2.
    • Stop when y ≤ 0.
  5. Termination: Stop when all quadrants are plotted.

Example

Draw an ellipse with center (0, 0), rx = 4, ry = 3:

  1. Input: (xc, yc) = (0, 0), rx = 4, ry = 3.
  2. Initialize: rx2 = 16, ry2 = 9, 2rx2 = 32, 2ry2 = 18.
  3. Region 1:
    • Start: (x, y) = (0, 3), p1 = 9 - 16×3 + 16/4 = -35.
    • Plot: (0, 3), (0, -3), (0, 3), (0, -3) (overlapping).
    • Step 1: p1 = -35 < 0, x = 1, p1 = -35 + 18×1 + 9 = -8, plot (±1, ±3).
    • Step 2: p1 = -8 < 0, x = 2, p1 = -8 + 18×2 + 9 = 37, plot (±2, ±3).
    • Step 3: p1 = 37 > 0, x = 3, y = 2, p1 = 37 + 18×3 - 32×2 + 9 = -14, plot (±3, ±2).
    • Stop: 2×9×3 = 54 ≥ 32×2 = 64 (close enough, transition to Region 2).
  4. Region 2:
    • Start: (x, y) = (3, 2), p2 = 9(3+0.5)2 + 16(2-1)2 - 16×9 = -83.25.
    • Plot: (±3, ±2).
    • Step 1: p2 < 0, x = 4, y = 1, p2 = -83.25 + 18×4 - 32×1 + 16 = -27.25, plot (±4, ±1).
    • Step 2: p2 < 0, x = 4, y = 0, p2 = -27.25 - 32×0 + 16 = -11.25, plot (±4, 0).
    • Stop: y = 0.
  5. Output: Pixels plotted include (0, ±3), (±1, ±3), (±2, ±3), (±3, ±2), (±4, ±1), (±4, 0).

Advantages of Midpoint Ellipse Algorithm

  1. Efficiency: Uses incremental calculations and symmetry to reduce computational load.
  2. Accuracy: Selects pixels closest to the true ellipse, producing smooth curves.
  3. Versatility: Works for any ellipse orientation and axis lengths.
  4. Simplicity: Relatively easy to implement with integer arithmetic for decision parameters.

Disadvantages of Midpoint Ellipse Algorithm

  1. Complexity: More complex than line-drawing algorithms due to handling two regions.
  2. Rounding Errors: Integer approximations may cause slight deviations in pixel selection.
  3. Limited to Ellipses: Not applicable for other curves like hyperbolas or arbitrary shapes.
  4. Resolution Dependency: Quality depends on display resolution, affecting smoothness.

Applications

Comparison with Other Algorithms

Pseudo-Code

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;
        }
    }
}