Sunteți pe pagina 1din 22

CSE605-Computer Graphics-Scan Conversion -1-

Graphics Devices
Scan Conversion

• Raster-Scan Displays and the Frame Buffer


• Graphics Software
• Windows-Based Graphics Systems
• Fundamental Concepts
• Scan Conversion
o Lines
o Circles
o Flood Fill
o Character Generation
o Anti-Aliasing
• Data Visualization

Raster-Scan Displays and the Frame Buffer

There are many different types of displays but the one in which we are most interested is
the one most of us use each day, whether on a Mac, PC or workstation: a raster-scan
display. The operation of a raster-scan display is based on a cathode-ray tube (CRT). A
beam of electrons (cathode ray) is emitted by an electron gun. This beam passes through
a focusing and deflection system which directs the beam toward specified positions on a
phosphor-coated screen. The phosphor then emits a small spot of light at each position
contacted by the electron beam. This flicker of light fades very quickly so, in order to
maintain the picture on the screen, the picture must be redrawn repeatedly by directing
the electron beam back over the same points.
CSE605-Computer Graphics-Scan Conversion -2-

Each phosphor point corresponds to a pixel. Raster-scan displays construct a picture


from these individual points of light. The information stored for an image corresponds
directly to the image on the display as shown below. In this example, the display is bi-
level, i.e., each pixel is either on or off (a monochrome monitor). The raster image is
stored, or “buffered” in an area of memory called the frame buffer.

The frame buffer represents a Cartesian plane with an origin defined either at the lower
left corner or upper left corner. To get the image from the frame buffer onto the screen,
the image is scanned row by row from top to bottom, left to right, just like an ordinary
TV. The CRT beam paints out a sequence of scan lines, one above the other. Each
position of the beam on the screen corresponds to one pixel and the values of these pixels
are read out from the frame buffer in sync with the beam position. For the image to be
refreshed (and not flicker due to the fading of the phosphor), it must be scanned many
times a second. Typical refresh rates are 60 times a second.

There are other types of displays. In a random-vector display, the electron beam may be
directed to any random point on the screen under program control. The display frame is
created by moving the beam over the screen in the pattern of the image to be created.

Liquid-crystal displays are very common in appliances (microwaves, digital clocks) and
in laptops. They are flat, light and draw less power than raster-scan displays. LCD
displays utilize two sheets of polarizing material with a liquid crystal solution between
them. An electric current passed through the liquid causes the crystals to align so that
light cannot pass through them. Each crystal, therefore, is like a shutter, either allowing
light to pass through or blocking the light.
CSE605-Computer Graphics-Scan Conversion -3-

Our discussion thus far has focused on monochrome displays. In order to create color
images on a raster-scan display, we need something more. First, we need more than one
electron gun and more than one type of phosphor (which is all we needed for
monochrome). A color display has three electron guns and three types of phosphor (one
glows green, one red and one blue). The phosphor-coated screen of a color display has a
“triad” pattern for each pixel. The focusing and deflection circuitry is much the same as
in monochrome except three beams are being deflected now instead of just one. They all
strike the screen at the same time and in the same place so that each gun hits its element
of the triad. Actually a mask with tiny holes called a shadow mask is carefully positioned
inside the tube of the display so that each of the beams can hit only one type of phosphor.
Each gun always hits the phosphor of a particular color so for convenience, we talk about
a “red” gun, “green” gun and “blue” gun, although the guns are the same.

CRT

Shadow Mask
Electron Guns

Red Input

Green
Input

Blue Input

Deflection
Yoke Red, Blue,
and Green
Phosphor Dots

For color, we also need to store more information about each pixel in the frame buffer.
Each pixel color is represented by several bits, and conversion circuitry converts the
digital representation of each pixel value into appropriate intensity values for the electron
guns. If a pixel is described by b bits, there will be 2b possible values for its colors.

Consider 6 bits per pixel. This is called a “6 bit/pixel” frame buffer and it can be
implemented as 6 bit “planes” of memory in the frame buffer. The six bits that represent
the pixel value give us 64 possible colors where two of the bits are routed to the green
gun of the CRT, two to the red gun and two to the blue gun. Thus, each of the guns can
be driven at four possible intensities:

