Something that occurs completely "behind the scenes" in your computer when drawing is a process called clipping. Clipping is the process whereby lines that extend over the defined edges of the drawing surface are cut off at those edges. There are two different clipping boundaries at all times: the soft clip limits and the hard clip limits. The hard clip limits are the absolute boundaries of the plotting surface; the pen cannot go outside these limits. The soft clip limits are user-definable limits, and are defined by the CLIP statement.
CLIP 10,20.5,Ymin,Ymax
This statement defines the soft clip boundaries only; hard clip limits are
completely unaffected. After this statement has been executed, all lines
which attempt to go outside the X limits (in UDUs) of 10 and 20.5, or the
Y limits (in UDUs) of Ymin
and
Ymax
will be truncated at the appropriate edge. Clipping
at the soft clip limits can be turned off by the statement:
CLIP OFF
and it can be turned back on, using the same limits, by
CLIP ON
If you want the soft clip limits to be somewhere else, use the CLIP statement with four different limits. Only one set of soft clip limits can be in effect at any one time. Clipping at the hard clip limits cannot be disabled.
The VIEWPORT statement, in addition to defining how WINDOW coordinates map into the VIEWPORT area, turns on clipping at the specified VIEWPORT edges.
On a monochromatic CRT, three different drawing modes are available. (For selecting pens with a color CRT, see "Color Graphics".) The three pens perform the following actions:
Pen Number | Function |
---|---|
1 | Draws lines (turns on pixels) |
-1 | Erases lines (turns off pixels) |
0 | Complements lines (changes pixels' states) |
A characteristic of drawing with pen -1 or pen 1 is that if a line crosses a previously drawn line, the intersection will be the same "color" as the lines themselves. When drawing with pen 0, and a line crosses a previously-drawn line, the intersection becomes the opposite state of the lines.
This concept is illustrated by the following program. However, since it is
a dynamic display, no figure is given. Line 150 of the program defines the
type of operation the program will exhibit. If Pen
equals
zero, all lines will complement, because lines 610 and 680 select pen -0
and +0, which are identical. When you wish to change the program to drawing
and erasing mode, change line 150 to say Pen=1
. Then
lines 610 and 680 will select pens -1 and +1, respectively. (Run the example
program in file Pen
.)
100 CLEAR SCREEN ! Clear the alpha display
110 INTEGER Polygon,Polygons,Side,Sides,Pen ! Make loops faster
120 Polygons=20 ! How many polygons?
130 Sides=3 ! How many sides apiece?
140 Pen=0 ! 1: Draw/erase; 0: Complement
150 ALLOCATE INTEGER X(0:Polygons-1,1:Sides),Y(0:Polygons-1,1:Sides)
160 ALLOCATE INTEGER Dx(Sides),Dy(Sides)
170 RANDOMIZE ! Different each time
180 GINIT ! Initialize graphics parameters
190 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
200 GRAPHICS ON ! Turn on graphics screen
210 WINDOW 0,511,0,389 ! Integer arithmetic is faster
220 PEN Pen ! Select appropriate pen
230 FOR Side=1 TO Sides ! For each vertex...
240 X(0,Side)=RND*512 ! ...define a starting point...
250 Y(0,Side)=RND*390 ! ...for both X and Y...
260 PLOT X(0,Side),Y(0,Side) ! ...then draw to that point.
270 NEXT Side ! et cetera
280 IF Sides>2 THEN PLOT X(0,1),Y(0,1) ! If simple line, don't close
290 GOSUB Define_deltas ! Get dx and dy for each vertex
300 FOR Polygon=1 TO Polygons-1 ! Draw all the polygons
310 PENUP ! Don't connect polygons
320 FOR Side=1 TO Sides ! Each vertex of each polygon
330 Temp=X(Polygon-1,Side)+Dx(Side) ! Avoid recalculation
340 IF Temp>511 THEN ! \
350 Dx(Side)=-Dx(Side) ! \
360 ELSE ! (it's not off right side) ! > Is X out of range?
370 IF Temp<0 THEN Dx(Side)=-Dx(Side)! /
380 END IF ! (off right side?) ! /
390 X(Polygon,Side)=X(Polygon-1,Side)+Dx(Side) ! Calculate next X
400 Temp=Y(Polygon-1,Side)+Dy(Side) ! Avoid recalculation
410 IF Temp>389 THEN ! \
420 Dy(Side)=-Dy(Side) ! \
430 ELSE ! (it's not off top) ! > Is Y out of range?
440 IF Temp<0 THEN Dy(Side)=-Dy(Side)! /
450 END IF ! (off the top?) ! /
460 Y(Polygon,Side)=Y(Polygon-1,Side)+Dy(Side) ! Calculate new Y
470 PLOT X(Polygon,Side),Y(Polygon,Side)! Draw line to new point
480 NEXT Side ! Loop for next side of polygon
490 IF Sides>2 THEN PLOT X(Polygon,1),Y(Polygon,1)! If line, don't close
500 NEXT Polygon ! Get each polygon
510 New=0 ! Start re-use at entry 0
520 ON CYCLE 10 GOSUB Define_deltas ! Change deltas periodically
530 LOOP ! Ad infinitum...
540 IF New=0 THEN ! Boundary condition?
550 Previous=Polygons-1 ! Start re-using over
560 ELSE ! (new>0)
570 Previous=(Previous+1) MOD Polygons ! Re-use next entry
580 END IF ! (new=0?)
590 PENUP ! Don't connect polygons
600 PEN -Pen ! This works either way for Pen
610 DISABLE ! Don't interrupt in "Side" loop
620 FOR Side=1 TO Sides ! \
630 PLOT X(New,Side),Y(New,Side) ! \
640 NEXT Side ! > Erase oldest line
650 IF Sides>2 THEN PLOT X(New,1),Y(New,1)! /
660 PENUP ! /
670 PEN Pen ! Drawing pen
680 FOR Side=1 TO Sides ! \
690 Temp=X(Previous,Side)+Dx(Side) ! \
700 IF Temp>511 THEN ! \
710 Dx(Side)=-Dx(Side) ! \
720 ELSE ! \
730 IF Temp<0 THEN Dx(Side)=-Dx(Side)! \
740 END IF ! \
750 X(New,Side)=X(Previous,Side)+Dx(Side) ! \
760 Temp=Y(Previous,Side)+Dy(Side) ! \ Draw the new line
770 IF Temp>389 THEN ! / same way as before.
780 Dy(Side)=-Dy(Side) ! /
790 ELSE ! /
800 IF Temp<0 THEN Dy(Side)=-Dy(Side)! /
810 END IF ! /
820 Y(New,Side)=Y(Previous,Side)+Dy(Side) ! /
830 PLOT X(New,Side),Y(New,Side) ! /
840 NEXT Side ! /
850 IF Sides>2 THEN PLOT X(New,1),Y(New,1)! /
860 ENABLE ! Interrupts OK again
870 New=(New+1) MOD Polygons ! Next one to re-use.
880 END LOOP ! End of infinite loop
890 Define_deltas: ! --------------------------------------------------
900 FOR Side=1 TO Sides ! For each vertex
910 Dx(Side)=RND*3+2 ! Magnitude of this dx
920 IF RND<.5 THEN Dx(Side)=-Dx(Side) ! Sign of this dx
930 Dy(Side)=RND*3+2 ! Magnitude of this dy
940 IF RND<.5 THEN Dy(Side)=-Dy(Side) ! Sign of this dy
950 NEXT Side ! et cetera
960 RETURN ! back to the main program
970 END
When running the program in complementing mode, observe that a pixel is on only if it has been acted upon by an odd number of line segments.
When a graph attempts to convey several different kinds of information, colors
are often used: The red curve signifies one thing, the blue curve signifies
another thing, and so on. But when only one color is available, as on a
monochromatic CRT, this method cannot be used. Something that can
be used, however, is different line types. There are ten line types available:
As you can see, LINE TYPE 1 draws a solid line. LINE TYPE 2 draws only the end points of the lines and is the same as moving to a new point, dropping the pen, lifting the pen, and repeating. LINE TYPEs 3 through 8 are patterned sequences of on and off. With these, the length of each pattern; i.e, the distance the line extends before the on/off pattern begins to repeat, can be specified by supplying a second parameter in the LINE TYPE statement. This second parameter specifies distance in GDUs.
For example,
LINE TYPE 5,15
tells the computer to start using a simple dashed line, and to proceed a total of 15 GDUs before starting the pattern over. On the CRT, the repeat length will be rounded to a multiple of five, with a minimum value of five.
LINE TYPEs 9 and 10 are solid lines with a minor and major tick mark at the end of each line, respectively. The tick mark will be either horizontal or vertical. The orientation of the tick marks will be whatever is farther from the angle of the line just drawn. For example, if you draw a line at a 30° angle, it is closer to being horizontal than it is to being vertical. Thus, the tick mark at the end of the line will be vertical. The value for major tick size is 2 GDUs, and minor tick length is one half the major tick length.
For all line types, the computer remembers where in the pattern a line segment ended (except for BASIC/UX 700, which does not remember). Therefore, when you start drawing another line segment, the line pattern will continue from where it left off. If you want the pattern to start over, just re-execute the LINE TYPE statement.
If a picture on the screen takes a long time to draw, or the image is used
often, it may be advisable to store the image itself--not the commands
used to draw the image--in memory or on a file. This can be done with the
GSTORE command. First, you must have an INTEGER array of sufficient size
to hold all the data in the graphics raster. The array size varies depending
on what computer system you have in general and what monitor you have in
particular. A formula for calculating array size is:
( [ X pixels * Y pixels ] / 16) * number of bits per pixel
A monochromatic display has 1 bit per pixel. The Model 236C color computer has 4 bits per pixel. The Series 300/400/700 color monitors have up to 32 bits per pixel. But rather than getting intimately involved with screen resolution and the number of bits per pixel, there is a shortcut. The fifth and sixth elements of the integer array passed back by GESCAPE operation selector 3 specify the number of rows and columns an integer array must have to contain the entire graphics image.
For example:
...
100 GINIT
110 INTEGER A(1:6)
120 GESCAPE CRT,3;A(*)
130 PRINT "Rows required for array: ";A(5)
140 PRINT "Columns required for array: ";A(6)
150 ALLOCATE INTEGER Gscreen(A(5),A(6))
160 GSTORE Gscreen(*)
170 END
...
The array Gscreen
is allocated the size specified by
the "rows" and "columns" numbers from the GESCAPE return array. This array
holds the picture itself and doesn't care how the information got to the
screen, or in what order the different parts of the picture were produced.
In the Gstore
program, the image is drawn with normal
plotting commands, and then, after the fact, the image is read from
the graphics area in memory, and placed into the array. After the array is
filled by the GSTORE, a curve is plotted on top of the image already there.
Then, turning the knob changes the value of a parameter, and a different
curve results, but we do not have to replot the grid, axes and labels.
We merely need to GLOAD the image (which has everything but the curve and
the current parameter value). This allows the curve to be inspected almost
in real time. (Run the example program in file
Gstore
.)
Often, data points do not form a continuous line. In those cases you need to control the position of the pen so that many lines (instead of one continuous line) get plotted from one set of data. Use the pen-control parameter a third parameter in the PLOT statement to raise or lower the pen as described below.
When using a single X-position and Y-position in a PLOT statement (as opposed to plotting an entire array), the third parameter is defined in the following manner. Though it need not be of type INTEGER, its value should be an integer. If it is not, it will be rounded. The third parameter is either positive or negative, and at the same time, either even or odd. The evenness/oddness of the number determines which action will be performed on the pen, and the sign of the number determines when that action will be performed: before or after the pen is moved.
Even (Up) | Odd (Down) | |
---|---|---|
Positive (After) | Pen up after move | Pen down after move |
Negative (Before) | Pen up before move | Pen down before move |
The default parameter is +1--positive odd--therefore, the pen will drop after moving, and if the pen is already down, it will remain down, drawing a line. Indeed, this is what happened in the first example in the section "Why Graphics?". (Zero is considered positive.)
Following is a program which uses pen control. It draws a LEM (Lunar Excursion
Module). In particular, see how the PLOT statement was used with an array
specifier. Notice that the X and Y values are in the same array as the
pen-control parameters. (Run the example program in file
Lem1
.)
100 CLEAR SCREEN ! Clear the alpha display
110 OPTION BASE 1 ! Arrays start at one
120 DIM Lem(33,3) ! Data and pen-control array
130 READ Lem(*) ! Define the LEM data
140 GINIT ! Initialize various graphics parameters
150 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
160 SHOW -10,10,-10,10 ! Isotropic scaling
170 GRAPHICS ON ! Turn on the graphics screen
180 AREA INTENSITY .125,.125,.125 ! 12.5% gray
190 PLOT Lem(*) ! Plot the data
200 Lem:! X Y Pen | X Y Pen | X Y Pen | X Y Pen
210 DATA 0, 0, 11 ! Start of polygon with FILL and EDGE
220 DATA 1.5, 1, -2, 2.5, 2, -1, 2.5, 3, -1, 1.5, 4, -1 ! Octagon
230 DATA -1.5, 4, -1, -2.5, 3, -1, -2.5, 2, -1, -1.5, 1, -1
240 DATA 0, 0, 7 ! End of first polygon
250 DATA 0, 0, 6 ! Start of polygon with FILL
260 DATA -2.5, 1, -2, 2.5, 1, -1, 2.5, -2, -1, -2.5, -2, -1 ! Box
270 DATA -2.5, 1, -1
280 DATA 0, 0, 7 ! End of second polygon
290 DATA -2.5, -2, -2, -4.5, -4, -1, -2.5, 0, -1, -5, -4, -2 ! Left Leg
300 DATA -4, -4, -1
310 DATA 2.5, -2, -2, 4.5, -4, -1, 2.5, 0, -1, 5, -4, -2 ! Rt. leg
320 DATA 4, -4, -1
330 DATA 0, 0, 10 ! Start of polygon with EDGE
340 DATA -0.5, -2, -2, -1, -3, -1, 1, -3, -1, 0.5, -2, -1 ! Nozzle
350 DATA 0, 0, 7 ! End of third polygon
360 END
Having the pen-control parameter in a third column of the data array is generally a good strategy; it reduces the number of array names you must declare, and when you have the data points for the picture, you also have the information necessary to draw it. Nevertheless, an array must be entirely of one type, and usually you'll want the data to be REAL. If you're pressed for memory, INTEGER numbers take only one-fourth the memory REAL numbers take to store.
PLOT can plot an entire array in one statement, but you must have just one array holding both the data and pen-control parameters. That is, you cannot have the data in a two-column REAL array and the pen-control parameters in a one-column INTEGER array, unless you are plotting one point at a time, as above. The array plotted must be a single two-column or three-column array. If it is a two-column array, the pen-control parameter is assumed to be +1 for every point (pen down after move). If you have a third column in the array, the array columns are interpreted in these ways:
Column 1 | Column 2 | Operation\Selector | Meaning |
---|---|---|---|
X | Y | -2 | Pen up before moving |
X | Y | -1 | Pen down before moving |
X | Y | 0 | Pen up after moving (Same as +2) |
X | Y | 1 | Pen down after moving |
X | Y | 2 | Pen up after moving |
pen number | ignored | 3 | Select pen |
line type | repeat value | 4 | Select line type |
color | ignored | 5 | Color value |
ignored | ignored | 6 | Start polygon mode with FILL |
ignored | ignored | 7 | End polygon mode |
ignored | ignored | 8 | End of data for array |
ignored | ignored | 9 | NOP (no operation) |
ignored | ignored | 10 | Start polygon mode with EDGE |
ignored | ignored | 11 | Start polygon with FILL and EDGE |
ignored | ignored | 12 | Draw a FRAME |
pen number | ignored | 13 | Area pen value |
red value | green value | 14 | Color |
blue value | ignored | 15 | Value |
ignored | ignored | >15 | Ignored |
For a detailed description of these parameters, see IPLOT, PLOT, RPLOT, or SYMBOL in the HP BASIC Language Reference manual.
AREA INTENSITY lets you get 17 shades of gray on a black-and-white CRT with an electron gun that is either fully on or completely off. This is done through a process called dithering. Dithering is accomplished by selecting small groups of pixels--a 4×4 square of them on the HP 9000 Series computers. Various pixels in the dithering box are turned on and off to arrive at an "average" shade of gray. You can have none of them on, one of them on, two of them on, and so forth, up to all sixteen of them on. it makes no difference which pixels are on; they are chosen to minimize the striped or polka-dotted pattern inherent to a dithered image.
For more detail on AREA INTENSITY and other color-related statements, see "Color Graphics."
Often, a segment of a drawing must be replicated in many places. It is possible, but rather tedious to do using the PLOT statement. Another statement called RPLOT, draws a figure relative to a point of your choice. RPLOT means Relative PLOT, and it causes a figure to be drawn relative to a previously chosen reference point. RPLOT's parameters may be two or three scalars, or a two-column or three-column array; the parameters are identical to those of PLOT.
The picture defined by the data given to an RPLOT statement is drawn relative to a point called the current relative origin. This is not necessarily the same as the pen position. The current relative origin is the last point resulting from any one of the following statements:
AXES DRAW FRAME GINIT GRID
IDRAW IMOVE IPLOT LABEL MOVE
PLOT POLYGON POLYLINE RECTANGLE
Typically, a MOVE is used to position the current relative origin at the desired location, then the RPLOT is executed to draw the figure. After the RPLOT statement has executed, the pen may be in a different place, but the current relative origin has not moved. Thus, executing two identical RPLOT statements, one immediately after the other, results in the figure being drawn precisely on top of itself.
A figure drawn with RPLOT can be rotated by using the PIVOT or PDIR statement before the RPLOT. The single parameter for a PIVOT or PDIR is a numeric expression designating the angular distance through which the figure is to be rotated when drawn. This value is interpreted according to the current angular mode: either DEG or RAD.
Here is a program using an RPLOT. Various figures are defined with DATA
statements: a desk, a chair, a table, and a bookshelf. The program displays
a floor layout. Here again, the "end polygon mode" codes (the
0,0,7
s in the desk and chair definitions) are unnecessary;
when a polygon mode starts, any previous one ends by necessity. (Run the
example program in file Rplot
.)
100 CLEAR SCREEN ! Clear the alpha display
110 OPTION BASE 1 ! Make arrays start at one
120 DIM Room(10,3),Desk(18,3),Chair(14,3),Bookshelf(4,3),Table(4,3)
130 READ Room(*),Desk(*),Chair(*),Bookshelf(*),Table(*)
140 GINIT ! Initialize graphics parameters
150 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
160 GRAPHICS ON ! Display the graphics screen
170 SHOW 0,120,-10,100 ! Need isotropic units for a map
180 PLOT Room(*) ! Draw outline of room
190 DEG ! Set degrees mode for angles
200 READ Object$ ! What to draw?
210 WHILE Object$<>"***STOP***" ! Until done...
220 READ X,Y,Angle ! Read where and at what angle
230 MOVE X,Y ! Move in unrotated coordinates
240 PIVOT Angle ! Set rotation for RPLOTs
250 SELECT Object$
260 CASE "Desk"
270 AREA INTENSITY .125,.125,.125 ! 87.5% gray: dark gray
280 RPLOT Desk(*)
290 CASE "Chair"
300 AREA INTENSITY .5,.5,.5 ! 50% gray: half-and-half
310 RPLOT Chair(*)
320 CASE "Bookshelf"
330 RPLOT Bookshelf(*),EDGE
340 CASE "Table"
350 AREA INTENSITY 0,0,0 ! 100% gray scale: Black
360 RPLOT Table(*),FILL,EDGE
370 END SELECT
380 READ Object$
390 END WHILE
400 Room: DATA 0,60,-2, 0,100,-1, 120,100,-1, 120,30,-1
410 DATA 120,20,-2, 120,0,-1, 40,0,-1, 40,25,-1
420 DATA 0,25,-1, 0,50,-1
430 Desk: DATA 0,0,11, 0,0,-2, 20,0,-1, 20,-10,-1, 0,-10,-1, 0,0,7
440 DATA 0,0,10, 2,-10,-2, 2,-10.5,-1, 3,-10.5,-1, 3,-10,-1, 0,0,7
450 DATA 0,0,10, 17,-10,-2, 17,-10.5,-1, 18,-10.5,-1,18,-10,-1, 0,0,7
460 Chair: DATA 0,0,11, -3,9,-2, 3,9,-1, 4,8,-1, 3,2,-1
470 DATA -3,2,-1, -4,8,-1, 0,0,7
480 DATA 0,0,10, -4,1,-2, 4,1,-1, 4,0,-1, -4,0,-1, 0,0,7
490 Bookshelf:DATA 0,0,-2, 20,0,-1, 20,-4,-1, 0,-4,-1
500 Table: DATA 0,0,-2, 25,0,-1, 25,-12,-1, 0,-12,-1
510 Objects: DATA Chair, 14,75,90 ! \
520 DATA Desk, 1,65,90 ! > Upper left corner of room
530 DATA Table, 1,99,0 ! /
540 DATA Bookshelf,27,99,0 !/
550 DATA Chair, 66,44,30 ! \
560 DATA Desk, 50,50,30 ! > Center of the room
570 DATA Chair, 45,65,210 ! /
580 DATA Desk, 60,58,210 !/
590 DATA Bookshelf,41,5,0 !\
600 DATA Bookshelf,62,5,0 ! > Bottom center of room
610 DATA Bookshelf,83,5,0 !/
620 DATA Chair, 6,26,0 !\
630 DATA Chair, 16,26,0 ! \
640 DATA Chair, 26,26,0 ! > Four chairs by west door
650 DATA Chair, 36,26,0 ! /
660 DATA Chair, 63,96,220 ! \
670 DATA Chair, 85,83,3 ! > Four chairs by northeast tables
680 DATA Chair, 112,83,0 ! /
690 DATA Chair, 100,83,355 !/
700 DATA Table, 68,99,0 ! \
710 DATA Table, 94,99,0 ! > Two tables in upper right
720 DATA Chair, 105,50,270 ! \
730 DATA Desk, 119,60,270 ! > Desk and chair by east door
740 DATA ***STOP***
750 END
Notice that you can specify the EDGE and/or FILL parameters in the RPLOT statement itself, in addition to in the array. (FILLs and EDGEs are specified in the array by having a 6, a 10, or an 11 in the third column of the array.) If FILL and/or EDGE are specified both in the PLOT statement and in the data, and the instructions differ, the value in the data replaces FILL or EDGE on the statement.
Also notice that some of the chairs appear to be under the desks and tables; that is, parts of several chairs are hidden by other pieces of furniture. This is accomplished by drawing the chair, and then drawing the desk or table partially over the chair, and filling the desktop or tabletop with its own fill pattern, which may be black.
Incremental plotting is similar to relative plotting, except that the origin--the point considered to be 0,0--is moved every point. Every time you move or draw to a point, the origin is immediately moved to the new point, so the next move or draw will be with respect to that new origin.
There are three incremental plotting statements available: IPLOT, which has the same parameters as PLOT and RPLOT; and IMOVE and IDRAW, which have the same parameters as MOVE and DRAW, respectively.
Below is an example program using IPLOTs. It reads data from statements
describing the outlines of certain letters of the alphabet, and then plots
them. (Run the example program in file Iplot
.)
100 CLEAR SCREEN ! Clear the alpha display
110 OPTION BASE 1 ! Make the arrays start at 1
120 DIM Array(20,3) ! Set aside space for the array
130 GINIT ! Initialize various graphics parameters
140 PLOTTER IS CRT,"INTERNAL" ! Use the internal screen
150 GRAPHICS ON ! Turn on graphics screen
160 SHOW 1,35,-15,15 ! Isotropic scaling
170 FOR Letter=1 TO 4 ! Four letters total
180 READ Points ! How many points in this letter?
190 REDIM Array(Points,3) ! Adjust the array size accordingly
200 READ Array(*) ! Read the correct number of points
210 MOVE Letter*6,0 ! Move to lower-left corner of letter
220 IPLOT Array(*) ! Draw letter
230 NEXT Letter ! et cetera
240 F: DATA 10, 0,5,-1, 5,0,-1, 0,-1,-1, -4,0,-1, 0,-1,-1
250 DATA 3,0,-1, 0,-1,-1, -3,0,-1, 0,-2,-1, -1,0,-1
260 L: DATA 6, 0,5,-1, 1,0,-1, 0,-4,-1, 4,0,-1, 0,-1,-1
270 DATA -5,0,-1
280 A: DATA 12, 2,5,-1, 1,0,-1, 2,-5,-1, -1,0,-1, -.4,1,-1
290 DATA -2.2,0,-1, -.4,-1,-1, -1,0,-1, 1.8,2,-2, .7,2,-1
300 DATA .7,-2,-1, -1.4,0,-1
310 X: DATA 12, 1.9,2.5,-1, -1.9,2.5,-1, 1,0,-1, 1.5,-2,-1, 1.5,2,-1
320 DATA 1,0,-1, -1.9,-2.5,-1,1.9,-2.5,-1, -1,0,-1, -1.5,2,-1
330 DATA -1.5,-2,-1, -1,0,-1
340 END
When you want a regular polygon, or a part of one, drawn on the screen, two statements will help. The first is called POLYGON. These statements are used when defining the radius and the number of sides is suffient to define the shape desired.
One attribute of POLYGON is that it forces polygon closure; that is, the first vertex is connected to the last vertex, so there is always an inside and an outside area. This is true even when drawing only one side of a polygon, in which case a "single" line results. This is actually two lines, from the first point to the last point, and back to the first.
There are two final keywords which may be included in a POLYGON statement: FILL causes the interior of the polygon or polygon segment to be filled with the current fill color as defined by AREA PEN, AREA COLOR, or AREA INTENSITY. FILL specified without EDGE causes the interior of the polygon to be indistinguishable from the edge. EDGE causes the edges of the polygon go be drawn using the current pen and line type. If both FILL and EDGE are specified (and FILL must be first), the interior will be filled, then the edge will be drawn. If neither FILL nor EDGE is specified, EDGE is assumed. On an HPGL plotter, only EDGE works.
Polygons can be rotated by specifying a non-zero value in a PIVOT or PDIR statement before the POLYGON statement is executed. Also, a PDIR statement can be used to specify the angle of rotation. PDIR works with IPLOT, RPLOT, POLYLINE, POLYGON, and RECTANGLE. The rotation occurs about the origin of the figure. For example, PDIR 15 would rotate a figure 15 units (degrees, radians).
The shape of the polygon is affected by the viewing transformation specified by SHOW or WINDOW. Therefore, anisotropic scaling causes the polygon to be stretched or compressed along the X and Y axes.
Pen status also affects the way a POLYGON statement works. If the pen is up at the time POLYGON is specified, the first vertex specified is connected to the last vertex specified, not including the center of the polygon, which is the current pen position. If the pen is down, however, the center of the polygon is also included in it. Thus, for piece-of-pie shaped polygon segments, like those in pie charts, cause the pen to be down before the POLYGON statement is executed. After POLYGON has executed, the current pen position is in the same position it was before the statement was executed, and the pen is up.
Another statement, POLYLINE, acts much the same way as POLYGON, except it does not connect the last vertex to the first vertex; it does not close the polygon. Since there is no "inside" or "outside," it is meaningless to use FILL or EDGE.
As in the case of POLYGON, a PIVOT or PDIR statement prior to executing POLYLINE will rotate the figure. Anisotropic scaling will stretch or compress the figure along the axes, and if the pen is down prior to invoking the statement, a line will be drawn from the center to the first perimeter point. After POLYLINE has executed, the current pen position is the same as it was before the statement was executed, and the pen is up.
One of the most used polygons in computer graphics is the rectangle. You can draw a rectangle by moving to the point where you want one of the corners to be and then specifying which directions to proceed to from there, first in the X direction, then in the Y direction. Which corner of the rectangle ends up at the current pen position depends on the signs of the X and Y parameters. For example, if you want a rectangle with a lower left corner at 3,2, which is 4 units wide and 5 units high, there are four ways you could go about it:
MOVE 3,2 (Reference point is the lower left corner)
RECTANGLE 4,5
or
MOVE 7,2 (Reference point is the lower right corner)
RECTANGLE -4,5
or
MOVE 3,7 (Reference point is the upper left corner)
RECTANGLE 4,-5
or
MOVE 7,7 (Reference point is the upper right corner)
RECTANGLE -4,-5
Again, you can specify FILL, EDGE, or both. FILL will fill the rectangle with the current color as specified by AREA PEN, AREA COLOR, or AREA INTENSITY. EDGE causes the edge of the rectangle to be drawn in the current pen color and line type. If both are specified, FILL must be specified first. If neither is specified, EDGE is assumed. The current pen position is not changed by this statement, and pen status prior to execution makes no difference in the resulting rectangle.
For many special-purpose programs, there is a shortage of characters that can be displayed on the screen. Greek letters--Delta, PI;, Sigma, and so forth--are often needed for mathematic communication, as are non-alphabetic symbols like square-root-of-, Infinity, and +/-. To alleviate this shortage of symbols, the SYMBOL statement allows you to draw any definable character. In function, it is similar to PLOT using an array, except the figure drawn by SYMBOL is subject to the three transformations which deal with character labeling: CSIZE, LDIR, and LORG.
NOTE |
---|
User-defined alpha character fonts are available on bit-mapped alpha displays. See "Communicating with the Operator" in HP BASIC Advanced Programming Techniques. |
The first argument needed by the SYMBOL statement is the array containing the instructions on what to draw. As in PLOT, this array may have two or three columns. If the third column does not exist, it is assumed to be +1 for every row of the array. If it does exist, the valid values for the third-column entries are identical to those for PLOT, RPLOT, and IPLOT when using an array. The possible values for the third column are listed earlier in this section in the table titled "Pen Control for Plotting Entire Arrays." For more detail on the meaning of these values, see the HP BASIC Language Reference manual.
Moves and draws specified in an array for a SYMBOL statement are defined in the symbol coordinate system. This coordinate system is a character cell, a 9×15 rectangle. Figures drawn in this coordinate system may be filled, edged, or both. FILL and EDGE can appear in the SYMBOL statement itself, or they can be specified in the data array. If FILL and/or EDGE are specified in both places, the instruction in the data array overrides that of the statement.
One interesting feature of this statement is that values outside the character cell boundaries are valid. Thus, you can define characters that are several lines high, several characters wide, or both. This feature is used in the following program. The SYMBOL statement, by virtue of its syntax, can only be used for one user-defined character at a time; the pen must be moved to the new position before each character. Therefore, users-defined characters (UDCs) cannot be embedded in a string of text. If the situation remained this way, the utility of the SYMBOL statement would be limited by its cumbersome implementation.
The program Symbol
makes UDCs easier to use.
Symbol
is a special-purpose program which calls two
general-purpose subprograms. The first subprogram
(New_udc
) is called to define a new UDC. Its parameters
are: 1) the character to be replaced by the UDC, and 2) the array defining
the character. The second subprogram (Label
) is called
after all desired UDCs have been defined. This allows text to be labeled
(written in graphics mode), intermixing ASCII characters with user-defined
characters at will. As mentioned above, all user-defined characters are affected
by CSIZE, LDIR and LORG, so no matter how the label is written, the UDCs
will act properly. (Run the example program in file
Symbol
.)
Of course, the limits (20 UDCs and 30 rows maximum) may be reduced or expanded to fit your purpose. Note that in lines 270 through 300 of the program, characters 168 through 171 were replaced by the four UDCs. There is nothing magical about these four characters. The characters replaced could have been any characters between 0 and 255, and they need not be consecutive.
Also note that in line 450 of the program, there are two spaces after the CHR$(171). This is because character 171 was replaced by the box, which is three character cells wide. The two extra spaces prevent the right two-thirds of the box from being overwritten by whatever is labeled after it.
When using multi-plane (color or gray-scale) bit-mapped displays, BASIC provides the ability to specify which planes to write-enable for alpha and graphics and which planes to display. Note that a request to modify the alpha and graphics write masks are not supported by X-windows. This feature provides several useful features on bit-mapped displays. Before we look at the uses, however, let's look at what these masks are:
First, we'll look at the graphics write-enable mask. Its function is to specify which frame buffer planes are to be written to by graphics operations.
To illustrate, assume that your machine has four planes in the frame buffer.
Suppose you want to set the graphics write-enable mask such that graphics
operations use only the first two planes of the frame buffer. This is done
by setting the first element of an integer array to the value desired, and
then executing the GESCAPE
with operation selector 7:
INTEGER Graphics_masks(0:0)
Graphics_masks(0)=IVAL("0011",2) ! Set graphics write mask: planes 1& 2
GESCAPE CRT,7,Graphics_masks(*) ! Set write mask; display mask is
unchanged
The graphics write-enable mask has the value 0011
(in
decimal, the value is 3, but the masks will be shown in binary for clarity).
This indicates that only planes 1 and 2 of the frame buffer will be used
for graphics write operations. For example, drawing a line can change bits
only in planes 1 and 2. A graphics write-enable mask of
0011
also implies that there are only four color-map
"pens" available for use by graphics operations: 0 through 3.
The difference between the graphics write-enable mask and the graphics display-enable mask is that the former specifies which planes are actually modified by graphics operations (regardless of whether or not they are displayed), and the latter specifies which planes can be seen by the user (regardless of whether or not anything has been or can be written to them).
Suppose you want to set the graphics display-enable mask such that only the
contents of the first two planes of the frame buffer are visible to the user.
This is done by setting the second element of an integer array to
the value desired, and then executing GESCAPE
with operation
selector 7:
INTEGER Graphics_masks(0:1)
Graphics_masks(0)= some value
Graphics_masks(1)=IVAL("0011",2) ! Set display-enable mask: planes 1& 2
GESCAPE CRT,7,Graphics_masks(*) ! Set masks
Although for many operations the graphics write-enable mask and the graphics display-enable mask will have the same value, they need not be the same. There are many instances where they will be different. In many of these cases, one or both of the graphics masks will change regularly as the program executes.
The alpha write-enable mask and display-enable mask do the same jobs for the alpha display as their graphics counterparts do for the graphics display.
NOTE |
---|
When the PLOTTER IS device is the same as
the ALPHA CRT device, the alpha display mask is the graphics display
mask and vice versa. Though they are the same entity, the mask can be accessed
either by GESCAPE CRT,7 or CONTROL
CRT,20 (see below). |
To set and read the alpha write-enable mask, use the following statements:
SET ALPHA MASK IVAL("1100",2) ! Set alpha WRITE-enable mask: planes 3& 4
STATUS CRT,18;Alpha_writemask ! Read alpha WRITE-enable mask
To set and read the alpha display-enable mask, use the following statements:
SET DISPLAY MASK IVAL("1100",2) ! Set alpha DISPLAY-enable mask: planes 3& 4
STATUS CRT,20;Alpha_disp_mask ! Read alpha DISPLAY-enable mask
The alpha and graphics write-enable masks both default at power-up and SCRATCH A to all planes in the machine. Thus (assuming you have a four-plane machine), both write-enable masks would be 1111. All four planes are at once both alpha planes and graphics planes. This implies that when you write graphical information, the alpha display may be modified and overwritten, and vice versa.
Alternately, if you set the alpha write-enable mask to 0011 (alpha uses planes 1 and 2), and the graphics display-enable mask to 1000 (graphics uses plane 4), plane 3 is neither alpha nor graphics.
This is a departure from older machine architectures where there was a fixed alpha area and a fixed graphics area, and in which "alpha" equals "not graphics" and "graphics" equals "not alpha." Now, planes can be "both alpha and graphics" or "neither alpha nor graphics," and you can choose where to put them.
When a plane is designated as both an alpha plane and a graphics plane (default state), alpha and graphics share the bit-mapped plane so that writing to the display overwrites existing information. A plane designated as graphics only can be written to by graphics statements such as DRAW and LABEL, but not with alpha statements. Similarly, an alpha-only plane can be written to with statements such as PRINT and DISP, but not with graphics statements. Note that when executing PLOTTER IS, PENs with bits in non-graphics planes are not updated when the color map is initialized. The graphics write-enable mask also affects GSTORE and GLOAD; see the HP BASIC Language Reference for details.
With this feature you can simulate separate alpha and graphics planes for compatibility with older systems that do not have bit-mapped alpha. Assuming you have a four-plane display, you could designate planes 1 through 3 for graphics, and plane 4 for alpha. This gives you eight pure graphics colors, and a single alpha color, and some of the capabilities of a separate alpha/graphics system on bit-mapped hardware:
It has always been true that you could dump alpha when using bit-mapped displays. However, this capability is afforded by the presence of an "alpha buffer," a spare storage place for all alpha information. This enables alpha to be dumped to a printer that does not have raster graphics capabilities.
There is one tricky condition that may occur if you're not careful. Suppose your program has executed ALPHA PEN 1, and at some point it changes the alpha write-enable mask to 1100. Suddenly, the output stops appearing, the run light remains on, and the "live" keyboard appears dead. By all appearances, your machine is hung. This is not the case, however.
What actually happens is this. Before the write-enable mask was changed, everything was going as expected. When you changed the write-enable mask to 1100, you caused the machine to only turn on pixels when using pens whose numbers had some bits in common with the write-enable mask, now 1100. The only pens which satisfy this condition are pens 4 through 15. In other words, nothing appeared when you were "writing" because on one hand you said "write pixels in planes 3 and 4 only," and on the other hand you said "I am going to write with a pen which doesn't turn on pixels in planes 3 and 4."
The following program illustrates the concept of simulating separate alpha and graphics. (You can also use SEPARATE ALPHA FROM GRAPHICS and MERGE ALPHA WITH GRAPHICS to accomplish these tasks; however, this program shows the intermediate steps in how the alpha write-enable and display-enable masks interact). The program writes some text which will be visible. Next, it changes the display mask so the alpha display mask and the current pen are disjoint. After writing a bit more, the program pauses, so you can see just how hung it really looks. When you press [CONTINUE] ([f2] in the System menu of an ITF keyboard), the alpha display mask and the pen will once again come into agreement.
10 ! This program demonstrates proper and improper use of alpha masks.
20 ! (Return everything to its default state if the program didn't finish)
30 SET ALPHA MASK IVAL("1111",2) ! Set alpha write-enable mask.
40 SET DISPLAY MASK IVAL("1111",2) ! Set alpha display-enable mask.
50 CLEAR SCREEN
60 GINIT
70 PLOTTER IS CRT,"INTERNAL";COLOR MAP
80 ! (Start the demo)
90 ALPHA PEN IVAL("0011",2) ! Set alpha pen
100 SET ALPHA MASK IVAL("0011",2) ! Set alpha write-enable mask.
110 SET DISPLAY MASK IVAL("0011",2) ! Set alpha display-enable mask.
120 PRINT "I'm printing visibly."
130 WAIT 4
140 PRINT "Changing the alpha display mask -- this text will vanish."
150 WAIT 4
160 SET DISPLAY MASK IVAL("1100",2) ! Set alpha display-enable mask.
170 WAIT 4
180 FOR I=1 TO 10
190 PRINT " I'm printing stuff now but you can't see it."
200 NEXT I
210 SET DISPLAY MASK IVAL("0011",2) ! Set alpha display-enable mask.
220 WAIT 1
230 PRINT "The above text just became visible."
240 WAIT 4
250 PRINT "The above text will disappear again and the machine will"
260 PRINT "appear hung until you press CONTINUE."
270 PRINT "(Note the run light stays on after the computer pauses.)"
280 WAIT 9
290 SET DISPLAY MASK IVAL("1100",2) ! Set alpha display-enable mask.
300 PAUSE
310 SET DISPLAY MASK IVAL("0011",2) ! Set alpha display-enable mask.
320 WAIT 1
330 PRINT
340 PRINT "The above text just became visible again."
350 WAIT 4
360 SET ALPHA MASK IVAL("1111",2) ! Set alpha write-enable mask.
370 SET DISPLAY MASK IVAL("1111",2) ! Set alpha display-enable mask.
380 ALPHA PEN IVAL("0001",2) ! Set alpha pen
390 PRINT "I just set the alpha masks and pen back to normal."
400 END
Another use of the graphics write-enable mask is the fast display of multiple pictures. For example, you could:
Cycling through this sort of a loop--flashing consecutive pictures on the screen--simulates a rudimentary animation; i.e., "motion" pictures. Be aware, however, that the drawing speed is much too slow to describe smooth, non-jerky movements.
The selection of graphics planes to be write-enabled and display-enabled is accessed via the GESCAPE statement (in the GRAPHX binary).
Series 300/400/700 computers (and Series 200 Model 237 computer) have alpha and graphics on the same raster (this is called "bit-mapped alpha"). One of the most important implications of this architecture for graphics is that when you scroll alpha information, you also scroll graphics. If you want to disable scrolling of both alpha and graphics due to the cursor-control keys (such as [Up Arrow] and [down arrow]), you can execute this statement:
CONTROL KBD,16;1
If scrolling is currently disabled and you want to re-enable it, execute this statement:
CONTROL KBD,16;0
On non-bit-mapped alpha displays, CONTROL KBD 16, 1
will
also disable alpha scrolling. Because the alpha and graphics are physically
separate, however, graphics will not be affected by alpha scrolling on
non-bit-mapped displays.
Color can be used for emphasis, clarity, and to present visually pleasing images. This section is an overview of color graphics on the computer. For a detailed discussion of color graphics programming techniques, refer to the "Color and Gray Scale Graphics" chapter in HP BASIC Advanced Programming Techniques.
The methods for displaying color fall into four categories:
The PEN, AREA PEN, AREA INTENSITY, and AREA COLOR statements control what are referred to as modal attributes. This means that the value established by one of the statements stays in effect until it is altered by another statement.
When PLOTTER IS CRT,"INTERNAL"
is executed, eight colors
are available through the PEN and AREA PEN statements. The colors provided
are:
The colors can be selected with the PEN statement, the same way they are for an external plotter. The meanings of the different pen values are shown in the table below. The pen value can cause either a 1 (draw), a 0 (erase), n/c (no change), or complement (invert) the value in each color plane.
Pen | Action | Plane 1\(red) | Plane 2\(green) | Plane 3\(blue) |
---|---|---|---|---|
-7 | Erase Magenta | 0 | n/c | 0 |
-6 | Erase Blue | n/c | n/c | 0 |
-5 | Erase Cyan | n/c | 0 | 0 |
-4 | Erase Green | n/c | 0 | n/c |
-3 | Erase Yellow | 0 | 0 | n/c |
-2 | Erase Red | 0 | n/c | n/c |
-1 | Erase White | 0 | 0 | 0 |
0 | Complement | invert | invert | invert |
1 | Draw White | 1 | 1 | 1 |
2 | Draw Red | 1 | 0 | 0 |
3 | Draw Yellow | 1 | 1 | 0 |
4 | Draw Green | 0 | 1 | 0 |
5 | Draw Cyan | 0 | 1 | 1 |
6 | Draw Blue | 0 | 0 | 1 |
7 | Draw Magenta | 1 | 0 | 1 |
If you are in this mode, you can draw lines in the eight colors listed above.
If you are trying to define a complex human interface, you will need more colors and more control over the colors. This is possible after you turn on the color map. To do so, execute:
PLOTTER IS CRT,"INTERNAL";COLOR MAP
If you do not modify the color map, the colors selected by the PEN and AREA PEN values depend on the default color map values. These values are shown in the following table:
Value | Color |
---|---|
0 | Black |
1 | White |
2 | Red |
3 | Yellow |
4 | Green |
5 | Cyan |
6 | Blue |
7 | Magenta |
8 | Black |
9 | Olive Green |
10 | Aqua |
11 | Royal Blue |
12 | Maroon |
13 | Brick Red |
14 | Orange |
15 | Brown |
Pens 0 7 of the default color map are the same as in non-color map mode. The upper 8 colors (8 through 15) were selected by a graphic designer to produce graphs and charts for business applications. The colors are:
These colors were chosen by a graphics designer to avoid clashing with each other. They are intended for business charts and graphs, and similar applications.
The SET PEN statement is used to customize the color that each PEN value represents. SET PEN supports two color models, the RGB (Red, Green, Blue) model and the HSL (Hue, Saturation, Luminosity) model. Since the color models are dynamically interactive, it is much easier to understand them by experimenting with them.
You can think of the RGB model as mixing the output of three light sources (one each for red, green, and blue). The parameters in the model specify the intensity of each of the light sources. The RGB model is accessed through the secondary keyword INTENSITY used with the SET PEN statements. The values are normalized (range from 0 through 1). Thus,
SET PEN 0 INTENSITY 0.7, 0.7, 0.7
sets pen 0 (the background color) to approximately a 70% gray value. Whenever all the guns are set to the same intensity, a gray value is obtained. The parameters for the INTENSITY mode of SET PEN are in the same order they appear in the name of the model, red, green, and blue.
When using an EGA system, each primary color (red, green, and blue) can be displayed at four distinct levels:
Therefore, each PEN may be set to one of 64 distinct colors.
The HSL model is closer to the intuitive model of color used by artists, and is very effective for interactive color selection. The three parameters represent hue (the pure color to be worked with), saturation (the ratio of the pure color mixed with white), and luminosity (the brightness-per-unit area). The HSL model is accessed through the SET PEN statement with the secondary keyword COLOR:
SET PEN
Current_Pen COLOR
Hue, Saturation, Luminosity
Hue, Saturation, and Luminosity are normalized to values from 0 to 1.
For a much more detailed discussion of this topic, refer to the HP BASIC Advanced Programming Techniques manual.
In either color-mapped or non-color-mapped mode, areas may be filled with a PEN color by first selecting that PEN with an AREA PEN statement. Filling is specified by using the secondary keyword FILL in any of the following statements:
IPLOT
PLOT
POLYGON
RECTANGLE
RPLOT
SYMBOL
It is possible to fill areas with other shades. These tones are achieved through dithering. Dithering produces different shades by combining dots of the eight colors described earlier. The screen is divided into 4-by-4 cells, and patterns of dots within the cells are turned on to match, as closely as possible, the color you specify. Dithered colors are defined with the AREA COLOR and AREA INTENSITY statements using the RGB or HSL models described in the previous section. For more information see the "Customizing Xwindows Colors for HP BASIC/UX" section in the chapter "Installing HP BASIC/UX on to HP-UX" in the Installing and Maintaining HP BASIC/UX manual.