The short answer

Overall, DDA vs Bresenham comes down to one thing: how each finds the next pixel. DDA uses floating-point maths, while Bresenham uses only integers. DDA computes an increment, then adds it and rounds at every step. Instead, Bresenham tracks a decision parameter and adds or subtracts small integers each step. Because Bresenham avoids division, rounding, and floating-point addition, it runs faster and never drifts off the true line. DDA is simpler to learn, so many courses teach it first. In practice, though, graphics libraries use Bresenham, or a close variant of it, for real pixel work.

Every line on a screen is really a row of pixels, since a screen has no room for perfectly smooth diagonals. So an algorithm must decide, pixel by pixel, which squares to light up. Indeed, DDA and Bresenham are the two classic answers to that problem.

GATE papers love this comparison, since examiners ask for the decision parameter, the pseudocode, or a worked line by hand. This guide walks through both algorithms in full. It also works one example line through each method, step by step, so you can check your own hand calculations against it.

Line drawing sits inside a bigger graphics pipeline. Clipping runs first, trimming lines to the visible window; read more on windowing and clipping in computer graphics for that earlier stage. When a line survives clipping, scan conversion turns it into pixels. That is exactly where DDA and Bresenham do their work.

Pixel grid diagram showing an ideal diagonal line crossing a raster with the nearest grid squares shaded as lit pixels
A mathematical line becomes a set of lit pixels once it meets the pixel grid.

What Line Drawing Actually Does

A mathematical line is continuous, since it has infinite points between its two ends. A screen, however, is a grid of discrete pixels. So nothing continuous survives contact with that grid unchanged.

Scan conversion is the process that bridges the two. It takes a line’s equation and picks the pixels that best approximate it. Every pixel sits at an integer coordinate. So the algorithm must round each computed point to its nearest integer position.

Rounding is unavoidable because a line’s true path rarely lands exactly on a pixel centre. Except at special slopes, such as exactly horizontal, vertical, or 45 degrees, the ideal line keeps crossing between pixels. Each algorithm must therefore choose the nearest pixel at every step. In short, that single choice, repeated many times, is the whole problem line drawing solves.

DDA and Bresenham both solve it. They just reach the same rounded pixel through very different arithmetic, as the worked example further down shows.

The DDA Algorithm

DDA stands for Digital Differential Analyzer. It is an incremental algorithm, so it builds the line one small step at a time. At each step, it adds a fixed increment to the previous point.

The steps are straightforward:

  1. Compute dx = x2 − x1 and dy = y2 − y1.
  2. Take steps = max(|dx|, |dy|), the larger of the two spans.
  3. Compute the increments: xIncrement = dx / steps and yIncrement = dy / steps.
  4. Start at (x1, y1). Add the increments after every step.
  5. Round each accumulated coordinate to the nearest integer. That rounded pair is the pixel to plot.

Here is the pseudocode:

dx = x2 - x1
dy = y2 - y1
steps = max(abs(dx), abs(dy))
xInc = dx / steps
yInc = dy / steps
x, y = x1, y1
plot(round(x), round(y))
for i in range(steps):
    x = x + xInc
    y = y + yInc
    plot(round(x), round(y))

Advantages of DDA:

  • Simple to understand and to code, so it is often taught first.
  • Works for any slope, since it always steps along the larger span.
  • Needs only a handful of variables to track state.

Disadvantages of DDA:

  • Needs floating-point arithmetic. It divides just to compute the increments.
  • Rounds at every step, so small errors keep entering the calculation.
  • Round-off error accumulates over long lines, and the pixel path can drift.
  • Floating-point addition and rounding run slower than plain integer operations.

For the broader idea of writing steps like these before you code them, see the difference between an algorithm and a flowchart.

Bresenham’s Line Algorithm

Bresenham’s algorithm answers the same question with only integers. Instead of a floating-point coordinate, it tracks a decision parameter. In fact, that parameter’s sign alone tells it which pixel comes next.

This walkthrough assumes a slope between 0 and 1, so dx is positive and larger than dy. For steeper lines, swap the roles of x and y, and step along y instead.

  1. Compute dx and dy, as before.
  2. Compute the initial decision parameter: p0 = 2·dy − dx.
  3. At each step, move x forward by one.
  4. If pk < 0, the next pixel is (xk+1, yk). Update pk+1 = pk + 2·dy.
  5. If pk ≥ 0, the next pixel is (xk+1, yk+1). Update pk+1 = pk + 2·dy − 2·dx.
  6. Repeat until x reaches x2.

Here is the pseudocode:

dx = x2 - x1
dy = y2 - y1
p = 2 * dy - dx
x, y = x1, y1
plot(x, y)
for i in range(dx):
    x = x + 1
    if p < 0:
        p = p + 2 * dy
    else:
        y = y + 1
        p = p + 2 * dy - 2 * dx
    plot(x, y)

Advantages of Bresenham’s algorithm:

  • Uses only integer addition, subtraction, and a multiply by two, which is a bit shift.
  • Needs no division and no rounding anywhere in the loop.
  • Always picks the pixel closest to the true line, so accuracy stays high.
  • Extends naturally to the midpoint circle algorithm.
  • Maps well onto graphics hardware, since integer operations are cheap there.