bit values relative intensity


00 0 (dark, i.e., none of this color)
01 1/3 (dim)
CSE605-Computer Graphics-Scan Conversion -4-

10 2/3 (brighter)
11 1 (brightest)

The digital value (e.g. 01) is converted to the analog value (1/3) by a DAC or digital-to-
analog converter. This is an electronic device designed to convert logical values to
voltage values. Each electron gun has a DAC and the intensity of its beam is driven by
the output voltage of the DAC. Because each gun has four possible intensities in this
example, 4 * 4 * 4 = 64 possible colors can be displayed. For example, suppose a given
pixel has the value 011100:

01 for red at 1/3


11 for green at 1
00 for blue at 0

What we see is bright green and dim red giving us a faint yellow. This way of
implementing color is called a direct color system because the pixel bits directly control
the color displayed.

Since it is typical these days to have 24 bits/pixel (8 bits for each RGB), over 16 million
colors are possible. We might implement this as described above where we would have
24 bit planes that directly control the display device. But this requires a lot of memory
(at least 3 megabytes for the frame buffer depending on the screen resolution) and is
inefficient in general.

N Red

Green

Blue

Instead, many raster-scan displays have a color lookup table or CLUT that defines all the
colors that can be displayed simultaneously on the screen. An index identifies each color
in the table and specifies the amount of red, green and blue that it contains. To draw a
CSE605-Computer Graphics-Scan Conversion -5-

particular color, the application stores the CLUT index of the color into the pixel location
in the frame buffer.

y RED
max
GREEN
255
BLUE
1
1
0
y 0
0 67 Pixel displayed
0
1 1001 1010 0001
0
67 100110100001 at x', y'
R G B
Pixel in
bit map 0
0 at x', y'
0 x x
max

Bit map Look-up table Display

Many color displays are capable of displaying a wide range of colors. Unfortunately,
however, the number of colors that the screen can render at any given time may be
limited. For example, a display that can potentially produce 16 million colors may be
able to show only 256 of them simultaneously due to hardware limitations. When such a
limitation exists, the device often dynamically maintains the CLUT. A dynamically
maintained CLUT is called a palette in Windows. When an application requests a color
that is not currently displayed, the device adds the requested color to the palette. When
the number of requested colors exceeds the number possible for the device, it maps the
requested color to an existing color, i.e., the colors displayed are different than the colors
requested. When this happens, the system tries to replace requested colors with similar
existing ones, so the difference between them is often small.

Interactive raster-scan systems usually consist of several processing units. In addition to


the CPU, there is usually a display controller that exists on a separate board. Here is the
organization of a simple system:

Peripheral
CPU devices

System bus

Display System
processor memory

Display
Frame Video
processor Monitor
buffer controller
memory

Typically, a fixed area of memory is reserved for the frame buffer, and the display
controller is given direct access to the frame buffer. A number of other operations can be
performed by the display processor, besides the primary chore of refreshing the screen
from the data in the frame buffer. Some transformations can be performed: areas of the
CSE605-Computer Graphics-Scan Conversion -6-

screen can be enlarged, reduced, or moved. The CLUT is also located on the display
controller. Some display controllers have on-board memory for two frame buffers so that
one can be used for refreshing the display while the other is queued up with the next
frame to be shown (this is required for smooth animation).

Many systems have a separate display processor on the display controller board. The
purpose of the display processor is to free the CPU from the graphics chores. A major
task of the display processor is digitizing a picture definition given in an application
program into a set of pixel-intensity values to be stored in the frame buffer. This process
is called scan conversion. Graphics routines specifying straight lines and other geometric
shapes must be scan converted into a set of discrete pixels.

Graphics Software

Our focus in this course is on writing graphics applications. Graphics require that
programs control specific graphics displays but many general-purpose languages do not
contain graphics routines. The programmer must either write these routines or acquire
them. In order to understand some of the issues involved, consider the following simple
example.

This is, of course, a picture of a baby. It’s one of those international symbols that
everyone is supposed to recognize regardless of nationality, and parental status. If we
want to draw this with a computer we need to decompose it into primitive shapes or lines
so that a sequence of calls to various graphics routines can create it. At first glance, the
shape looks rather complex but it really isn’t:
CSE605-Computer Graphics-Scan Conversion -7-

