Three advantages of integer arithmetic for raster graphics are:
- Cheap, fast operations. Historically, integer addition, subtraction and shifts needed much less hardware and execution time than floating-point arithmetic, especially on machines without a floating-point unit. An incremental Bresenham's line algorithm needs only a few additions and a decision per pixel.
- Exact decisions. Provided integer overflow is excluded, the scaled midpoint line decision is exact. There is no accumulated rounding error that can move a decision across a half-pixel boundary; equality has a reproducible tie rule.
- Simple storage and hardware. Integer coordinates already identify pixels. An implementation can keep coordinates and decision variables in ordinary registers and use a small add/compare datapath, avoiding conversion between floating-point numbers and integer screen addresses.
These are historical and structural advantages, not a claim that every modern processor executes every integer operation faster. An integer implementation still needs sufficient width for its intermediate results. The compact answer is
By exchanging axes, reversing endpoint order and reflecting coordinate signs where necessary, reduce a general line segment to the first octant:The vertical case is handled by exchanging axes. In this octant, increasing by one requires increasing by either zero or one. Thus, from the currently plotted pixel the candidates are and .
Use the implicit equation of the lineAt a fixed , means that lies below the exact line. The midpoint line decision evaluates , halfway between the two candidate pixel centres. If , the exact line lies below , so choose ; if , choose . At equality either candidate is equally near, but a fixed tie rule is essential. We choose on a tie throughout these solutions:This chooses the closest vertical-grid pixel centre in each column, with ties rounded upward. Since , the result has one pixel per column and consecutive pixels share an edge or a corner.
Multiply the midpoint line decision by two to remove the fraction. At the current pixel , maintainAt the initial endpoint this is . If is chosen, the next decision midpoint is displaced by and increases by . If is chosen, its displacement is and increases by . Both increments are constant, so the per-pixel work uses only integer arithmetic:The completed code, using the tie rule of part (b), is:
void midpointLine(int x0, int y0, int x1, int y1)
{
int dx, dy, incrE, incrNE, d, x, y;
x = x0; y = y0;
dx = x1 - x0;
dy = y1 - y0;
incrE = 2 * dy;
incrNE = 2 * (dy - dx);
d = 2 * dy - dx;
drawPoint(x, y);
while (x < x1) {
if (d < 0) {
d += incrE;
} else {
d += incrNE;
y++;
}
x++;
drawPoint(x, y);
}
return;
}Thus
guard1 is x < x1, and guard2 is d < 0. Multiplication by two is the only multiplication. Signed decision variables are convenient because and incrNE can be negative; this remains an integer arithmetic algorithm. A strictly unsigned hardware representation would need an equivalent biased or separated-sign encoding. As with the printed int skeleton, assume all intermediate values fit the chosen type; integer overflow would invalidate the mathematical decisions.To verify the geometry, write . The chosen ordinate isThe midpoint line decision selects exactly this nearest integer, rounding halves upward. Its increment between successive columns is zero or one. At and , it gives exactly and , respectively, so both endpoints are included and the line segment has precisely distinct pixels.
For the illustrated endpoints and , the ordinates are . In particular the exact ordinate at is , and the chosen pixel is .
The verifier can check the final geometric criterion directly, independently of the incremental decision variable. Set , , and define the scaled vertical residualThe exact line ordinate is , so . Nearest-integer selection with upward ties is preciselyThe strictness matters: at a half-integer ordinate the upper pixel has and passes, whereas the lower pixel has and fails. Each column has exactly one accepted integer ordinate.
With
reject() terminating verification unsuccessfully, suitable outline code is:void checkPoint(int x, int y)
{
Wide a = Wide(x) - x0;
if (a < 0) reject(); // inequality 1
Wide b = Wide(x1) - x;
if (b < 0) reject(); // inequality 2
Wide dx = Wide(x1) - x0;
Wide dy = Wide(y1) - y0;
Wide e = 2 * dy * a - 2 * dx * (Wide(y) - y0);
Wide lower = e + dx;
if (lower < 0) reject(); // inequality 3
Wide upper = dx - e;
if (upper <= 0) reject(); // inequality 4
counter[x]++;
}Wide denotes a signed integer type large enough for the products and differences, with conversion before subtraction. These are exactly four inequalities against zero, all applied to named integer variables. The arithmetic restriction on the drawing loop in part (c) does not restrict multiplication in this verifier. The screen endpoints are assumed valid, with and valid endpoint ordinates, so indexing is safe after the first two checks. These endpoint and screen preconditions belong in initialization if they are not guaranteed by the caller.No separate -range tests are needed: for between the endpoints, lies in , and its nearest integer lies in the same interval because both bounds are integers. The counters defer detection of omissions and repetitions to part (e). As for every finite counter, use adequate capacity or a sticky failure on overflow; saturating each counter at two also suffices because only zero, one, and “more than one” matter.
After every proposed pixel has passed part (d), insist on exactly one call in every column of the closed endpoint interval:
void final()
{
for (int x = x0; x <= x1; x++) {
if (counter[x] != 1) reject();
}
accept();
}Part (d) already rejected every out-of-range column and every incorrect ordinate. A zero counter now detects an omitted column; a counter greater than one detects a repeated call in that column. Because the residual interval in part (d) allows exactly one integer ordinate in each column, accepted calls in a repeated column must address the same pixel. Conversely, a counter of one in every column forces the complete set of nearest pixels, including both endpoints. Consecutive correct columns differ in ordinate by at most one, which proves that there are no gaps in the resulting thin line segment.
Articles by others on the same topic
There are currently no matching articles.
