I am currently using Bresenham\'s algorithm to draw lines but they are (of course) one pixel in thickness. My question is what is the most efficient way to draw lines of arb
I think the best way is to draw a rectangle rather than a line since a line with width is a two dimensional object. Tring to draw a set of parallel lines to avoid overdraw (to reduce write bandwidth) and underdraw (missing pixels) would be quite complex. It's not too hard to calculate the corner points of the rectangle from the start and end point and the width.
So, following a comment below, the process to do this would be:-
Note *: If you're using OpenGL you can also do Step 2 at the same time. Of course, using OpenGL does mean understanding OpenGL (big and complex) and this application may make that a tricky thing to implement at such a late stage in development.
For my embedded thermal printer application, using Bresenham's algorithm, the line was way too thin. I don't have GL or anything fancy. I ended up simply decrementing the Y value and drawing more lines under the first one. Each number of thickness added another line. Very quick to implement and made for the desired results printing from monochrome bitmap to the thermal.
Some simple routes to use:
I was facing the same problem some time ago. Based on this paper, I created a Matlab reference implementation, which I would like to share on GitHub.
For best accuracy, and also good performance for thicker lines especially, you can draw the line as a polygon. Some pseudo code:
draw_line(x1,y1,x2,y2,thickness)
Point p[4];
angle = atan2(y2-y1,x2-x1);
p[0].x = x1 + thickness*cos(angle+PI/2);
p[0].y = y1 + thickness*sin(angle+PI/2);
p[1].x = x1 + thickness*cos(angle-PI/2);
p[1].y = y1 + thickness*sin(angle-PI/2);
p[2].x = x2 + thickness*cos(angle-PI/2);
p[2].y = y2 + thickness*sin(angle-PI/2);
p[3].x = x2 + thickness*cos(angle+PI/2);
p[3].y = y2 + thickness*sin(angle+PI/2);
draw_polygon(p,4)
And optionally a circle could be drawn at each end point.
The easiest way to create a line of almost arbitrary thickness would be to first do a bresenham, then apply as many dilation iterations as you wish. Each dilation pads both sides of your line equally.
EDIT: It is also worth noting that this method has the nice feature of being easily generalizable to 3D, because both Bresenham and dilation are easily generalizable to 3D.
Bresenham → thickness 1:
Dilation mask:
0 1 0
1 1 1
0 1 0
Bresenham + 1 dilation → thickness 2
Bresenham + 2 dilations → thickness 3
etc.