Circles and rectangles are all we need, along with the ability to tilt and fill.

void circle(int cx, int cy, double radius, Boolean filled);


void rectangle(int cornerx, int cornery, double width, double height, double angle,
Boolean filled);

All we need is to draw the 15 objects in the right places, which really isn’t too hard to do.
The question now is how do we write circle and rectangle so that they work properly
given the hardware that we are using? There are a couple of options. One can use
embedded graphics routines that come with a programming environment for a particular
language. These routines are designed to work on a specific hardware configuration and
thus, are device dependent. So to draw the above picture, one checks the user manual or
the “.h” file to learn how to use the graphics routines, assuming one also has the
appropriate hardware.

The other approach is an independent graphics package which provides graphics routines
for a general-purpose programming language. These packages include the drawing
routines and a set of device drivers which control the hardware. A device driver is a
collection of low-level routines that send codes and commands to a specific graphics
device. Here is the process:

1) Programmer writes program in programming language with a particular graphics


package in mind, making calls as needed to its drawing routines.
2) Programmer compiles program.
3) Graphics display is chosen and the application, graphics package, and
appropriate device driver are linked into an executable.

The ideal scenario is if we want our code to work for a different display, just link in a
different device driver without any changes to the application. This is true device
independence. It is achieved by careful design of the graphics package. Suppose you
have a function:

void Line(double x1, double y1, double x2, double y2);


CSE605-Computer Graphics-Scan Conversion -8-

in the graphics package. What does it have inside it?

{
int xa, ya, xb, yb;

/* maybe some other stuff is done too */


ddLine(xa, ya, xb, yb); /* device driver’s line drawer */
}

The function may do other things, but primarily it makes a call to the device driver’s line
drawer. Every driver has a different version of ddLine to match a specific graphics
display. The only way this all works, of course, is if all the different device drivers name
their functions the same. That’s where the whole idea of graphics standards comes in –
something Microsoft has implemented in Windows, and SGI has done in OpenGL.

Microsoft Windows-Based Graphics Systems


CSE605-Computer Graphics-Scan Conversion -9-

Fundamental Concepts

The underlying element of all computer-generated pictures is geometry. Because of the


inherent geometry of the grid-based raster display, raster graphics pictures are composed
of geometric elements, such as points, lines, circles, arcs, triangles, and rectangles known
as primitives. We essentially draw pictures on the raster by connecting dots, i.e., by
drawing lines from pixel to pixel to create graphical primitives. These primitives serve
as the basic building blocks in the construction of more complex objects.
CSE605-Computer Graphics-Scan Conversion -10-

We typically think of computer-generated pictures as existing in two or three dimensions.


The fundamental difference between 2-D and 3-D graphics is that 2-D pictures appear
flat, and 3-D pictures appear to have volume. Note that 3-D objects are created from 2-D
primitives. A user may describe an irregular 3-D object like a tree trunk, but the
computer would deal with this by dividing it into 2-D primitives. It calculates shape,
placement and orientation of an object based on its geometric components, such as
triangles and rectangles.

Scan Conversion: Lines

Now that we have a better understanding of the hardware and basic concepts involved in
creating graphics software, we turn to the algorithms for scan conversion. These are the
algorithms that determine which pixels to illuminate to draw a line or a circle or some
other primitive.

We know that the frame buffer consists of R rows and C columns each of memory
elements which correspond to pixel locations on the screen. Each memory element either
contains or references b bits of information which can generate 2b different colors or
intensities for each pixel. To do scan conversion, we will assume the existence of a
routine called SetPixel(row, col, C) which computes the memory address in the frame
buffer for a pixel at row, col, and loads value C (which is either the color or the index for
that color in the palette) into that address.

To scan convert a line, we use SetPixel to set the pixels between the two designated
endpoints of the line so the path will represent a good approximation of the ideal line
segment that joins the endpoints. The following simple routine is our first pass at scan
converting a line. The function works directly in device coordinates, i.e., the rows and
columns of the frame buffer to determine which pixels lie closest to the ideal line.
void scLine(int col1, int row1, int col2, int row2, int color)
// draws a line from (col1, row1) to (col2, row2) in given color
{
double dy, dx, y, m;
int x;

dx = col2 - col1;
dy = row2 - row1;
m = dy / dx;
y = row1;
for (x = col1; x <= col2; x ++) {
SetPixel(x, round(y), color);
y = y + m;
}
}

