Algorithms
Algorithms
VECTOR GENERATION
The process of "turning on" the pixels for a line segment is called vector generarion. If
we know the endpoints which specify the segment, how do we decide which pixels
Na 2 4 7 8
12 CHAPTER ONE
10
'L 8 9 10
FIGURE 1-7
A pixel.
should have their intensity changed? There are several approaches to this problem. We
shall present two examples here. The first is a general algorithm, while the second is a
more efficient version for the case where the line segment endpoints are integers.
The problenm is to select pixels which lie near to the line segment. We might try
to turn on every pixel through which the line segment passes, but there is a problem
with this approach. It would not be easy to find all such pixels, and since vector gener
ation may be performed often, especially for animated displays or complex images, we
want it to be efficient. Another problem is that the apparent thickness of the line would
change with slope and position. An alternative would be to step along the columns of
pixels, and for each column ask which row is closest to the line. We could then turm on
the pixel in that row and column. We know how to find the row because we can place
the x value corresponding to the column into the line equation, solve for y, and note
which row it is in. This will work for lines with slopes between -I
and 1 (lines which
are closer to being horizontal than vertical). But for the steeply rising
or falling lines,
the method will leave gaps. This failing can be overcome if we divide
the lines into
two classes. For the gentle slopes (-1 < m < 1) there are
more columns than rows.
These are the line segments where the length
of the x component D, = ( Xb- Xa) 1S
longer than the length of the y component D, = ( y, ya ), -
This means that as we step along the columns, we can find the new value of y for the
line by just adding m to the y position at the previous column. So our approach so Tar
is first to find the column at the left end of the line segment and the y value at that
col
um, and then to step through the columns which the line segment crosses, adding m
to the y value each time to get a new y value. The y values will be used to select a
row at each column, and we turn on a pixel at the selected row and column. (See
Figure 1-8.)
The vector generation algorithms (and curve generation algorithms) which step
along the line (or curve) to determine the pixels which should be turned on are some-
times called digital diferetial analyzers DDAs). The name comes from the fact that we
use the same technique as a numerical method for solving differential equations. For a
line segment, we solve the differential equation for a straight line and plot the result in-
stead of printing it.
We shall make one further refinement in our approach. Instead of determining
the full y value of the line segment for each column, we shall only keep track of the
current height above the closest row boundary. At each step, the height increases by m
along with y. We can check the height at each step to see if we have moved into a new
row. If we have entered a new row, then we change the row value used to select pixels
and also subtract 1 from our height so that we will now be measuring height from the
new row boundary. For lines with negative slopes, we could let the height decrease and
check for crossing of a lower row boundary, but instead we use the absolute value of
(C,
FIGURE 1-8
Turn on pixels with centers closest to the line segment.
14 CHArTER ONP
Ya t m(c - Xa
To find the index of the closest row, we round the value of y. Rounding may be done by
adding 0.5 and then using the FLOOR function.
r = FLOOR(y + 0.5) (1.37)
j+1
i+2
FIGURE 1-9
Height of the line above pixel-row boundaries.
GEOMETRY AND LINE GENERATION 15
To find the height of y above the row boundary, we take the difference of y (where thc
line is) and r (the row index). If we then add m to this, we have the height value which
should be checked for the next column and so on. (Sec Figure 1-9.)
We shall now present the full algorithm.
BEGIN
the gentle slope case
M-DY/ DX;
set up of starting point depends on which point is leftmost
IF DX > 0THEN
BEGIN
C-CEILING(XA);
D-YA + M * (C- XA);
F-FLOOR(XB);
END
ELSE
BEGIN
C-CEILING(XB);
D-YB+ M * (C. XB);
F-FLOOR(XA);
END;
R-FLOOR(D + 0.5);
+ M;
H-R- 0DTHEN
M>
IF BEGIN
the positive slope case
- 1;
MI-Mthrough
now step the columns
WHILE C s FDO
16 CHAPTER ONE
BEGIN
in the frame buffer
set the ncarest pixel
INTENSITY;
FRAMEIC. R]-
next column
+ 1:
C-C change
should rowW
THEN
IFH0.5
BEGIN
1;
R-R +
H-H + MI:
END
ELSEH-H + M:
END:
END
ELSE
BEGIN
then negative slope case
M--M:
H--H;
MI-M- l;
WHILE C sFDO
BEGIN
set the nearest pixel in the frame buffer
FRAME[C, R]- INTENSITY;
next column
C-C + l;
should row change
IFH >0.5 THEN
BEGIN
R-R 1;
H-H t MI;
END
ELSE H H + M;
END;
END;
END
ELSE
BEGIN
the sharp slope case
IF DY = 0.0 THEN RETURN;
here the above steps are repeated
with the roles of x and y interchanged
END;
RETURN;
END;
The actual algorithm contains a couple of things which were not brought up in
the above discussion. The determination of the starting values is complicated by not
GHOMETRY AMD LINE GENERATION 17
BRESENHAM'S ALGORITHM
The above algorithm was chosen because it can be revised into a very efficient and
popular form known as Bresenham's algorithm for the special case where the
coordi-
nates of the line segment endpoints are integers. The attractiveness of Bresenham1s
algorithm is that it can be implemented entirely with integer arithmetic. Integer
arith
metic is usually much faster than floating-point arithmetic. Furthermore, Bresenham's
algorithm does not require any multiplication or division. To derive the algorithm, first
consider the effect of integer coordinates on determining the starting point. The start
ing point will just be the endpoint of the line segment. No calculation is needed to
move along the line to a pixel center, because it is already there. This eliminates one
place where the line slope was needed, but we also used the slope to update H. How
can we revise our test for new rows so that it requires only integer arithmetic? To
simplify the discussion, consider just the gentle slope case. The test was
H>0.5 (1.38)
where
H-H+ M
or
H-H + M- 1
2H 1> 0 (1.39)
Notice how the 0.5 fraction is removed. But H still has a fractional part, which arises
from the denominator in M that is added in at each step. To remove it, we multiply by
DX. Assuming we have arranged the endpoints so that DX is positive, the test is then
2DX H-DX > 0
Suppose we define G as
G 2DX H - DX (1.40)
Then how does G change from one column to the next? Solving for H gives
18 CHAPTER ONF
G+ DX (1.42)
2DX
Hnew-Hoiu + M
then DY
Gnew + DX Gold + DX
2DX DX
2DX
ot 2DYY (1.43)
Gpnew-Goid +
we get - (1.44)
Gnew Gold+ 2DY 2DX
can be done entirely with
additions and subtractions and
Calculating G requires only to determine when a row boundary
integers. The trick then is to use the test G>0 endpoints, the initial value-
the line instead of the test H >0.5. For integer
crossed by
value of G is
of H is M., so the initial
G 2DX -
G. If it is positive,
DX = 2DY
- DX
IFG>0THEN
BEGIN
R-R-I
G-INC2;
END
ELSE G-G + INCl
END:
END:
END
ELSE
BEGIN
this is the sharp slope case
here the above steps are repeated
with the roles of x and y interchanged
END:
RETURN:
END:
We have seen how the BRESENHAM algorithm is more efficient than the VEC
GEN algorithm in that it requires only integer addition and subtraction. We might ask
why not always use it? Why not always round line segment endpoints to integers be.
fore vector generation? In fact, many systems will do just that, but note that in round.
ing the line segment endpoint positions, errors are introduced. These errors can be seen
in cases where two overlapping line segments are drawn on the display (as when two
objects are shown side by side). Another example occurs when a new line segment
with a different INTENSITY overlaps an old line segment; we might like to change the
old segment's pixels to the appropriate values for the new segment. If we deal with
exactly the same line equation for both line segments, then the same pixels should be
selected: but if errors in the endpoint positions are introduced, the line equations might
not match. and the new line segment can leave pixels from the old line segment peek
ing out from behind it. Note, however, that even our VECGEN algorithm can have
er
rors introduced in the endpoint position as the result of round-off in the floating point
arithmetic of the machine.
Algorithms for vector generation (such as the ones we've seen) may be im
plemented in hardware where speed is important. This is usually done for displays
which avoid the cost of a large frame buffer memory by letting the vector
generator di-
rectly control the drawing instrument (usually an electron beam in a
cathode ray tube).
Instead of setting the (x. y) element in a frame buffer, the pen (or
electron beam) is
moved to position (x, y), where it illuminates the pixel on the
screen.
ANTIALASING OF LINES
Many displays allow only two pixel states, on or off. For
these displays, lines may
have a jagged or stair-step appearance when they step from
one row or column to tne
next. The lower the resolution, the more apparent the effect. aspect or a
This is one
GLOMIETRY AND LINE OENERATION 21
phenomenon called alusnng. Aliasing produces the defccts which occur when the scene
bein displayed changes laster or more smoothly than every
two pixels. Displays
wlhich allow settng PIxcls lo gray levels between black
and white provide a means to
educe this ellect, The technique is called atialiasing, and it uses the gray levels to
gradually turn oft he pixels in one row as il gradually
turns on the pixels in the next.
(See Fipure 1- 10.)
The vector generatu0n algorithms can be modified to perform antialiasing.
Re-
member that for gentle slopcd lines, we in effect examined the line
position for each
column index and decided which row was closest. The line segment would lie between
wo pixels, and we picked one. Suppose that instead of picking the closest, we turned
them both on. We should choose the intensity values according to a function of the
dis
tance between the pixcl index and the line segment so that the pixel closest to the line
receives most of its intensity. The sum of the intensity values for the two pixels should
match the total intensity valuc for the line. The function used can be a simple or a com-
plex expression based on intensity patterns, pixel shapes, and how lines cover them. In
general, we want the pixel's intensity to match the amount of the line which covers its
area. Antialiasing with complicated functions can still be done efficiently by storing
the function values in a table. The table is then used to look up the intensity for a dis-
ance between the pixel index and the line. (See Figure 1-11.)
FIGURE 1-10
Antialiasing of a line.
22 mt o
i+l
FIGURE 1-11
Using vertical distance from the pixel to determine intensity.
down order to achieve the proper width w as measured perpendicular to the line di.
in
rection, not up and down. (See Figure 1-12.) Sharply sloping lines can be handled
similarly with the x and y roles reversed.
CHARACTER GENERATION
Along with lines and points, strings of characters are often displayed to label and anno-
tate drawings and to give instructions and information to the user. Characters are al
most always built into the graphics display device, usually as hardware but sometimes
through software. There are two primary methods for character generation. One is
called the stroke method. This method creates characters out of a series of line seg
ments. like strokes of a pen. We could build our own stroke-method character
generator by calls to the VECGEN algorithm. We would decide what line segments are
needed for each character and set up the calls to the VECGEN for each character we
wished to draw. In actual graphics displays, the commands for drawing the character
line segments may be in either hardware or software. The stroke method lends itself to
changes of scale; the characters may be made twice as large by simply doubling the
length of cach segment
The second method of character generation is the dot-matrir
or bitmap method. In
this scheme, characters are represented by an array of dots. An array of 5 dots wide and
7 dots high is often used, but 7 x 9 and 9 x 13 arrays
are also found. High-resolution
devices, such as ink-jet or laser printers, may use character arrays that are over 100