Chapter 13 - Graphics

One of the many advantages to programming in True BASIC is the power and simplicity of its graphics capabili- ties. Using True BASIC’s various tools, you can easily create complex graphical images to enhance your programs. And unlike those produced by many other programming languages, the graphics you create with True BASIC pro- grams will look the same regardless of the operating environment you use.

True BASIC’s PLOT statements draw points, lines, curves, and filled regions. You can use any combination of col- ors your computer provides, and you may freely mix printing and graphics. You define the coordinate system for the graphic statements, and you can create several regions or “logical windows” within the physical output area for graphical or text elements. The user can supply coordinate input to your program as it is running. BOX state- ments can speed up many graphics operations and animate your drawings. Pictures are subroutines that let you define graphical components that you may combine and transform to create complex drawing.
This chapter introduces all the above elements of True BASIC’s graphics statements. It introduces physical win- dows and logical windows, and describes the coordinate systems available with True BASIC. See Chapter 14 “Interface Elements” for details on creating and manipulating physical windows and on the True Controls library of subroutines for creating graphic and other objects such as menus, scroll bars, radio buttons, and check boxes.

Windows and Coordinate Systems
True BASIC uses two kinds of windows — physical and logical windows — and three coordinate systems — pixel coordinates, screen coordinates, and user coordinates.

For most of your work with True BASIC graphical statements, you will use user coordinates. Graphical state- ments place elements in the current display area based on user coordinates. You define the limits of these coordi- nates with the SET WINDOW statement described below in the section on “User Coordinates.” For quick, simple graphical output, all you need to do is define the limits of the user coordinates and then use the appropriate graph- ics statements to draw images within those coordinates. In this simple case, True BASIC uses the full content area of the output window to display output in the user-coordinate range you define (or, more technically, True BASIC fits your user-coordinate system into the default logical window that occupies the entire default physical window). If you are new to graphic programming, you can begin by reading the section on user coordinates below and then skipping ahead to “Plotting Points and Lines,” returning later to the explanations below.

You can further control the graphical display area, however, by defining specific window areas to display different ranges of user-coordinates. You do this by creating one or more logical windows within the default physical window — the standard output window — or by creating additional physical windows for output, which could in turn have multiple logical windows. The next two sections define physical and logical windows and show how to use screen coordinates to create logical windows within a physical window.

You create additional physical windows — and may also position user-interface objects within physical windows
— with pixel coordinates. Pixel coordinates are introduced below. Chapter 14 “Interface Elements” describes how to create and manipulate physical windows.

Physical Windows vs. Logical Windows
A physical window in True BASIC is the type of window your operating system uses. These windows occupy a distinct area of the screen and often have features such as title bars, borders, and scroll bars that easily identify them as windows.
132 True BASIC Language System

When you run a program that produces screen output, True BASIC automatically creates a physical window to dis- play that output. This window is called the default physical window, and it is easily visible on the screen.

What you can’t easily see, however, is that True BASIC also creates another window within the default physical window. This second window has no visually identifying features, such as a title or border. This type of window is a logical window. The default logical window fills the entire content area of the default physical window; your user-coordinate system fills this area if you do not define a specific logical window. (The content area of a physi- cal window is the region that may contain output; it does not include the title bar and scroll bars.) While your com- puter’s operating system does most of the management of physical windows, True BASIC has exclusive control of logical windows.

True BASIC uses logical windows to partition a physical window. Logical windows serve two important functions: (1) they provide a framework for defining user-coordinate systems, and (2) they define a “clipping region” for graphical output. As described below, you can create several logical windows within a physical window and direct different output elements to different logical windows.

Chapter 14 “Interface Elements” describes how you can use the True Controls library of routines to create and maintain numerous physical windows. In this chapter, however, we assume that you are working with only the default physical window, although you may have several logical windows within that physical window.

————————–––———————————————————————————————
[ ! ] Note: Each logical window must exist within a physical window. Although it is possible to use the
built-in Object routine (see Chapter 19 “Object Subroutine”) to create a physical window that does not
contain a logical window, it is not possible to define a logical window without a physical window. This chapter defines all logical windows within the default physical window.
————————————–––———————————————————————————

Creating Logical Windows with Screen Coordinates
As noted above, if you do not specifically create a logical window, your output will use the default logical window, which fills the content area of the default physical window. Although you can accomplish a lot using only the default logical window, you may sometimes want to define additional logical windows.

