I'm looking for an algorithm (coded in Java would be nice, but anything clear enough to translate to Java is fine) to draw a 4-connected line. It seems that Bresenham's algorithm is the most widely used, but all the understandable implementations I've found are 8-connected. OpenCV's cvline function apparently has a 4-connected version, but the source code is, to me, as a mediocre and nearly C-illiterate programmer, impenetrable. Various other searches have turned up nothing.
Thanks for any help anyone can provide.
For the Python-illiterate, here is a C version of 6502's code:
The following is a Bresenham-like algorithm that draws 4-connected lines. The code is in Python but I suppose can be understood easily even if you don't know the language.
The idea is that to draw a line you should increment X and Y with a ratio that matches DX/DY of the theoretic line. To do this I start with an error variable
e
initialized to 0 (we're on the line) and at each step I check if the error is lower if I only increment X or if I only increment Y (Bresenham check is to choose between changing only X or both X and Y).The naive version for doing this check would be adding
1/dy
or1/dx
, but multiplying all increments bydx*dy
allows using only integer values and that improves both speed and accuracy and also avoids the need of special cases fordx==0
ordy==0
thus simplifying the logic. Of course since we're looking for a proportion error, using a scaled increment doesn't affect the result.Whatever is the line quadrant the two possibilities for the increment will always have a different sign effect on the error... so my arbitrary choice was to increment the error for an X step and decrement the error for an Y step.
The
ix
andiy
variables are the real directions needed for the line (either +1 or -1) depending on whether the initial coordinates are lower or higher than the final coordinates.The number of pixels to draw in a 4-connected line is obviously
dx+dy
, so I just do a loop for that many times to draw the line instead of checking if I got to the end point. Note that this algorithm draws all pixels except the last one; if you want also that final pixel then an extradraw_pixel
call should be added after the end of the loop.An example result of the above implementation can be seen in the following picture