Disadvantages of Bresenham’s algorithm:

  • Needs a separate case for steep slopes, where x and y swap roles.
  • Reads less intuitively than DDA at first, since the decision parameter takes some getting used to.
  • Handles straight lines and circles, but free-form curves need different algorithms, such as Bezier or spline methods.

DDA vs Bresenham: Comparison Table

Infographic comparing DDA and Bresenham on maths float versus integer, speed slower versus faster, error grows versus none, and loop add plus round versus add or subtract
DDA vs Bresenham at a glance: maths, speed, error, and the inner loop.
AspectDDABresenham
Arithmetic typeFloating-pointInteger only
Operations in the inner loopAdd, then roundAdd or subtract, then compare
Division requiredYes, to compute the incrementsNo
Rounding requiredYes, at every stepNo
SpeedSlower, due to floating-point workFaster, integer work only
Accumulated error on long linesGrows, from repeated roundingNone; steps stay exact integers
Accuracy of pixel choiceApproximate, rounded each stepAlways the nearest pixel to the line
Decision variableNone; uses raw coordinates directlyDecision parameter p, updated each step
Implementation difficultyEasier to learn and derive firstSlightly harder to follow at first
Hardware suitabilityPoor fit for simple integer ALUsStrong fit; maps onto shift-and-add logic
Extension to circlesNot the standard base for circlesExtends directly to the midpoint circle algorithm
Memory and register useNeeds floating-point registersNeeds only integer registers
Precision on long linesDegrades as line length growsStays exact, regardless of length
Use in modern graphics librariesRare in production rasterisersCommon; still underpins many rasterisers

Worked Example: The Same Line, Both Ways

Diagram of one pixel grid step showing the upper pixel and lower pixel candidates around the true line with the decision parameter p marked
At every step, Bresenham’s decision parameter p picks the upper pixel or the lower pixel.

Take the line from (2, 3) to (10, 8). Here dx = 8 and dy = 5, so the slope m = 0.625. Both algorithms plot the same starting pixel, (2, 3), before their loops even begin.

DDA: steps = 8, xIncrement = 1, and yIncrement = 0.625. The table below shows y accumulating, then rounding to a pixel at each step.

Step kxy (accumulated)Rounded pixel
023.000(2, 3)
133.625(3, 4)
244.250(4, 4)
354.875(5, 5)
465.500(6, 6)
576.125(7, 6)
686.750(8, 7)
797.375(9, 7)
8108.000(10, 8)

Bresenham: p0 = 2(5) − 8 = 2. From here, only integer addition and subtraction decide each pixel.

Step kpkDecisionPixel plottedpk+1
02pk ≥ 0(3, 4)−4
1−4pk < 0(4, 4)6
26pk ≥ 0(5, 5)0
30pk ≥ 0(6, 6)−6
4−6pk < 0(7, 6)4
54pk ≥ 0(8, 7)−2
6−2pk < 0(9, 7)8
78pk ≥ 0(10, 8)2

Look closely at the final pixel lists. Both give (2,3), (3,4), (4,4), (5,5), (6,6), (7,6), (8,7), (9,7), (10,8), the same nine pixels either way. However, DDA needed floating-point addition and a rounding step at every point. In contrast, Bresenham needed only integer addition and subtraction. That one contrast is the entire argument between them.

Why Integer Arithmetic Wins

Processors handle integers faster than floating-point numbers, especially on simple or embedded hardware. Integer addition, subtraction, and bit shifts are cheap. Floating-point division and rounding cost more, both in time and in circuitry.

Bresenham’s inner loop needs only a compare, an add, and occasionally a subtract. Multiplying by two is just a left shift, not real multiplication. So every step of the loop maps directly onto basic integer hardware. This matters even for how a display refreshes; see how horizontal retrace and vertical retrace work if you want the full picture of how pixels reach the screen.

DDA’s inner loop, in contrast, needs a floating-point add and a round at every step. Rounding is not free, since it usually means a conversion step between floating-point and integer formats. Multiply that small cost by millions of pixels, and the gap becomes real.

Both algorithms are still O(n) in the number of pixels plotted, so their growth rate is identical; see our guide on time complexity if that idea needs a refresher. Even so, Bresenham simply carries a much smaller constant factor per step. Overall, that smaller constant, multiplied across an entire frame, is why it wins in practice.

Code Example

Below is a working Python version of both algorithms. Each returns the full list of plotted pixels, so you can run it and check the output against the worked example above.

def dda_line(x1, y1, x2, y2):
    dx = x2 - x1
    dy = y2 - y1
    steps = max(abs(dx), abs(dy))
    x_inc = dx / steps
    y_inc = dy / steps
    x, y = x1, y1
    pixels = [(round(x), round(y))]
    for _ in range(steps):
        x += x_inc
        y += y_inc
        pixels.append((round(x), round(y)))
    return pixels