For each x value, we use the slope of the line to find the ideal value y and then use
round() to get the nearest pixel position. If we want to draw a line from (1,1) to (5,6),
this routine would do the following:

dx = 4; dy = 5
m = 1.25; y = 1
CSE605-Computer Graphics-Scan Conversion -11-

for x = 1 through 5 {
SetPixel(x, round(y), color)
/* (1,1) (2,2) (3, 4) (4, 5) (5, 6) */
y = y + m }

What are the limitations and disadvantages of this routine?

This function is clearly not the best way to scan convert lines. An IBM researcher named
Jack Bresenham came up with an algorithm in 1962 for scan converting lines using only
incremental integer calculations. This means the location of the next pixel on the line is
based on information about the previous pixel. It’s an important algorithm because it is
very efficient, and it can be adapted to display circles and curves.

To illustrate Bresenham’s approach, we first consider scan-converting lines with positive


slope less than 1. Here is what we need to do:

…..

yk+2 y = mx + b

y k+1

yk

x k x k+1 x k+2……

We start at the leftmost end point, we step to each successive column (x position) and
plot the pixel whose scan line (y position) is closest to the line path. In the above
diagram, we will assume that we have determined (xk, yk) to be displayed. We now need
to decide which pixel to plot in column xk+1. We have two choices: (xk+1, yk) and (xk+1,
CSE605-Computer Graphics-Scan Conversion -12-

yk+1). The actual “y” value for the line is between the centers of pixels yk and yk+1 (in
column xk+1). What we want to do is set the pixel which is closest to this line.

So all we have to do is define these distances (the distance from y k to the line and the
distance from y k+1 to the line). The actual y value for the line is defined by:

y = m(xk+1) + b

We call the first distance (from yk to y) d1 and the second (from y to yk+1) d2.

d1 = y - yk
= m(xk+1) + b - yk

d2 = (yk+1) - y
= (yk+1) - m(xk + 1) - b

One way of looking at this is the difference between these two distances will be negative
if yk is closer to y and positive if y k+1 is closer:

d1 - d2 = 2m(xk+1) - 2yk + 2b - 1

Let’s see if we can figure out a way to use only integers in this equation so the algorithm
that we are defining will be as fast as possible. The only non-integer number in this
equation is m which is equal to the ratio of two positive integers (assuming we are
drawing a line from (x0, y0) to (xn,yn)):

dy = yn - y0
dx = xn - x0
m = dy / dx

We can define a decision parameter p; the value of this parameter will decide which y
pixel we should set. To obtain this decision parameter, we re-arrange the d1 - d2
equation above, so that it involves only integer calculations.

pk = dx(d1 - d2)
= dx(2m(xk+1) - 2yk + 2b - 1)

Substituting dy/dx for m and doing a little algebra gives us:

pk = 2dy * xk - 2dx * yk + c

The sign of pk must be the same as d1 - d2 since dx >0 (we started by saying we were
going to deal with positive slopes between 0 and 1). “c” is a constant with value 2dy +
dx(2b-1) which does not change as the algorithm increments from x0 to xn.
CSE605-Computer Graphics-Scan Conversion -13-

So, what does all this mean? Well, if the pixel at yk is closer to the line than the pixel at
yk +1 (i.e., d1 < d2) then pk is negative. In that case, we set the lower pixel; otherwise we
set the upper one.

Coordinate changes along the line occur in unit steps as we move to the next row or
column. So we can get the value of the next decision parameter using the previous one.
At step k+1, we have:

pk+1 = 2dy * xk+1 - 2dx * yk+1 + c

Subtract the pk equation above from this one gives us:

pk+1 - pk = 2dy(xk+1 -xk) - 2dx (yk+1 -yk)


pk+1 = pk + 2dy - 2dx (yk+1 -yk)

Why subtract these two equations?

We got rid of the c and we also know that (xk+1 -xk) = 1 so that goes away too. The (yk+1
-yk) is either going to be 0 or 1 depending on the sign of p k.

