Miscellaneous Graphics Concepts

Clipping

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.

Drawing Modes

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:
Monochromatic Pens
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.

Selecting Line Types

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:

Line Types

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.

Storing and Retrieving Images

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.)

Data-Driven Plotting

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.
Pen Control Parameters
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
 

Example of Data-Driven Plotting (Lem2)

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:
Pen Control when Plotting Entire Arrays
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."

Translating and Rotating a Drawing

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,7s 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

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
 

Incrementally Plotting Letters (Iplot)

Drawing Polygons

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.

But I Don't Want Polygon Closure...

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.

Rectangles

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.

User-Defined Characters (UDCs)

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.)

Implementing User-Defined Characters (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.

Multi-Plane Bit-Mapped Displays

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:

The Graphics Write-Enable Mask

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 Graphics Display-Enable Mask

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 Masks

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
 

Interactions Between Alpha and Graphics Masks

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:

  1. Disable all planes displayed. This makes the screen blank.
  2. Enable plane 1 for writing.
  3. Create a single-color picture in plane 1.
  4. Enable plane 1 for display. Now the picture in plane 1 appears on the screen.
  5. Disable plane 1 for writing and enable plane 2.
  6. Create a different single-color picture in plane 2.
  7. Disable plane 1 for display and enable plane 2. Now the picture in plane 2 appears on the screen.

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).

Disabling and Enabling Alpha Scrolling

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.

Introduction to Color Graphics

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.

Non-Color Mapped Color

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.
Non-Color-Map Dominant-Pen Mode
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.

Color Mapped Color

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
 

Default Colors

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:
Default Color Map Values
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.

Changing Default Colors

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.

Fill Colors

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.