def bresenham_line(x1, y1, x2, y2):
    dx = x2 - x1
    dy = y2 - y1
    p = 2 * dy - dx
    x, y = x1, y1
    pixels = [(x, y)]
    for _ in range(dx):
        x += 1
        if p < 0:
            p += 2 * dy
        else:
            y += 1
            p += 2 * dy - 2 * dx
        pixels.append((x, y))
    return pixels


print("DDA:", dda_line(2, 3, 10, 8))
print("Bresenham:", bresenham_line(2, 3, 10, 8))

# DDA: [(2, 3), (3, 4), (4, 4), (5, 5), (6, 6), (7, 6), (8, 7), (9, 7), (10, 8)]
# Bresenham: [(2, 3), (3, 4), (4, 4), (5, 5), (6, 6), (7, 6), (8, 7), (9, 7), (10, 8)]

Run this, and both functions return the same list of nine pixels. Notice that dda_line divides and calls round() at every step. Meanwhile, bresenham_line only ever adds, subtracts, and compares. Overall, that difference in the source code is the whole lesson in one glance.

When to Use Which

Use DDA when you are learning scan conversion for the first time, since its floating-point steps make the underlying idea easy to see. It also works fine for short lines or one-off tools, where speed barely matters.

Use Bresenham for anything resembling production graphics work. Rasterisers, low-level drivers, embedded displays, and plotting hardware all favour it, since integer speed and exact pixels matter there. Once pixels are chosen, they still need mapping into the final display region; see viewport vs window in computer graphics for how that mapping works. Overall, reach for Bresenham whenever performance or precision genuinely counts.

Interview Questions

DDA computes xIncrement and yIncrement by dividing dx and dy by the step count. Those increments are rarely whole numbers, so every added coordinate needs rounding. Bresenham avoids this entirely. It tracks a decision parameter built from integer values alone, updated only by addition, subtraction, and a shift. So its loop never touches a fractional value.

The decision parameter, p, tracks how far the true line sits from the midpoint between two candidate pixels. When p is negative, the line sits closer to the lower pixel, so the algorithm keeps y the same. When p is zero or positive, the line has drifted closer to the upper pixel, so y increases by one. Only the sign of p, never its exact value, drives the choice.

DDA adds a floating-point increment at every step, then rounds the result. Each rounding step introduces a tiny error, and those errors can drift in the same direction over a long line. Bresenham never rounds at all. Its decision parameter stays an exact integer through every update, so there is no fractional error left to accumulate.

The standard derivation assumes dx is larger than dy, so the algorithm steps one pixel in x on every iteration. When the slope exceeds 1, dy is larger instead, so the roles of x and y simply swap. The algorithm now steps one pixel in y each time and uses the decision parameter to choose between the left and right candidate pixels.

Frequently Asked Questions

No, it is the other way round. DDA needs a division upfront and a rounding step at every point in its loop, since it works in floating point. Bresenham needs only integer addition and subtraction. Because integer operations run faster than floating-point ones on almost any hardware, Bresenham is the quicker algorithm in practice.

Yes. Bresenham’s decision parameter always chooses the pixel closest to the true line at every single step. DDA also rounds toward the nearest pixel, but its floating-point error can build up over a long line, so its path can drift further from the ideal line than Bresenham’s does.

No, that is a common mix-up. DDA is fully incremental. It adds a fixed xIncrement and yIncrement to the previous point at every step, rather than recomputing the line from scratch. Bresenham is incremental too, since it updates its decision parameter from the previous one. Both algorithms build the line step by step.

Not in the meaningful sense. Its loop uses only addition, subtraction, and a multiply by two, which any processor implements as a cheap left shift rather than true multiplication. There is no division anywhere in the loop. That is exactly why the algorithm suits simple integer hardware so well.

Not on its own, but its logic extends directly to one. The midpoint circle algorithm applies the same decision-parameter idea to a circular arc instead of a straight line. Both rely on comparing an integer decision value against zero to pick the next pixel, so the core trick carries over almost unchanged.

Most production rasterisers favour Bresenham, or a close integer variant of it, since speed and pixel-exact output both matter at scale. DDA still shows up in textbooks and teaching code, because its floating-point steps are easier to follow. In short, DDA teaches the idea well, while Bresenham does the real work.

Wrapping Up

DDA and Bresenham both turn a mathematical line into a set of lit pixels. DDA does it with floating-point increments and a rounding step at every point. Meanwhile, Bresenham does it with an integer decision parameter, updated by addition and subtraction alone.

Remember the essentials for your exam. Both are incremental, though only DDA rounds inside its loop. Bresenham always picks the nearest pixel and never accumulates round-off error, so it wins on speed and on precision alike. When it is time to write real graphics code, Bresenham is almost always the right default.

Related reading on DiffStudy:


Whatsapp-color Created with Sketch.

By Arun Kumar

Full Stack Developer with a BE in Computer Science, working with React, Next.js, Node.js, MongoDB, and AI/ML tools. Founder of DiffStudy — built to help CS students ace GATE and university exams, and keep developers up to date across AI, cloud, system design, web development, and every field of computer science. Every article is written from real hands-on experience, not just theory.

Leave a Reply

Your email address will not be published. Required fields are marked *


You cannot copy content of this page