To get this all to work, we just have to calculate some simple variables as we move from
x0 to xn. The starting value for the decision parameter is:

p0 = 2dy - dx

(we plug (x0 , y0) into the pk equation.) Here is the final algorithm:

Bresenham’s Line-Drawing Algorithm for |m| < 1

1) Input two endpoints, store left endpoint as (x0 , y0).


2) Set (x0 , y0) in the frame buffer.
3) Calculate constants: dx, dy, 2dy and 2dy - 2dx; calculate starting value of decision parameter: 2dy -
dx.
4) At each xk, starting with k = 0 and going until k = n, perform the following test:

If pk < 0
SetPixel(xk + 1, yk, color)
pk+1 = pk + 2dy
else
SetPixel(xk + 1, yk + 1, color)
pk+1 = pk + 2dy - 2dx

Here is an example that you can plot yourself to see how it looks:

Scan convert a line from (20,10) to (30,18).

dx = 10, dy = 8, 2dy = 16, 2dx = 20, 2dy - 2dx = -4 and p0 = 6


CSE605-Computer Graphics-Scan Conversion -14-

SetPixel(20,10, color)

k pk (xk+1, yk+1) k pk (xk+1, yk+1)


0 6 (21,11) 5 6 (26,15)
1 2 (22,12) 6 2 (27,16)
2 -2 (23,12) 7 -2 (28,16)
3 14 (24,13) 8 14 (29,17)
4 10 (25,14) 9 10 (30,18)

What are the cases we must deal with to have a generic line drawing algorithm?

Scan Conversion: Circles

Circles are also frequently used as graphic primitives, so it would be helpful to have a
fast way to generate their pixel patterns given some basic information (center_x,
center_y, radius). The most obvious way to draw a circle is to use the distance
relationship between the center point (xc, yc) and a point on the circle (x, y) which is
distance r from the center. This is defined by the Pythagorean Theorem:

(x - xc)2 + (y - yc) 2 = r2

So all we have to do is step through x values and calculate the corresponding y values
using a re-arrangement of this formula:

y = yc ± sqrt(r2 - (xc - x) 2)

What are the problems with this approach?

Another way to do this is to take advantage of the inherent symmetry of a circle.


y

(x,y)
x

Notice that if we have the values for the (x,y) point in the Cartesian plane above, we can
get seven other points around the circle very easily.

What are the other points?


CSE605-Computer Graphics-Scan Conversion -15-

If we draw in the 45° angles (one is drawn), we divide the circle into 8 octants. Notice
that these octants are symmetrical, i.e., circle sections in adjacent octants within one
quadrant are symmetric with respect to the 45° line dividing the two octants. Taking
advantage of this, we can generate pixel positions around a circle by calculating only the
points within an octant. This speeds things up quite a bit, but the basic equation is still
very slow to compute.

Bresenham (of “Line-Drawing Algorithm” fame) did a similar algorithm for circles. We
won’t take the time to go through the details but it’s worth a quick look. Consider the
“best” pixels P = (x,y) to set in the octant just above the positive x-axis. In this octant,
we increment the y value by 1 at each step, and calculate a new x value. Since we are
below the 45° line, we will not have to change slope.

Here is the situation. We have just set the black pixel and now we must figure out which
pixel to set on the next round, pixel a or pixel b. We do this by figuring out which of
these pixels is closest to a point on the actual circle.

Why are these the only two choices for the next pixel?

The closer point can be found by finding the distances from each possible point to the
true point (Xtrue, Ytrue) and then subtracting one distance from the other. By testing the
sign of the result, we find which point should be used. Remembering that we are
incrementing Y and calculating X in this octant, here is the formula for the square of the
distance from the true point on the circle to the point on the right (b) which we will call
Xlast:

d1 = Xlast2 - Xtrue2 = Xlast2 - r2 + (Ylast + 1) 2

The last part of this formula comes from a substitution using the Pythagorean Theorem.
The square of the distance from the point on the left (a) which we will call Xlast-1:

d2 = Xtrue2 - (Xlast -1) 2 = r2 - (Ylast + 1) 2 - (Xlast - 1) 2

