I created a C# implementation of Bresenham’s line drawing algorithm in Visual Studio. You can view/download the source code from my github.
Given two integer endpoint coordinates, Bresenham’s line drawing algorithm determines what other integer coordinates best approximate the ideal line segment that they define.
Here is the (modified) pseudocode from Wikipedia:
plotLine(x0,y0, x1,y1) dx = x1 - x0 dy = y1 - y0 D = 2*dy - dx y = y0 for x from x0 to x1 plot(x,y) if D > 0 y = y + 1 D = D - 2*dx end if D = D + 2*dy
Remarkably, this algorithm uses only integer arithmetic. Earlier computers motivated this property because non whole number operations, like division, were then relatively slow to compute.
The algorithm encodes the following intuitive logic:
- Provided I am currently on a pixel that best approximates the ideal line, I should proceed to the adjacent pixel that also best approximates the ideal line. That pixel is either straight ahead, or diagonal from the current pixel.
- By repeating this logic I can always begin at one endpoint and, selecting the pixel that best approximates the ideal line at each step, arrive at the other endpoint.
- Since the pixels that best approximate the ideal line are always selected at each step, the entire line approximates the ideal line segment as best as possible.
But from looking at the code, that’s not at all apparent. So why does Bresenham’s line drawing algorithm work?
Endpoints, and define the ideal line:
Denote the current coordinate:
To measure , the error in proceeding from the current coordinate the diagonal coordinate, and , the error in proceeding instead to the adjacent coordinate:
If the error in proceeding to the diagonal coordinate is less than the error in proceeding to the adjacent coordinate, then I should proceed to the diagonal coordinate, otherwise I should proceed to the adjacent coordinate.
If I instead take the difference of the two errors,
I can follow the equivalent logic:
Since the slope of the line, m, is a rational number, the decision still can not be made using just integer arithmetic.
But I can multiply the equality by
and now follow the equivalent, integer arithmetic only logic:
I’ll give this expression a name:
But rather than making all these calculations at every iteration of the algorithm, observe that the difference between successive terms is
Then I only have to track changes to this quantity at each iteration. This requires fewer calculations. Since at every iteration, the x-coordinate increases by one, is always one. Since the y-coordinate increases by one only when
So when D is less than zero, add to D and keep the y-coordinate the same. Otherwise, if D is greater than zero, add to D and increase the y-coordinate by one.
Now all that remains is to find the initial value, :
And that’s all there is to it!