You may define any rectangular region of a physical window’s content area as a logical window. The OPEN statement with the SCREEN keyword creates a logical window within the current physical window, as follows:
OPEN #1: SCREEN left, right, bottom, top
The OPEN statement associates the defined area of the physical window with a specified channel number. Chan- nel numbers always consist of a pound sign (#) followed by a number from 1 to 999 (or a numeric expression that evaluates to such a value). Channel #0 is reserved for the default logical window, which is always open. After you’ve opened a logical window, you must always refer to it by its associated channel number.

The four numeric values following the keyword SCREEN define an area of the physical window. They use screen coordinates to represent the positions of the left, right, bottom, and top edges of the logical window within the physical window. Screen coordinates are used exclusively for positioning logical windows. In this coordinate sys- tem the point (0, 0) is always in the lower, left corner of the physical window’s content region. The upper, right cor- ner is always the point (1,1). Thus, the x-axis (horizontal axis) of the physical window ranges from 0 (at the left end) to 1 (at the right end), and the y-axis (vertical axis) ranges from 0 (at the bottom) to 1 (at the top).

You may define any region of the physical window as a logical window by giving the locations of its edges as val- ues between 0 and 1, inclusive, in an OPEN statement. For instance, the example:

OPEN #7: SCREEN .5, 1, 0, .3
opens a logical window that occupies the lower right corner of the content area of the physical window and associ- ates this logical window with channel #7.
Graphics

133

True BASIC Screen Coordinates
——————————————————————————————————————

1

.3

WINDOW #7

0
0 .5 1
Screen Coordinates
——————————————————————————————————————

The CLOSE statement closes channels associated with logical windows (or files or printers) For instance, the statement:
CLOSE #7
would close the logical window associated with channel #7.

You may not use a channel number that is already open to open a logical window, but you may reuse channel num- bers after they have been closed. Also, True BASIC does not allow more than 25 open channels at any one time (not counting #0 which is always the default logical window). Thus, when your program no longer needs a logical win- dow, it should close it to make that channel available for reuse. (Note that files and printers also use channel num- bers, see Chapter 12 “Files for Data Input and Output.” A channel number may be associated with only one open item; that channel must be closed before it can be reused for another item.)
Following an OPEN statement, the logical window just created will be the current logical window where True BASIC will send subsequent output (either textual or graphical). Only one logical window can be the current log- ical window at any one time. To change the current logical window, use the WINDOW statement. For instance, to switch to the logical window associated with channel #7, use:
WINDOW #7
Or, if you have opened four logical windows using channels #1 through #4, the following code:
FOR n = 1 to 4 ! Window number WINDOW #n ! Switch window PRINT “Window”; n
NEXT n
will label each of the logical windows.

True BASIC remembers each logical window’s currently selected options (as described below); when the program switches to a logical window, all options defined for that window are available.
The default logical window is always associated with channel #0 and cannot be closed. Therefore, you can always return to this window with the statement:
WINDOW #0
If you need to find out the screen coordinates that define the location of the current logical window, you can use the
ASK SCREEN statement:
ASK SCREEN left, right, bottom, top
This assigns the screen coordinates of the current logical window to left, right, bottom, and top.
134 True BASIC Language System

User Coordinates
Each logical window has a user-coordinate system used by True BASIC’s various plotting statements to position output within the logical window. This coordinate system is defined by a range of values along the horizontal edge or x-axis of the window combined with the range of values along the vertical edge or y-axis of the window. Most graphical operations described in this chapter use user coordinates. You can define any point within the logical window simply by specifying its position in relation to both axes. A point’s position along the x-axis is its x-coor- dinate, and its position along the y-axis is its y-coordinate. Thus, any point may be identified by its x- and y-coor- dinates.
When a logical window is first opened, it has a default user-coordinate system in which the x-axis ranges from
0 (on the left) to 1 (on the right) and the y-axis ranges from 0 (at the bottom) to 1 (at the top). Thus, by default, the user-coordinate point (0, 0) is the lower, left corner of a logical window, and the point (1,1) is the upper, right cor- ner of the window.
You may change a logical window’s user-coordinate system to anything you wish with the SET WINDOW state- ment. For example:
SET WINDOW 0, 2*pi, -1, 1
specifies that the values along the x-axis range from 0 (on the left) to 2p (on the right) and the values along the y- axis range from –1 (at the bottom) to 1 (at the top). This user-coordinate system would be suitable for plotting a sine curve. If you wanted to graph population data (in millions) between 1900 and 1990, you might use the follow- ing coordinates:
SET WINDOW 1890, 2000, -30, 300
Notice how these coordinates define an area slightly larger than the graph itself, allowing room for labels.

Remember that each logical window you create has its own user-coordinate system. Thus, if you open several dif- ferent windows, you may want to specifically set their user-coordinate ranges:
OPEN #1: SCREEN .5, 1, 0, .4 ! Lower right portion
SET WINDOW -10, 10, -10, 10 ! Define coordinate system

OPEN #2: SCREEN .5, 1, .5, 1 ! Upper right portion
SET WINDOW -1, 11, -5, 100 ! Define coordinate system
You will usually find that your code will be easier to understand if you place the SET WINDOW statement imme- diately after the OPEN statement. However, True BASIC does not require this; you may use a SET WINDOW statement at any time to change the user coordinates of the current logical window.

You can find the current user-coordinate ranges of the current logical window with the ASK WINDOW statement:
ASK WINDOW left, right, bottom, top
This example would assign the user coordinates of the current logical window to left, right, bottom, and
top.

User coordinates provide great power and flexibility. You may specify any axes range you wish including ranges from larger to smaller values. In fact, the only limitation of the SET WINDOW statement is that the values of the left and right ends of the x-axis may not be equal, nor may the values of the top and bottom ends of the y-axis. You will find that most graphical applications are easy to implement when you can choose a coordinate system suited to your needs.

The user-coordinate system adapts itself as the size or shape of the logical window changes. Regardless of the size or shape of the logical window, its user-coordinate range will remain the same — units along the axes are stretched or condensed so that the defined ranges always fill the current logical window. This greatly simplifies graphical pro- gramming in varied environments, since programs can draw equivalent images in logical windows of any size and shape on any computer without changes to the source code. This is a significant advantage over the third type of coordinate system available within True BASIC — pixel coordinates.
Graphics

135

Pixel Coordinates
Each physical window has a pixel-coordinate system in addition to the screen-coordinate system used to define log- ical windows.

The word “pixel” is an abbreviation of the phrase “picture element,” and it refers to the units that form images on the computer screen. A computer screen is divided into a very fine grid of a very large number of rectangles. By changing the color of some of these rectangles, the computer displays “pictures” on the screen, thus the rectangles are called picture elements or pixels.

A pixel-coordinate system is, therefore, another way of identifying points within the content area of a physical window. Each point has two pixel coordinates. The first represents the point’s location as a number of pixels from the left edge of the window, and the second represents the point’s location as a number of pixels from the top edge of the window. (Note that pixel coordinates start from the top edge, while screen coordinates and user coordinates begin at the bottom edge.)

Everything displayed on a computer screen is a pattern of pixels of various colors, but not all computer screens dis- play the same number of pixels. The number of horizontal and vertical pixels determines the screen’s resolution. Pixel-coordinate ranges therefore vary depending upon the resolution of the current computer hardware, the com- puter’s operating environment, and the size of the physical window in relation to the full screen.

Because they can vary so easily, pixel-coordinate systems are less desirable than user-coordinate systems for most types of graphics. True BASIC graphical statements described in this chapter automatically translate user coor- dinates into pixel coordinates, thus you need not worry about pixel coordinates when using them. Most of the inter- face objects described in Chapter 14 “Interface Elements” also let you use user coordinates if you wish, but there are times when you might wish to use pixel coordinates directly.

You may also define a user-coordinate system to mimic pixel coordinates. To do so use the ASK PIXELS state- ment, which reports the number of pixels within the current logical window in the horizontal and vertical direc- tions, along with the SET WINDOW statement. For example:
ASK PIXELS hpix, vpix
SET WINDOW 0, hpix-1, vpix-1, 0
Notice that the vpix value sets the bottom range of user coordinates. In pixel coordinates “bottom” is always greater than “top” because pixels are counted from the top edge.

Aspect Ratios
You may be disappointed when you ask True BASIC to draw a circle or a square; a square may look like a rectan- gle, and a circle may look like an ellipse (or oval). Getting square squares and round circles can be tricky as it involves adjusting the aspect ratio of the current logical window.

The aspect ratio of a window compares the distance of a horizontal line segment to an equivalent vertical line seg- ment — in user-coordinate units. When a window’s aspect ratio is 1, equivalent horizontal and vertical lines will appear to be the same length, and as a result squares will look like squares and circles will look like circles.

Since most computers today have square pixels, you can adjust the aspect ratio of a window by matching the x to y ratios for pixel and user coordinates. For the current logical window for example, the following code would set up a user-coordinate system with the origin (0,0) in the center of the window and with an aspect ratio of 1:
ASK PIXELS hpix, vpix
LET pratio = hpix/vpix ! Find x to y ratio for pixels
LET vrange = 20
LET hrange = 20 * pratio ! x to y ratio for user coordinates will
! = pixel ratio
SET WINDOW -(hrange/2), (hrange/2), -(vrange/2), (vrange/2)
136 True BASIC Language System

Plotting Points and Lines
The PLOT POINTS and PLOT LINES statements let you draw points or lines on the screen. For example, the following statement plots the corners of an isosceles triangle:
PLOT POINTS: 1,1; 3,1; 2,2
And the following draws the sides of the triangle:
PLOT LINES: 1,1; 3,1; 2,2; 1,1
In the PLOT LINES statement the first point must be repeated at the end so that the last point connects to the original one. Notice that both statements have a colon after the keywords, before the list of points.
If the statement is quite long, you can divide it into more than one statement. But for PLOT LINES, each state- ment other than the last must end with a semicolon to indicate that the lines should be connected:
PLOT LINES: 1,1; 3,1; PLOT LINES: 2,2; 1,1
The following program draws fifty randomly chosen points:
SET WINDOW 0, 1, 0, 1 ! All points between 0 and 1 for each axis
FOR n = 1 to 50
PLOT POINTS: Rnd, Rnd ! Random point
NEXT n

END
Replacing the PLOT POINTS statement with:
PLOT LINES: Rnd, Rnd; ! Random lines
will produce a random zig-zag pattern.

You may use the PLOT statement as an abbreviation for either the PLOT POINTS or PLOT LINES statement. If you are plotting unconnected points, however, you must place each coordinate-pair on a separate PLOT state- ment. For example, to draw the points of a triangle you would need three statements:
PLOT 1,1
PLOT 3,1
PLOT 2,2
A semicolon between or after coordinate pairs on a PLOT statement connects the points with lines. Thus, a trian- gle could be drawn with the statement:
PLOT 1,1; 3,1; 2,2; 1,1
Similarly, the random points in the loop above could be drawn with:
FOR n = 1 to 50
PLOT Rnd, Rnd ! Random point
NEXT n
and the random lines with:
FOR n = 1 to 50
PLOT Rnd, Rnd; ! Random lines
NEXT n
Notice that there is no colon in a PLOT statement.

Although, True BASIC can draw only straight lines between two points, you can plot a curved line as a series of sev- eral short lines. As an example, look at the following code segment that prints a table of the sine function:
FOR x = 0 to 2*Pi step .1 ! Use built-in functions Pi and Sin
PRINT x, Sin(x) NEXT x
Just changing the PRINT statement to a PLOT statement will plot the corresponding points (in a suitable user- coordinate system). And adding a semicolon at the end of the PLOT statement will plot the sine curve:
Graphics

137

SET WINDOW 0, 2*Pi, -1, 1
FOR x = 0 to 2*Pi step .1
PLOT x, Sin(x); ! Plot sine curve
NEXT x
PLOT ! Stop connecting points

END
A PLOT statement with no coordinate pair and no punctuation, sometimes called a vacuous PLOT statement, starts a new line or curve. This is analogous to a PRINT statement with nothing after it. Thus, the above program uses a vacuous PLOT statement after the NEXT statement in case it later plots another point or line. Without a vacuous PLOT, the last point of the sine curve would be connected to the next point plotted. While it is not essen- tial in this example, it is a good habit to use vacuous PLOT statements to avoid stray lines when expanding or maintaining your programs.
In the previous example, the entire curve will be visible. If, however, the user coordinates did not include the entire range, the curve would be clipped at the logical window boundary. That is, only the part of the curve that lies within the window is drawn. For example, with the user coordinates:
SET WINDOW 0, 2*Pi, 0, 1
only the top half of the curve would be visible. No error results; the entire curve is “drawn,” but that portion out- side the bounds of the current logical window is not shown.
Note that all plotting is performed using the current color, as explained later in this chapter.

If you want to plot many points, it may be convenient to compute the coordinates first and store them in an array. The array must be two-dimensional, with one row for each point and exactly two columns. The first column con- tains the x-coordinates and the second contains the corresponding y-coordinates. The statements MAT PLOT POINTS and MAT PLOT LINES work like the corresponding PLOT statements, plotting points or lines con- tained in the array named with the statement.
For example, the following program plots a sine curve by first storing the values in an array and then using MAT PLOT LINES to plot the points in the array:
SET WINDOW 0, 2*Pi, -1, 1
DIM sincurve (100,2)

FOR x = 0 to 2*Pi step .1
LET point = point + 1
LET sincurve (point,1) = x ! Store values in array
LET sincurve (point,2) = Sin(x) NEXT x

MAT redim sincurve(point,2) ! Remove any uncomputed points
MAT PLOT LINES: sincurve ! Plot values in the array

END

Plotting Areas
The PLOT AREA statement draws the outline of a region (which may be quite complex) and colors its interior in the current foreground color. It works very much like the PLOT LINES statement, but, since the region must be enclosed, it automatically connects the last point to the first. Thus:
PLOT AREA: 1,1; 3,1; 2,2
will draw a triangle and fill it in. If the boundaries of the region cross each other, it is not obvious which points are on the inside. True BASIC uses a standard mathematical solution of this problem.
You can also color an area with the FLOOD statement. After you have drawn the boundaries of a region, you may color a contiguous piece of it with the statement:
FLOOD x, y
138 True BASIC Language System

Flooding uses the current foreground color starting from the point x, y and continuing out to the boundaries, which are identified by any color different from the original color of the point x, y. You may color different areas by using several FLOOD statements. To color the exterior, use a coordinate point outside the region.
———————————–––————————————————————————————
[ ! ] Note: If the color on the screen is a dithered color, FLOOD will not work correctly. Colors need to be
solid (realizing them if necessary) for FLOOD to work correctly.
———————————————————–––————————————————————
As mentioned above for plotting points, you can store and plot coordinates in two-dimensional arrays. The first column of the array must contain the x-coordinates and the second, the corresponding y-coordinates. The MAT PLOT AREA statement works like the PLOT AREA statement for each coordinate pair in the array. The fol- lowing program produces the picture shown below:
DIM points(201, 2)
SET WINDOW -1, 1, -1, 1
FOR t = 0 to 2 step .01 ! Compute points LET c = c+1 ! Count points LET points(c,1) = Sin(3*t*Pi) ! x-coordinate LET points(c,2) = Cos(5*t*Pi) ! y-coordinate
NEXT t
MAT PLOT AREA: points ! Draw and fill in

END

MAT PLOT AREA Example
——————————————————————————————————————

——————————————————————————————————————
See the section below on “Box Statements and Animation” for additional statements that can quickly draw or fill simple shapes.

Mixing Text and Graphics
Logical windows may contain text as well as graphics. In fact, they are often used exclusively for text. To print text to a logical window, you may use the standard PRINT statement or the more flexible PLOT TEXT statement.
Output from a PRINT statement goes to the current logical window. Each logical window maintains its own text cur- sor position, margin, and zone width. Thus, the SET CURSOR, SET MARGIN, and SET ZONEWIDTH state-
Graphics

139

ments (plus their associated ASK statements and the ASK MAX CURSOR statement) apply to the current logical window. As you switch between logical windows, subsequent PRINT statements in each window will send output to that window’s current text cursor position. (See Chapter 3 “Output Statements” for information on these statements.)

When the text cursor reaches the bottom of a logical window, the contents of that window scroll up to make room for a new line, and the topmost line is lost. Text, like graphics, may be clipped at logical window boundaries if the margin is greater than the width of the logical window. Lines that are too wide to fit within the current margin will be wrapped to the next line; since True BASIC sets an appropriate margin for any logical windows you create, text will normally be wrapped at the window boundary. However, if you reset to a wider margin, that part of a text line that extends beyond the window boundary will be clipped.
———————————————————–––————————————————————
[ ! ] Note: Operating environments with graphical user interfaces generally do not support automatic text
scrolling as efficiently as the text-only environments prevalent during much of True BASIC’s evolution.
Reliance on True BASIC’s automatic text scrolling may not produce fully satisfactory results. If you encounter such a situation, you may be able to produce more pleasing results by handling the scrolling of text yourself (see Chapter 14 “Interface Elements”) or avoiding it altogether.
—————————————————————–––——————————————————
Despite its usefulness for many simple tasks, the PRINT statement is limited to specific cursor locations within a logical window. Thus, you may prefer the PLOT TEXT statement when combining text with graphics.

The PLOT TEXT statement is more convenient because it positions text output using the graphical user-coordi- nate system. For example, the statement:
PLOT TEXT, AT x, y: “Sine curve”
places the text label “Sine curve” at the coordinate point x, y.

PLOT TEXT can print only string values, but you can easily convert numbers into strings using the STR$ or
USING$ functions (see Chapter 8 “Built-in Functions”). For example:
PLOT TEXT, AT 1990, y: Str$(y)
or
PLOT TEXT, AT x, y: Using$(“##.##”, y)
The PLOT TEXT statement normally places the lower-left corner of the text at the point defined by x, y. How- ever, you can use the SET TEXT JUSTIFY statement to control the alignment of the text at the defined point. The general form of the SET TEXT JUSTIFY statement is:

SET TEXT JUSTIFY horiz$, vert$
For horiz$ you may use one of the values “LEFT”, “CENTER”, or “RIGHT” to indicate a point along the length of the text; for vert$ you indicate a point in the height of the text as “TOP”, “HALF”, “BASE”, or “BOTTOM”. The “bottom” of the text is the lowest point (or descender) of any character, while the “base” of the text refers to its baseline, or the line along the lowest points of uppercase characters.

SET JUSTIFY Values
——————————————————————————————————————
top
half bottom
Justify That Text! base

left center right

——————————————————————————————————————
For example, if you want to center the lowest point of the text at a specified point, you should use:
SET TEXT JUSTIFY “center”, “bottom”
before using the PLOT TEXT statement.
140 True BASIC Language System

The text alignment established by a SET TEXT JUSTIFY statement remains in effect for all subsequent PLOT TEXT statements until another SET TEXT JUSTIFY statement is encountered. The SET TEXT JUSTIFY statement controls the alignment of PLOT TEXT output only; it has no effect on the alignment of PRINT state- ment output.

The statement:
SET TEXT JUSTIFY “left”, “base”

returns to the default alignment that True BASIC uses, and the statement:
ASK TEXT JUSTIFY horiz$, vert$

lets your program find the current text alignment.

Consider an example. The following program draws the values of the array profit as a bar chart and labels the years. It centers the label at the specified point and uses the STR$ function to convert numeric values to string. (The SET COLOR statement is described below.)
SET WINDOW 1975, 1989, -10, 100
SET COLOR “GREEN”
PLOT 1975,0; 1989,0 ! Axis

SET TEXT JUSTIFY “LEFT”, “HALF” ! Position label
FOR y = 1975 to 1988
SET COLOR “YELLOW”
BOX AREA y, y+.5, 0, profit(y) ! Bar
SET COLOR “red”
PLOT TEXT, AT y+.25, 1: Str$(y) ! Label
NEXT y

END
Whether you use text, graphics, or a combination of both, you can clear the contents of a logical window with the
CLEAR statement:
CLEAR
The CLEAR statement erases the contents of the current logical window, filling it with the current background color and repositioning the window’s text cursor in the upper-left corner. The window’s margin, zone width, beam state (whether or not a line will be drawn to the next PLOT point), and graphics cursor position are not changed.

Using Colors
True BASIC lets you use any color available in your computer’s operating environment. At any given time, you may work with two colors — a foreground color and a background color.

The foreground color is used for objects drawn on the screen including points, lines, and text. By changing the foreground color between plotting or print statements you can produce multi-colored output. The background color is used behind text produced by the PRINT statement and when the window is cleared.

The SET COLOR statement establishes the foreground color. There are two forms of this statement; one takes a string and the other takes a number. When used with a string, as in:
SET COLOR “RED”

the SET COLOR statement sets the current foreground color to the named color After the above statement, all drawing and printing will be in red until a new SET COLOR statement is executed.

The available color names are:
RED MAGENTA YELLOW GREEN BLUE CYAN BROWN WHITE BLACK
BACKGROUND
Graphics

141

The value of a string expression used with the SET COLOR statement must evaluate to one of these names; oth- erwise an error occurs. If your computer does not provide all these colors, True BASIC will use another color. For example, red may be used in place of magenta, or vice versa.

Although there are only ten color names, most computers can display many more colors. The second form of the
SET COLOR statement uses a numeric value to specify the foreground color, as follows:
SET COLOR 12

The default foreground color is color number -1 (black); the default background color is -2 (white). True BASIC also initially defines color numbers 0 through 15; the rest are set to black. Your computer, however, may likely be able to produce many more colors. The ASK MAX COLOR statement will tell you how many colors your computer can simultaneously display. See the next section on “Making Custom Colors” to learn how to define additional color numbers.

You may also specify color numbers as string values. Thus, the following two statements are equivalent:
SET COLOR “1” SET COLOR 1

You can find out the current foreground color with the ASK COLOR statement. It too has a string form and a numeric form, as follows:
ASK COLOR cname$ ASK COLOR cnumber
True BASIC assigns the name or number of the current foreground color to the specified variable. If you ask for a string variable and the current color is not one of the official color names, True BASIC assigns a null string to the variable.

The color numbers that correspond to color names vary among computer operating environments. You can use the
ASK COLOR statement to find out the color number assigned to a particular color name as follows:
SET COLOR “RED” ASK COLOR red
These statements first set the current color to “RED” and then assign the corresponding color number to the vari- able red.

The SET BACK (or SET BACKGROUND COLOR) statement establishes the background color. As with the SET COLOR statement, it may take a string or numeric value. The same color names and rules for the string expression apply to the SET BACK statement as for the SET COLOR statement.
The specified background color will be used to surround subsequent printed text and to clear regions of the screen until a new SET BACK statement is executed. Any existing background is not affected, however, until it is cleared or printed on.
You can find out the current background color with the ASK BACK (or ASK BACKGROUND COLOR) statement, which like ASK COLOR has both string and numeric forms:
ASK BACK bname$ ASK BACK bnumber
If you ask for a string variable and the current color is not one of the official color names, True BASIC assigns a null string to the variable.
The color name “BACKGROUND” represents the current background color. For example, the statement:
SET COLOR “BACKGROUND”
sets the current foreground color to match the current background color. By drawing or redrawing an image in the current background color, you can easily erase or cut a hole in a previously drawn image.
You may simultaneously change current color and background color as follows:
SET COLOR “BLUE/WHITE”
142 True BASIC Language System

for drawing or printing in blue on a white background.

To better understand the use of colors, consider the following program that draws blue axes and a red curve on a yellow background:

SET WINDOW -1, 10, -3, 3

SET BACK “YELLOW”
CLEAR ! Re-paint background with new color
SET COLOR “BLUE”
PLOT 0,0; 10,0 ! x-axis
PLOT 0,-3; 0,3 ! y-axis
SET COLOR “RED”
FOR x = .1 to 10 step .1 ! Draw curve
PLOT x, Log(x); NEXT x

END
The CLEAR statement is needed to erase the entire logical window and re-draw it in the new current background color. Without the CLEAR statement the axes and curve would be drawn on the default background color.

Making Custom Colors
Your computer can probably display many more colors than the 16 color numbers (0 through 15) initially defined by True BASIC. The ASK MAX COLOR statement:

ASK MAX COLOR m
will assign to m the number of colors your computer can display simultaneously. You can use the SET COLOR MIX statement to define any available color number.

A computer screen displays colors by directing beams from “color guns” at the phosphor coating on the screen. The nature, intensity, and combination of these beams determine the precise color they produce. There are three such color guns — red, blue, and green — and all can be directed at any single pixel on the screen. By controlling the intensity of the beams from each color gun, you can control the colors displayed on the screen.

The SET COLOR MIX statement gives you control of these beam intensities, as follows:

SET COLOR MIX (colornum) red, green, blue
For colornum, you specify a number for the color you want to create. You may choose any number between 0 and the value returned by the ASK MAX COLOR statement. Note, however, that a single color number may repre- sent only one color at a time; when you associate it with a new color, any existing color is replaced.

You define the color for colornum by specifying the intensity levels of the red, green, and blue color guns. The intensity levels can vary between 0 and 1, where 0 is off and 1 is full intensity. Thus,
SET COLOR MIX (14) 0, 0, 0
associates pure black with color number 14 (since all the color guns are off), and
SET COLOR MIX (13) 1, 1, 1
associates pure white with color number 13 (since all the color guns are at full intensity). Likewise, you can use values between 0 and 1 to create different colors:
SET COLOR MIX (2) 1, 1/3, 0 ! Color 2 is orange
SET COLOR MIX (5) 0, 0, 1 ! Color 5 is bright blue
By varying intensity values, you can create any color your current operating environment can display. If your sys- tem cannot display the exact color intensities you specify, True BASIC uses the color closest to the defined mix. Thus, very small changes in the values of red, green, and blue may not produce different colors.
Graphics

143

True BASIC selects a color mix for each legal color number, including (if possible) the nine colors that have names. To find out the current mix for a color number, use the ASK COLOR MIX statement:
ASK COLOR MIX (colornum) red, green, blue
This places the color intensities for color number colornum into red, green, and blue.
If you mix your own colors, we advise that you avoid the lower numbers or use color numbers (and not color names) throughout your program. When you use a color name, True BASIC establishes a new color mix for its corre- sponding color number. Thus, if you have established a custom color and then use a color name that happens to correspond to that same color number, your custom color will be replaced by the color name.

BOX Statements and Animation
You can draw simple shapes quickly and animate your drawings with BOX statements. Each BOX statement operates on a rectangular region of the screen called its bounding rectangle. This bounding rectangle is speci- fied as four values in user coordinates representing its left, right, bottom, and top edges:
BOX LINES left, right, bottom, top ! Draw rectangle
BOX AREA left, right, bottom, top ! Draw filled rectangle
BOX CLEAR left, right, bottom, top ! Erase rectangle
BOX CIRCLE left, right, bottom, top ! Inscribe an ellipse within rectangle BOX ELLIPSE left, right, bottom, top ! Inscribe an ellipse within rectangle BOX DISK left, right, bottom, top ! Inscribe a filled ellipse within rectangle
The BOX LINES statement draws the outline of its bounding rectangle in the current foreground color. The BOX AREA statement fills its bounding rectangle with the current foreground color. The BOX CLEAR statement fills its bounding rectangle with the current background color, effectively erasing its contents. The BOX CIRCLE statement (which is identical to BOX ELLIPSE) draws the outline of the circle (if the bounding rectangle is a square) or ellipse (if it is not) inscribed within its bounding rectangle. The BOX DISK statement fills the circle or ellipse inscribed within its bounding rectangle with the current foreground color.
While many of these BOX statements can be reproduced using PLOT, PLOT AREA, or FLOOD statements, the BOX statements execute faster and are easier to use. For example, the following program draws six rectangles, each inside the previous one, and each in a different color. If the logical window is square, the result will be six squares.
SET WINDOW -6, 6, -6, 6
FOR n = 6 to 1 step -1
SET COLOR n
BOX AREA -n, n, -n, n
NEXT n

GET KEY k
END
BOX AREA Example
——————————————————————————————————————

——————————————————————————————————————
144 True BASIC Language System

You can use BOX LINES to easily “frame” a window:
ASK WINDOW left, right, bottom, top ! Get user coordinates
BOX LINES left, right, bottom, top ! Draw “frame” around window
Note that the same four numbers are used, in the same order. The next series of statements draws a circle (or ellipse) in one color and fills it with a different color:
SET COLOR “RED”
BOX CIRCLE 1, 3, 6, 8
SET COLOR “GREEN” FLOOD 2, 7
The FLOOD statement uses a point in the middle of the figure to color the area. If you want the outline and the interior to be the same color, the BOX DISK statement is faster.

Saving and Showing Screen Images
The BOX KEEP and BOX SHOW statements let you store and redisplay rectangular regions of the screen. The BOX KEEP statement “memorizes” the contents of its bounding rectangle, storing the image in an image string. The BOX SHOW statement displays a stored image string (in its original shape and size) at any location in the window. You can produce animation by alternating BOX SHOW and BOX CLEAR statements to move a draw- ing or series of drawings across the screen.

For example, suppose that your program has drawn a picture of a dog that you want to display again later in the program. You can use the BOX KEEP statement:
BOX KEEP 2,4,7,9 IN dog$
to save the rectangular area containing the dog picture in the string variable dog$. You can then redisplay this image using the BOX SHOW statement. The statement:
BOX SHOW dog$ AT 5, 8
would redisplay the image stored in dog$ with its lower, left corner at the point (5, 8). The displayed image will be the same size and shape as the rectangular region saved by the BOX KEEP statement.

If you combine the BOX KEEP and BOX SHOW statements with the BOX CLEAR statement, you can simulate movement on the screen. As an example, consider the following program, which shoots an arrow across the screen:
SET WINDOW 0, 10, 0, 20

PLOT 0,9; 1,9 ! Draw arrow
PLOT .6,8; 1,9; .6,10
PAUSE 1
BOX KEEP 0, 1, 8, 10 IN arrow$ ! Memorize it

LET x = 0
FOR move = 1 to 50 ! Move in small steps
PAUSE 0.1 ! Slow it down
BOX CLEAR x, x+1, 8, 10 ! Erase old
LET x = x + .2
BOX SHOW arrow$ AT x,8 ! Draw at new position
NEXT move

END
You could create more complex animation with several slightly different image strings. For example if you had images of a dog with its legs in different positions, you could save each as a separate image. You could then have the dog walk across the screen by showing and clearing each image in rapid sequence.

You can store BOX KEEP images in byte files for use by other programs. For example, you could write the
arrow$ image to a file as follows:
Graphics

145

OPEN #8: name “arrow.tru”, org byte, create newold
ERASE #8 ! Be sure file is empty
WRITE #8: arrow$ CLOSE #8
Another program could then read and display that image as follows:
OPEN #4: name “arrow.tru”, org byte
ASK #4: FILESIZE fs ! Find number of bytes in file
READ #4, BYTES fs: image$ ! Read entire file
CLOSE #4
BOX SHOW image$ AT 0,.5
For more information on byte files, see Chapter 12 “Files for Data Input and Output.”

BOX SHOW USING Effects
The BOX SHOW statement may also take the following extended form:
BOX SHOW image$ AT x, y USING option

where option may be any value from 0 to 15, inclusive. Each value of option produces a different result in displaying the designated image. The nature of this result depends both on the contents of the image string being displayed and the current contents of the rectangular region on the screen. These options can produce reverse images and spectacular color effects.

The following table summarizes the 16 available options, which are explained below. The first column shows the option, and the others show the resulting bit-value, depending on the bit in image$ and the corresponding bit currently displayed on the screen.

Numeric BOX SHOW Options
——————————————————————————————————————
Bit in BOX SHOW string: 0 0 1 1
Bit on screen: 0 1 0 1
————————————————————————————————
0 0 0 0 0
1 (AND) 0 0 0 1
2 0 0 1 0
U 3 0 0 1 1
S 4 0 1 0 0
I 5 0 1 0 1
N 6 (XOR) 0 1 1 0
G 7 (OR) 0 1 1 1
8 1 0 0 0
C 9 1 0 0 1
O 10 1 0 1 0
D 11 1 0 1 1
E 12 1 1 0 0
13 1 1 0 1
14 1 1 1 0
15 1 1 1 1
——————————————————————————————————————
Three of these options represent common logical operations and have names. You can use AND instead of 1, OR
instead of 7, and XOR instead of 6.

The interpretation is simplest if only one color is available and therefore the “color” of a pixel is represented by one bit, 0 or 1, off or on. Under the AND option, a bit is 1 if it is 1 in image$ and also 1 on the screen. The common
146 True BASIC Language System

part of the two images is displayed. Under the OR option a bit is 1 if either bit was 1, therefore a combination of the two images is displayed. The XOR (exclusive or) option equals 1 if image$ or the screen had a 1 in this position, but not both; it produces a combination of the non-overlapping regions of the images.

USING 3 is equivalent to a BOX SHOW statement without any option (i.e. the BOX SHOW string bit takes prece- dence over what was on the screen), while USING 0 is the same as BOX CLEAR. USING 12 ignores the screen but displays a reverse image of the show string. For example, if it was black-on-white, it is shown white-on-black.

If more than one color is available, the color value of each pixel is coded by more than one bit. The options still apply, combining corresponding bits of the color codes. Working out the effect of each option is trickier. For exam- ple, if there are 16 colors, a four-bit code is used. Say that image$ has color five for one pixel (coded 0101) while the screen has color six (0110). Then the AND option produces color four (0100), the OR option produces color seven (0111), the XOR option produces color three (0011), and option 12 produces color ten (1010). Some experimentation with the options is recommended when working with colors.

Using Pictures
True BASIC provides special subroutines for graphics, called pictures. For instance, if you want to create several hexagons, you could define a picture and simply draw that picture when needed rather than repeat the PLOT statements each time. Pictures are more flexible than either subroutines or BOX KEEP images because you can transform them geometrically. When you draw a picture you can rotate it, change its scale, tilt it, or move it any- where on the screen.

PICTURE structures are defined just like subroutines, except that they begin with a PICTURE keyword and end with an END PICTURE statement. A picture has a name, may have parameters, may be internal or external, and may be placed in a library file.

A simple example is a picture that draws axes for the current logical window:
PICTURE Axes
ASK WINDOW left, right, bottom, top ! Find user-coordinate range
PLOT left,0; right,0 ! x-axis
PLOT 0,bottom; 0,top ! y-axis
END PICTURE
You invoke a picture with a DRAW statement:
DRAW Axes
The EXIT PICTURE statement corresponds to the EXIT SUB statement and immediately returns control to the line following the DRAW statement.
Pictures may include most valid True BASIC statements, including DRAW statements to invoke other pictures. However, a picture cannot open a logical window or set user coordinates — this must be done in the invoking pro- gram. Pictures can use WINDOW statements to switch to existing windows, and you can pass channel numbers to pictures as parameters.
Here’s a picture that uses a parameter to draw a regular polygon with s sides inscribed in a unit circle. The poly- gon is centered about the point (0,0).
PICTURE Polygon(s) ! Polygon of s sides
OPTION ANGLE DEGREES ! Use degrees instead of radians
FOR i = 0 to s ! Run through vertices
LET a = 360*i/s ! Angle
PLOT Cos(a), Sin(a); NEXT i
PLOT
END PICTURE
The parameter s indicates the number of sides. If the above picture is in a library file, the main program could use:
SET WINDOW -1, 1, -1, 1
Graphics

147

FOR n = 3 to 9 step 2
SET COLOR n
DRAW Polygon(n) NEXT n
to draw odd-sided polygons with three to nine sides, each in a different color.

Output of the Ploygon Picture
——————————————————————————————————————

——————————————————————————————————————

Transformations
The important difference between subroutines and pictures is that you can transform pictures when you invoke them. Transformations are options applied to the picture to change its appearance. True BASIC’s built-in trans- formations let you resize, move, tilt, and rotate pictures.

For example, the statement:
DRAW Polygon(4) with Rotate(pi/4) * Shift(1,2)
uses the polygon picture defined above to draw a rotated square (or rectangle) that is centered about the point (1,2). First the DRAW statement constructs a square centered on the origin as defined by the picture. Before it draws the image, however, it applies the transformations to rotate the square counterclockwise by an angle of Pi/4 (45 degrees) around the origin and then shift the rotated square one unit horizontally and two units vertically, so that its center is at (1, 2).
——————————————–––—————————————————————————
[ ! ] Note: While the external picture uses degrees, its OPTION ANGLE statement has no effect on the
main program. Unless otherwise specified, the main program measures in radians. See Chapter 8 “Built-
in Functions” for information on specifying degrees or radians with the OPTION ANGLE statement.
————————————————–––——————————————————————— Multiple transformations — which must be separated by an asterisk — are applied from left to right. Thus, the square above is rotated before it is shifted. Pictures are always rotated about the origin (0,0) which happens to be the square’s center. Thus, the square remains centered on the origin until it is shifted. Had the square been shifted first, the result would have been different. The shift would move the center of the square to (1, 2). Then, rotation about the origin would move the square away from its shifted position (as if it were riding on the hand of a clock moving backwards).
148 True BASIC Language System

Effects of Multiple Transformations
——————————————————————————————————————
DRAW polygon(4) DRAW polygon(4) with DRAW polygon(4) with
Rotate(pi/4) * Shift(1,2) Shift(1,2) * Rotate(pi/4)

——————————————————————————————————————

True BASIC defines four transformations that you can use with pictures:
Picture Transformations
——————————————————————————————————————
Transformation Effect
SHIFT(a,b) Move by a horizontally and by b vertically
SCALE(a,b) Change scale, multiplying horizontal coordinates by a, and vertical coordinates by b; if a = b, then you may specify SCALE(a)
ROTATE(t) Rotate around origin counterclockwise by an angle t
SHEAR(t) Lean vertical lines forward (clockwise) by an angle t
——————————————————————————————————————
In the SHIFT and SCALE transformations, all calculations use user coordinates. In the ROTATE and SHEAR transformations, angles are normally measured in radians, but you may change that with an OPTION ANGLE statement.

—————————–––——————————————————————————————
[ ! ] Note: Transformations are applied only to the various forms of the PLOT statement within a picture;
they are not applied to BOX statements.
—————————————————————–––——————————————————
As mentioned above, a picture may include DRAW statements to call other pictures. For example, a picture that draws a house may repeatedly call a picture that draws a window applying different transformations each time to place different-sized windows in various locations. The main program, in turn, might apply a transformation to the house picture. Any transformation applied to the house picture will also affect the window pictures it invokes, maintaining the integrity of the house as a whole. For example you could build a neighborhood of houses by scal- ing and shifting the houses. For an illustration of this, see the HOUSES.TRU program in the TBDEMOS direc- tory installed with True BASIC.

Constructing Your Own Transformations
This section gives technical details on how transformations work and shows how you can construct additional transformations.
Transformations may be represented by a four-by-four matrix. For example:

æ 1 0 0 0 ö ç 0 1 0 0 ÷
Shift (3,5) = ç 0 0 1 0 ÷
è 3 5 0 1 ø
Graphics

149

When this transformation is applied to a picture, each plotted point (x, y) is represented by the four-element vector (x, y, 0, 1), which is multiplied on the right by the transformation matrix. The shift yields the result (x + 3, y + 5, 0, 1) and the point is changed into (x + 3, y + 5). With repeated transformations, several multiplications are carried out. Thus, the asterisk separating transformations actually represents matrix multiplication.
True BASIC will accept any four-by-four matrix as a transformation. Thus, you may define your own transforma- tion as a four-by-four matrix and use this matrix as a transformation. For example, you may introduce a reflection around a 45 degree line:
DIM Reflect(4,4) ! Reflection transformation
MAT READ Reflect
DATA 0, 1, 0, 0
DATA 1, 0, 0, 0
DATA 0, 0, 1, 0
DATA 0, 0, 0, 1

DRAW Polygon(5) with Reflect ! Pentagon reflected
The third and fourth components of (x, y, 0, 1) are currently not used.

Graphical Input
True BASIC provides two simple methods for obtaining graphical input — the GET MOUSE and GET POINT
statements.
The GET MOUSE statement returns the current position of the mouse pointer and the state of the leftmost mouse button. The GET POINT statement, on the other hand, pauses the program and waits for the user to press the left mouse button; it then returns the position at which the click occurred. Both statements return the position of the mouse pointer in the user coordinates of the current logical window. The mouse pointer must be within the cur- rent physical window, but it need not be in the current logical window. Points outside the logical window are returned in appropriate user coordinates as if the coordinate range were extended beyond the window. As usual, however, any lines or points drawn to coordinates outside the user-coordinate range will be clipped at the window edge and not shown.
The following program uses the GET POINT statement to draw a figure connecting points selected by the user:
DO
GET POINT x,y
PLOT x,y;
IF key input then GET KEY k
LOOP UNTIL k = 27 ! Use escape key to exit
END
There is no special prompt to indicate the program is waiting for GET POINT input. You may therefore wish to print instructions to the user before using GET POINT.

The GET MOUSE statement requires three numeric variables:
GET MOUSE x, y, s
The current position of the mouse pointer is returned in x and y and the status of the left mouse button in s. The possible values for s are:

0 No button down
1 Button is down
2 Button clicked at this point
3 Button released at this point
4 Button shift-clicked at this point
150 True BASIC Language System

Thus, the above example could use the GET MOUSE statement as follows:
DO
GET MOUSE x, y, s
IF s = 2 then PLOT x,y;
IF key input then GET KEY k
LOOP UNTIL k = 27 ! Use escape key to exit
END
Note, that omitting the IF test before the PLOT statement produces a program that draws a curve following every movement of your mouse (as if s = 0).

————————————————————–––———————————————————
[ ! ] Note: The TC_Event routine, described in Chapter 14 “Interface Elements,” provides more sophisti-
cated mouse-handling capabilities. The GET MOUSE and GET POINT statements are primarily for
compatibility with earlier versions of True BASIC, and for simpler programs.
————————————————————–––———————————————————

Drawing Charts and Graphs
There are certain graphing tasks that many programmers face fairly often. For some of these common tasks, True
BASIC includes subroutines that simplify the display of a wide array of charts and graphs.

These routines are not built into the language, but rather are stored in separate library files (see Chapter 11 “Libraries and Modules”). Thus, you must name the library file in a LIBRARY statement before you can invoke the subroutines.

The charting and graphing routines are in the library files:

BGLib.TRC for pie charts, bar charts, and histograms SGLib.TRC for plotting data and function values SGFunc.TRC for plotting values of functions that you define
which are stored in the TBLIBS subdirectory when you install True BASIC. Remember that the LIBRARY state- ments must use the appropriate “path name” to indicate the location of the library files for the computer you will use to run your program; see “The True BASIC Environment” chapter in the introductory section for information on the correct formats.

See Chapter 23 “Additional Library Routines” for descriptions of the subroutines in these libraries.
151