A generalized midpoint algorithm for drawing line segments

Back to 2d drawing

Abstract

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.

Problem

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 .

Solution

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\

Two possibilities for the next move

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.

Choosing the next move to keep close to the line

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.

Packing the comparison into a decision variable

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.

Computing the decision variable incrementally

We now notice:

If option 1 is chosen, then

Similarly, if option 2 is chosen, then

Thus the values for can be computed incrementally.

Computing the initial value of the decision variable

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.

Other octants

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 :

Summary

Octant 0:

Octant 1 (reflected octant 0):

Octant 3

Octant 6 (reflected octant 3)

Octant 4

Octant 5 (reflected octant 4)

Octant 7

Octant 2 (reflected octant 7)