Bresenham's line drawing algorithm is well known and quite simple to implement.
While there are more advanced ways to draw anti-ailesed lines, Im interested in writing a function which draws a single pixel width non anti-aliased line, based on floating point coordinates.
This means while the first and last pixels will remain the same, the pixels drawn between them will have a bias based on the sub-pixel position of both end-points.
In principle this shouldn't be all that complicated, since I assume its possible to use the sub-pixel offsets to calculate an initial error value to use when plotting the line, and all other parts of the algorithm remain the same.
No sub pixel offset:
X###
###X
Assuming the right hand point has a sub-pixel position close to the top, the line could look like this:
With sub pixel offset for example:
X######
X
Is there a tried & true method of drawing a line that takes sub-pixel coordinates into account?
Note:
- This seems like a common operation, I've seen OpenGL drivers take this into account for example - using
GL_LINE, though from a quick search I didn't find any answers online - maybe used wrong search terms? - At a glance this question looks like it might be a duplicate of:
Precise subpixel line drawing algorithm (rasterization algorithm)
However that is asking about drawing a wide line, this is asking about offsetting a single pixel line. - If there isn't some standard method, I'll try write this up to post as an answer.










Let's assume you want to draw a line from
P1 = (x1, y1)toP2 = (x2, y2)where all the numbers are floating point pixel coordinates.Calculate the true pixel coordinates of
P1andP2and paint them:P* = (round(x), round(y)).If
abs(x1* - x2*) <= 1 && abs(y1* - y2*) <= 1then you are finished.Decide whether it is a horizontal (true) or a vertical line (false):
abs(x1 - x2) >= abs(y1 - y2).If it is a horizontal line and
x1 > x2or if it is a vertical line andy1 > y2: swapP1withP2(and alsoP1*withP2*).If it is a horizontal line you can get the y-coordinates for all the x-coordinates between
x1*andx2*with the following formula:If you have a vertical line you can get the x-coordinates for all the y-coordinates between
y1*andy2*with this formula:Here is a demo you can play around with, you can try different points on line 12.