How DDA Line Drawing Simulator works
The digital differential analyser draws a line by sampling it at unit intervals along whichever axis it moves fastest on. Start from dx = x₂ − x₁ and dy = y₂ − y₁ and take steps = max(|dx|, |dy|). Dividing both deltas by that count gives the per-step increments xInc and yInc, and one of them is always exactly ±1 — the driving axis — while the other is the fractional slope. From the starting point you then repeatedly add the increments to a pair of floating-point accumulators and round each result to the nearest integer to get a pixel. Because the driving axis advances by a full pixel every step, the line never leaves gaps, and because the other axis creeps along by the true slope, the rounded values track the ideal line closely. The cost is arithmetic: DDA needs floating-point addition and a rounding operation per pixel, which is exactly what Bresenham was invented to remove.
Pseudocode
DDA(x1, y1, x2, y2):
dx = x2 - x1
dy = y2 - y1
// drive along the axis with the larger span, so no gaps appear
steps = max(abs(dx), abs(dy))
if steps == 0:
plot(round(x1), round(y1)); return // degenerate: single point
xInc = dx / steps // one of xInc, yInc is exactly +1 or -1
yInc = dy / steps
x = x1
y = y1
plot(round(x), round(y))
repeat steps times:
x = x + xInc
y = y + yInc
plot(round(x), round(y))Time and space complexity
- Time
- O(max(|dx|, |dy|)) — one iteration per pixel plotted
- Space
- O(1)
The work is linear in the length of the longer axis because exactly one pixel is emitted per step; the per-step cost is two floating-point additions and two roundings.
Worked example
Draw from (2, 3) to (7, 6). dx = 5, dy = 3, so steps = max(5, 3) = 5, xInc = 1.0, yInc = 0.6.
- k = 0x = 2.0, y = 3.0 → plot (2, 3).
- k = 1x = 3.0, y = 3.6 → round → plot (3, 4).
- k = 2x = 4.0, y = 4.2 → round → plot (4, 4).
- k = 3x = 5.0, y = 4.8 → round → plot (5, 5).
- k = 4x = 6.0, y = 5.4 → round → plot (6, 5).
- k = 5x = 7.0, y = 6.0 → plot (7, 6). Endpoint reached.
Six pixels: (2,3), (3,4), (4,4), (5,5), (6,5), (7,6). Note y advances irregularly — 3,4,4,5,5,6 — which is the slope 0.6 showing up in the rounding.
Common exam mistakes
- Using steps = |dx| always. That leaves gaps whenever |dy| > |dx|; the whole point of max() is to drive along the steeper axis.
- Truncating instead of rounding. floor() biases every pixel downward and visibly shifts the line; round() is required.
- Rounding the accumulator itself rather than a copy. Feed the un-rounded x and y forward, or the error compounds and the line bends.
- Forgetting the starting pixel. The loop runs `steps` times but the line has steps + 1 pixels.
- Not handling dx = dy = 0. Both increments become 0/0; guard the degenerate case before dividing.
Frequently asked questions
What is the difference between DDA and Bresenham's line algorithm?
They plot nearly the same pixels but DDA uses floating-point accumulators and rounding, while Bresenham (midpoint) uses an integer decision parameter and only additions. Bresenham is faster and free of floating-point drift, which is why hardware uses it.
Why does DDA use max(|dx|, |dy|) as the step count?
So the faster-changing axis moves exactly one pixel per iteration. If you stepped along the slower axis, the faster one would jump by more than a pixel each time and the line would come out dotted.
Is DDA accurate for steep lines?
Yes — for |dy| > |dx| the roles simply swap, y becomes the driving axis with yInc = ±1 and xInc holds the reciprocal slope. The algorithm is symmetric.
Why is DDA considered slow?
Every pixel costs a floating-point add and a round on both axes. On long lines the accumulated floating-point error can also drift, so integer methods are preferred in practice.
Related simulators
Midpoint Line Drawing Simulator
Convert to zone zero, track the decision parameter and plot pixel by pixel.
Cohen-Sutherland Clipping
Compute outcodes region by region and clip the line against each window boundary.
Cyrus-Beck Clipping
Use boundary normals and t values to classify each intersection as entering or leaving.
2D & 3D Transformations
Chain translation, scaling, rotation and shear, and read off the composite matrix.