We then calculate d1 - d2 for our decision parameter pi:


CSE605-Computer Graphics-Scan Conversion -16-

pi = 2(Ylast + 1) 2 + Xlast 2 + (Xlast - 1) 2 - 2r2 (*)

To find pi+1, we plug the next point (X current, Y current) into this formula. We know that
Ycurrent is Ylast +1 and Xcurrent is either Xlast or Xlast -1. Since we don’t know which yet,
we will just refer to it as Xcurrent.

pi+1 = 2[(Ylast + 1) + 1] 2 + Xcurrent 2 + (Xcurrent - 1) 2 - 2r2

As in Bresenham’s line drawing algorithm, we now calculate pk+1 - pk. After much
algebraic manipulation, we end up with:

pk+1 = pk + 4Ylast + 6 + 2(Xcurrent 2 - Xlast 2) - 2(Xcurrent - Xlast )

Depending on which point is closer to the line, the value (Xcurrent - Xlast ) is either 0 or -1.
So the last term can be taken out and the constant becomes either 6 or 4. The (Xcurrent 2 -
Xlast 2) term will also cancel if Xcurrent = Xlast, giving us the following simple formula:

pk+1 = pk + 4Ylast + 6

This is what we need to find pk+1 when the point being plotted has the same X value as
the last point. The other case is a little harder because of the squares:

pk+1 = pk + 4Ylast + 8 + 2(Xcurrent 2 - Xlast 2)

Recall that Xcurrent in this case = Xlast - 1 so we can do a substitution to get:

pk+1 = pk + 4(Ylast - Xlast ) + 10

There is still a multiplication here but it is by 4, which is equivalent to shifting two bits to
the left. All that remains is figuring out the initial value of p by substituting (X,Y) for
(Xlast, Ylast) into the original “p” formula (marked with an asterisk above). We leave the
rest for the reader to work out.

Scan Conversion: Flood Fill

In raster-scan systems, one way of defining regions is according to the color of the pixels
which show where the region’s interior, exterior and boundary are. To tell where a
region begins and ends, we must agree on some basic terms.

Two pixels are 4-connected if they are adjacent horizontally or vertically. Thus, the
pixel at (10, 11) is 4-connected to the one at (10, 12) but not the one at (11, 12).
Two pixels are 8-connected if they are adjacent horizontally, vertically, or
diagonally. Thus, the pixel at (10, 11) is 8-connected to the pixel at (11, 12).
CSE605-Computer Graphics-Scan Conversion -17-

We’ll look at two simple filling algorithms. The first works on 4-connected regions. It
changes every pixel of inside-color to new-color. It is called a flood-fill algorithm
because it begins with a “seed” pixel in the interior of the region and floods the region
with new-color spreading out from the seed pixel. The basic idea is simple: If the pixel at
(x,y) is part of the interior (i.e., it has color inside-color), change it to new-color and
apply the same principle recursively to its four connected neighbors.

Notice we introduce a new routine in this algorithm: GetPixel(x, y) returns the color of
the pixel at location (x,y).

Recursive Flood-Fill for 4-Connected Regions


void FloodFill(int x, int y, int inside_color, int new_color)
{
if (GetPixel(x,y) == inside_color)
{
SetPixel(x, y, new_color);
FloodFill(x-1, y, inside_color, new_color);
FloodFill(x+1, y, inside_color, new_color);
FloodFill(x, y+1, inside_color, new_color);
FloodFill(x, y-1, inside_color, new_color);
}
}

How would you expand the algorithm to an 8-connected region?

This is not efficient due to all the redundant checking that must be done. The second
algorithm fills in “runs” of pixels. A run of pixels is a horizontally adjacent group of
interior pixels. To see how this works, consider the following 4-connected region:

b s a

i e d

h g f

“s” is the seed pixel. The run in which s is located (from a through b) is filled next.
Then, the row above the a-b row is scanned (from a to b) to see if there is a run. One is
found, and its rightmost pixel (c) is saved by pushing its address on a stack. Then, the
row below is scanned from a to b; a run is found and its rightmost pixel (d) is pushed on
the stack.
CSE605-Computer Graphics-Scan Conversion -18-

