Thus by performing one addition, we can incrementally compute the value of y for each value of x. Note that we need real valued arithmetic as m is a rational number. To compute the pixel number we need to turn on, we just round the value y + m.
Let us start with the implicit form of the line equation: F(x,y) = Ax + By + C = 0. For consistency, assume A > 0 (if A < 0, negate all coefficients).
Suppose we the current pixel on the line = (xp, yp). We next need to choose between pixels (xp+1, yp) and (xp+1, yp+1). In order to do that, we need to test the sign of dp = F(xp+1, yp+0.5). We call d the decision variable. (It is F evaluated at the mid-point of the two pixels).
If dp > 0, we must choose the upper pixel otherwise we choose the lower pixel. Note that to compute dp, as described, we need real valued arithmetic. We can eliminate all real arithmetic by resorting to incremental computation.
Assume we know dp. We can then compute dp+1 as follows:
Case I:
We choose (xp+1, yp) at the current step.
Thus, if B is an even number, d1 is an integer. If B is an odd number, all we need to do is multiply all coefficients of the equation of the line by 2 (and go through the math again). This leaves the line unchanged: 2Ax + 2By + 2C = 0.
For example, if the first pixel is (xp, yp), the decision variable d1 is: A(xp+1) + B(yp+0.5) + C. This is not equal to B/2 any more, but it still is an integer:
Assume xp = x1 + ix and
yp = y1 + iy .
(ix and iy are integers.)
Now, d1 = A(x1+ix+1) +
B(y1+iy+0.5) + C.
That is an integer (why?).
If the line extends beyond a horizontal boundary, the problem is more acute. Suppose the line intersects the lower boundary of the window. Check to see what happens for lines with slope close to zero, if we start at the rounded value of the intersection point. A number of pixels that are closer to the boundary than the scan-line beyond it do not get drawn. To account for this short-sightedness (no pun intended), we find the intersection with the line corresponding to half a pixel lower than the actual boundary. Now, if we round of this intersection, we start at exactly the pixel that we would have started at if the window was not truncated below this boundary.
Remember that it is not wise to change the order of drawing to, say, an always increasing primary axis. This can result in "patterned" poly-lines looking wrong.
Again, with a little manipulation we can get away with integer arithmetic. We break 1/m into an integer part i and a fractional part r. Remember, we need to keep adding 1/m to the current value of x. This can be done by adding i each time and updating r = N/D, N < D. We need to add N/D, 2N/D, 3N/D, and so on. We keep adding N to the numerator until it exceeds D, each time adding i to x. Once the numerator exceeds D, we add 1 more to x, and subtract 1 from the fractional part, which is achieved by subtracting D from numerator.
Remember, we must set only pixels lying in the interior of the polygon. Hence on the left edges of the span, we round up, and on the right edges of a span we round down. If the point of intersection lies exactly on a pixel, using our length convention, on the lower end, we include the pixel, and on the upper end we exclude the pixel from being drawn.
Step 2
We use coherence in sorting again. If no new edges start at the new scan-line (i.e.,
no vertices lie at the scan line) the sorted order remains the same (remember, we are
assuming no self-intersections). If a new vertex does start, we can easily insert it
in the current list of sorted intersections, by using insertion sort.
The intersection list can easily be managed by starting with a y sorted list of edges (usually a bucket sort) and maintaining the currently active list of intersections. Once we reach a scan line at which an edge starts (by looking at the bucket corresponding to the current scan line), we insert it into the active list.
Step 3
We need to consider the special case of when a vertex of the polygon lies on the
scan line. For closed polygons, such vertices would normally be repeated as they
lie on two edges. Always counting them twice (or even once) for the odd-even parity
results in inconsistencies. However, using the following rule eliminates any such
problems: