Here we derive a generalized midpoint algorithm for drawing line segments. This generalized version works with floating point end-points instead of integer end-points.
In the following the norm is assumed to be the maximum norm and stands for unique existence. Given two points , the problem is to generate a sequence such that:
I.e. informally the problem is to draw a set of pixels such that they form an 8-connected one-pixel wide line segment from to .
We take the sampling point of a pixel to be at . For example if , then the sampling point of the pixel is at .
Let
The algorithm separates into cases based on which octant the end-point is with respect to the start point. The octants are numbered as:
\2|1/
3\|/0
--+--
4/|\7
/5|6\
Assume . This takes care of octants 0, 3, 4 and 7. We will deal with the other octants later.
We start tracing from the pixel that has the sampling point closest to .
From here, we perform either of the two steps:
where .
We choose the one that will keep us closer to the line. This simple procedure is repeated to trace the whole line segment.
The distance of a pixel to the line is measured as the distance of its sampling point to the line. Thus the comparison to select between the two cases is:
If this comparison yields true, the option 1 is chosen. Otherwise option 2 is chosen. However, directly applying a distance algorithm here is expensive. Rather, let
Then traces out points from the line with horizontally at the sampling points. Because of similar triangles, we can equivalently compare the distances of the sampling points to the line along the y-axis:
This is much faster, but the absolute values still block the way to an efficient implementation. Fortunately, we can use an alternative comparison that keeps us equivalently close to the line. Rather than comparing the distances of the two candidate points to the line segment, we can compare the position of their midpoint to the line segment along the y-axis:
This is almost the same inequality as above but with absolute values removed.
Rather than comparing directly , we can compare the sign of the difference :
If , then we choose the option that increases . Otherwise we choose the option that decreases . Because is positive, and thus does not change the sign of , we can as well multiply by to avoid division.
We now notice:
If option 1 is chosen, then
Similarly, if option 2 is chosen, then
Thus the values for can be computed incrementally.
However, must be computed directly:
Notice that if and (the start point is at a sample point), then
If in addition is at a sample point, then the whole algorithm runs on integer arithmetic. This is the traditional midpoint algorithm.
The octants 1, 2, 5, and 6 with can be derived by simply exchanging and in all formulas. This has the effect of reflecting the plane w.r.t the line . Thus the , and can be obtained from the following reflection pairs by exchanging and :
Octant 1 <-> Octant 0
Octant 2 <-> Octant 7
Octant 5 <-> Octant 4
Octant 6 <-> Octant 3