Now the stack is popped to give us a new seed (d) and the process is repeated. The run
from d to e is filled and three new runs are found resulting in pushes of f, g, h. Pixel h is
popped, its run is filled and two more runs are found (i and j are pushed on the stack).
The process continues until the stack is empty at which point all pixels “reachable” from
the original seed have been filled.

Character Generation

A necessary tool in the scan conversion toolkit is a character generator. Characters for
our purposes are letters, numbers, punctuation and other symbols which must be
displayed in a variety of sizes and styles. The overall design style for a set of characters
is called a typeface or font. You’ve no doubt run into these before: Courier, Helvetica,
Geneva, New York, etc.

Two different methods are used for storing fonts. The simplest is to use grid patterns or
bitmaps. To display the character, all we have to do is take a character grid and map it to
a frame buffer position. We have one such grid for all the characters in a font.

The advantages of this approach are ease of implementation and speed. The downside is
bitmap fonts require a lot of space because each variation in size and format (e.g., 10
point bold) is usually stored as a separate grid. There are techniques to modify size and
format with just one stored font. Sizing techniques are more successful then format ones,
as long as the size change is a simple integer multiple. To double the size of a character,
for example, we can use pixel replication. What we do is take small sections of the
original character grid, say 2-by-2 sections of pixels. We then create a 4-by-4 section by
enlarging each 2-by-2 section in both directions.

It is more difficult to enlarge by a non-integer factor or reduce the size of a character by


a simple factor of two. Why?

Format changes with bitmap fonts require a different set of characters for each format
type. If we need to do more involved transformations, e.g., rotate a letter, bitmap fonts
CSE605-Computer Graphics-Scan Conversion -19-

are very limited. It’s easy to rotate by 180°, but to rotate at any angle requires a
refashioning of the letter.

The other, more flexible method of storing fonts is to use outline fonts. With this
method, we describe the character shape using straight lines and curves (this is how it’s
done in PostScript). Then we use one of the scan conversion fill routines to fill in the
areas of the character. Outline fonts require less storage, but more time to process. We
can produce bold, italic or different sizes by manipulating the curve and line definitions
for the character outlines. The processing time is longer because of these manipulations,
and also because the lines and curves and fills must be scan converted into the frame
buffer.

Anti-aliasing

You have probably noticed that in raster-scan displays, we have a problem called the
“jaggies”: that stair-step effect in lines at certain angles. This is a form of aliasing. It
occurs because of the discrete nature of pixels, i.e., pixels appear on the display in a fixed
rectangular array of points. If you draw a line at certain angles, the jaggies are very
prominent; at other angles, not so much.

Aliasing arises in graphics from the effects of sampling. Samples are taken spatially, at
different points. A pixel is set to a color based on the presence or absence of the figure to
be drawn at one point (that point is the pixel’s center). In effect, the figure is sampled at
this one point without checking other areas of the pixel. We are not looking “densely”
enough within the pixel region; we could test more points if we want to minimize the
problem.

There are several techniques to perform anti-aliasing. An obvious thing to try is a higher
resolution monitor. This makes the jags smaller in size relative to the figure being drawn
(as shown above).

Looking at software solutions, the basic idea of all anti-aliasing techniques is to “blur” or
“smooth” the image. For example, if we are drawing a black triangle on a white
background, we might use shades of gray pixels near the triangle’s border. When these
CSE605-Computer Graphics-Scan Conversion -20-

gracefully varying shades are looked at from afar, the eye tends to blend them together
seeing a smoother edge.

We’ll take a look at one technique in detail: supersampling. When we apply


supersampling, we take more than one sample per pixel. What we do is subdivide the
pixel into subpixels. Then, we apply Bresenham’s algorithm (or whatever algorithm we
are using) at this more dense level. But we don’t just set the pixel on or off, we apply
different shades of gray (if we are in black/white), depending on where the pixels lie.
The subpixels closest to the figure are darkest, the ones farther away are lighter shades of
gray. The actual pixel value is the average of these samples. This has the effect of
smoothing the stairstep effect by displaying a somewhat blurred line in the vicinity of the
stairstep. There is a tradeoff for doing this: considerably more calculations per pixel.

There are other anti-aliasing techniques but all share the idea of blurring the edges to
avoid the jagged effect.

