Skip to main content
← All posts

Part 2: Scan Conversion & Line Generation: DDA vs Bresenham's Integer Algorithm

Md. Harun-Or-RoshidNov 5, 20265 min readArticle
Part 2: Scan Conversion & Line Generation: DDA vs Bresenham's Integer Algorithm

Mathematical Foundations of Rasterization

In computer graphics, scan conversion is the algorithmic process of digitizing continuous mathematical primitives (lines, curves, and polygons) into a discrete grid of integer pixel coordinates $(x, y)$ in the framebuffer. A straight line segment between endpoints $(x_0, y_0)$ and $(x_1, y_1)$ represents an infinite set of real numbers; rasterization must approximate this continuum using a finite lattice of pixels while preserving uniform brightness, minimal aliasing, and maximum throughput. In this article, we rigorously analyze and implement the two cornerstone line algorithms: the Digital Differential Analyzer (DDA) and Bresenham's Integer Line Algorithm.

1. The Differential Equation of a Line & Slope Dynamics

In Cartesian geometry, the slope-intercept form of a straight line is:

y = m \cdot x + c

Where the slope $m$ and y-intercept $c$ are determined by the delta differentials $\Delta x = x_1 - x_0$ and $\Delta y = y_1 - y_0$:

m = \frac{\Delta y}{\Delta x} = \frac{y_1 - y_0}{x_1 - x_0}, \quad c = y_0 - m \cdot x_0

Directly evaluating $y = m \cdot x + c$ for every integer $x$ requires floating-point multiplication and addition per step. More critically, when $|m| > 1$, incrementing $x$ by 1 produces $\Delta y > 1$, causing gaps and disconnected pixel holes along steep lines. Robust rasterization algorithms must dynamically adapt step increments according to the line's slope magnitude.

2. Digital Differential Analyzer (DDA) Algorithm

The DDA Algorithm is an incremental scan-conversion method based on calculating differential increments $\Delta x$ and $\Delta y$. Instead of computing full multiplications at each coordinate, DDA samples the line at unit intervals along the coordinate axis with the largest differential.

Case 1: Shallow Slope ($|m| \le 1$)

Step along $x$ in unit intervals: $\Delta x = 1$. The next y-coordinate is incremented incrementally by the slope:

x_{k+1} = x_k + 1, \quad y_{k+1} = y_k + m

The plotted pixel is $(x_{k+1}, \text{round}(y_{k+1}))$.

Case 2: Steep Slope ($|m| > 1$)

Step along $y$ in unit intervals: $\Delta y = 1$. The next x-coordinate is incremented incrementally by the inverse slope:

y_{k+1} = y_k + 1, \quad x_{k+1} = x_k + \frac{1}{m}

The plotted pixel is $(\text{round}(x_{k+1}), y_{k+1})$.

Weakness of DDA: Although DDA eliminates multiplication, it still relies on floating-point arithmetic and explicit rounding functions (round() or floor()) at every single step. In hardware graphics pipelines, floating-point roundoff errors accumulate over long lines, causing the line trajectory to drift away from the true mathematical path.

3. Bresenham's Integer Line Algorithm

In 1962, Jack Elton Bresenham developed an optimal scan-conversion algorithm that utilizes pure integer addition, subtraction, and bitwise arithmetic—completely eliminating floating-point math and division.

Consider a line in the first octant where $0 \le m \le 1$ with $x_0 < x_1$. At step $k$, having plotted $(x_k, y_k)$, the next candidate pixel must be either:

  • East (E): $(x_k + 1, y_k)$
  • North-East (NE): $(x_k + 1, y_k + 1)$

The true mathematical line at $x = x_k + 1$ has vertical coordinate $y = m(x_k + 1) + c$. The vertical distances from the true line to the lower candidate pixel ($d_1$) and upper candidate pixel ($d_2$) are:

d_1 = y - y_k = m(x_k + 1) + c - y_k
d_2 = (y_k + 1) - y = y_k + 1 - [m(x_k + 1) + c]
d_1 - d_2 = 2m(x_k + 1) - 2y_k + 2c - 1

Substituting $m = \Delta y / \Delta x$ and multiplying throughout by $\Delta x$ (which is strictly positive) produces the integer decision parameter $P_k$:

P_k = \Delta x (d_1 - d_2) = 2 \Delta y \cdot x_k - 2 \Delta x \cdot y_k + C

Initial Parameter & Incremental Recurrence

Evaluating at the origin endpoint $(x_0, y_0)$ yields the initial decision parameter $P_0$:

P_0 = 2 \Delta y - \Delta x

At each subsequent step $k$, the next parameter $P_{k+1}$ is computed incrementally from $P_k$:

  • If $P_k < 0$: The true line is closer to pixel $E$ $(x_k + 1, y_k)$. Plot $(x_k + 1, y_k)$, and update:
    P_{k+1} = P_k + 2 \Delta y
  • If $P_k \ge 0$: The true line is closer to pixel $NE$ $(x_k + 1, y_k + 1)$. Plot $(x_k + 1, y_k + 1)$, and update:
    P_{k+1} = P_k + 2 \Delta y - 2 \Delta x

4. C++ Reference Implementation

text
123456789101112131415161718192021
void drawLineBresenham(int x0, int y0, int x1, int y1) {
    int dx = std::abs(x1 - x0);
    int dy = std::abs(y1 - y0);
    int sx = (x0 < x1) ? 1 : -1;
    int sy = (y0 < y1) ? 1 : -1;
    int err = dx - dy;

    while (true) {
        setPixel(x0, y0);
        if (x0 == x1 && y0 == y1) break;
        int e2 = 2 * err;
        if (e2 > -dy) {
            err -= dy;
            x0 += sx;
        }
        if (e2 < dx) {
            err += dx;
            y0 += sy;
        }
    }
}

5. Performance & Hardware Efficiency Comparison

MetricDirect Equation ($y = mx + c$)DDA AlgorithmBresenham's Algorithm
Arithmetic OperationsFloat multiplication & additionFloat addition & roundingInteger addition, subtraction, bit-shift ($2x$)
Accumulative ErrorNone (calculated from scratch)Drifts due to floating-point truncationZero error drift; exact integer precision
Hardware ComplexityHigh (FPU multiplier required)Moderate (FPU adder required)Extremely low (pure ALU adder/shifter)
Share:
Share on X
Share on LinkedIn
Share on Facebook
Share on Reddit
Share on WhatsApp
Share on Telegram
Copy link

Related reading

Line Drawing Algorithms: DDA & Bresenham | Draftsbook · Draftsbook