So much for our whirlwind tour of scan conversion. We have only touched on the issues
and complexities involved but hopefully, you now have a general understanding of what
is involved in creating images on raster-scan displays.

Sidebar: A Picture is Worth a Thousand Words (or a trillion data points)

Graphics serve a critical role in data visualization. In certain applications, huge amounts
of data are collected which are often difficult to analyze. Sometimes, a simple picture
can reveal important relationships. A good example comes from the world of chaos.

We first define a function for a basic parabola. For example,

f(x) = 4δx(1 - x)

where δ is some constant between 0 and 1. Beginning at a starting point for x0, between
0 and 1, the function is applied iteratively to generate the following sequence:
CSE605-Computer Graphics-Scan Conversion -21-

x1 = f(x0)
x2 = f(x1) = f(f(x0))
x3 = f(x2) = f(f(f(x0)))
etc.

How does this sequence behave? It so happens that this function exhibits a very complex
behavior and the only way to really get a feel for it is to display it graphically. The way
we create the graph is we start with a point at (x0, x1), then draw a horizontal line to (x1,
x1), then a vertical line to (x1, x2). In general, from the previous position (xk-1, xk), a
horizontal line is drawn to (xk, xk) from which a vertical line is drawn to (xk, xk+1). If we
use 0.1 for x0 and 0.7 for δ, we get a spiral effect where we converge on an attractor, or
fixed point where f(x) = x. If δ is set to small values, the action is very simple, there is a
single fixed point at x = 0. But as δ increases, something strange starts to happen. At δ =
0.85, for example, there appear to be several attractors. At the critical value of δ =
0.892486418, the effect is chaotic. For most starting points, the orbit is still periodic, but
the number of orbits between repeats is very large. For other starting points, there is a
periodic motion with very small changes in the starting point yielding very different
behavior.

This remarkable phenomenon was first recognized by Mitchell Feigenbaum in 1975.


Before then, most mathematicians believed that very small adjustments to a system of
this nature should produce correspondingly small changes in its behavior. They also
believed that simple systems like this could not exhibit such complicated behavior.
Feigenbaum’s work spawned a new field into the nature of non-linear systems, known as
chaos theory.

Bibliography

The above was derived from the following books. Refer to these if you’d like to know more about scan
conversion.
CSE605-Computer Graphics-Scan Conversion -22-

Farrell, J.A., From Pixels To Animation. London: Academic Press, 1994.

Foley, J., van Dam, A., Feiner, S., Hughes, J., Computer Graphics: Principles and Practice, Second Edition.
Reading, MA: Addison-Wesley, 1990.

Hearn, D. and Baker, P., Computer Graphics, Third Edition. Englewood Cliffs, NJ: Prentice Hall, 2004.

Microsoft Windows Software Dev. Kit: http://msdn.microsoft.com/

Pavlidis, T. Algorithms for Graphics and Image Processing, Rockville, MD: Computer Science Press,
1982.

Rogers, D.F., and Earnshaw, R.A., Techniques for Computer Graphics, New York: Springer-Verlag, 1987.

Sun Microsystems, Inc. An Introduction to Computer Graphics Concepts: from Pixels to Pictures, Reading,
MA: Addison-Wesley, 1991.

Bresenham’s algorithms come from:

Bresenham, J.E., “Algorithm for Computer Control of Digital Plotter,” IBM Systems Journal, 4: 25-30,
1965.

Bresenham, J.E., “A Linear Algorithm for Incremental Display of Circular Arcs,” Communications of the
ACM, 20(2): 100-106, 1977.

For more on anti-aliasing:

Booth, K.S., Bryden, M.P., Cowan, W.B., et al, “On the Parameters of Human Visual Performance: An
Investigation of the Benefits of Antialiasing,” IEEE Computer Graphics and Applications, 7(9): 34-
41, 1987.

Crow, F.C., “A Comparison of Antialiasing Techniques,” IEEE Computer Graphics and Applications, 1(1):
40-49, 1981.

On chaos theory:

Gleick, J., Chaos: Making a New Science, New York: Viking Penguin, 1987.

Hofstadter, D.R., Metamagical Themas, New York: Basic Books, 1985.

S-ar putea să vă placă și