Z-Plot Title
by David Bader
24K cassette or 32K Disk

I have always been fascinated by a computer's ability to take a flat grid and literally bend and distort it. I've seen various pictures produced by the Atari - hats and spirals made simply by a formula. However, altering these programs for personal use and experimentation is both difficult and time consuming.

After studylg calculus and graphics in my first semester of college, I resolved to make a program to allow anyone to produce quick, fascinating pictures on Atari's superior high-resolution mode (graphics 24).

With Z-Plotter, all you have to do (besides typing in the program) is enter a formula in terms of the X and Y during the run, Atari's forced read mode (utilized with location 842) will install the formula in all the appropriate line numbers.

There are no loops, IF/THENs, or special circumstances to enter for each formula. This program simply won't graph out of specified domains, which prevents errors. If you wish, Z-Plotter will scale the Z-axis, so that the function won't even extend beyond the bounds.

How to run Z-Plotter.

Once you've saved your copy to disk, simply type RUN, and the program will prepare itself, filling two machine language routines (49 Second Screen Dump and a text-superimposing routine).

Next, it will inquire for a function. A short set of directions is also displayed, to guide you. Simply type the Z= fuction in terms of X and/or Y. Several sample formulas are given at the end of this article. Z-Plotter will then resume control and ask you for the following inputs.

You are asked to choose between automatic scaling and manual scaling of the Z-axis. Automatic scaling will determine the maximum and minimum Z values for the function in the intervals specified. Although it's very tempting to be lazy and just select the autoscaling feature, you will find that many functions are far more stimulating and exciting when they are graphed in part.

The autoscale will force a function to be squeezed into the isometric box drawn on the screen. If you select manual scaling, you'll be asked to enter the lowest and highest points on the Z-axis to be displayd. The graph will not be plotted outside of the Z-axis range. Note: when manual scaling, the limits must be set so that the point Z=0 is either on or between the upper and lower bounds. Examples of acceptable limits: Z lower =-2, Z upper =2 or Z lower =0, Z upper =3.

X/Y lower limit: this will be the leftmost point on the X-axis, and the number also serves as the lowest point for the Y-axis.

X/Y Upper limit: opposite of above. Note: just as with the Z-axis, Y=0 and X=0 must be within or on the box. Picture a perfect square; the Y-axis will have the same length as the X-axis has width.

Desired resolution (1= high, 10 =low): I use 4 for most graphs. It's a good balance between BASIC's speed and peformance resolution. Note: odd numbers may cause problems if your formula is undefined somewhere in the box.

The next input can be surpassed by just pressing RETURN. Here, you're asked for the eight-character name that can be used if you wish to save to disk (in Magniprint format) the screen, once it has been displayed.

That's all! Z-Plotter can let almost anyone dream up equations to dazzle the computer screen. When it's finished, it will sound off, telling you that you can now render the following options!

(1) OPTION - adds borders (the isometric box) and labels superimposed over the graphics screen for an impressive technical display.
(2) SELECT - saves the picture as a data file that can be redisplayed with the program Magniprint by Alpha Systems. The lines used to perform this duty are provided by Magniprint for use in all BASIC programs. By the way, Magniprint can then print out these pictures - in several sizes and in varied formats.
(3) START - 49 Second Screen Dump! This will print the screen out right then and there for the Epson MX-80 printer with Graphtrax 80 (works perfectly with my Gemini 1OX). This routine was provided by COMPUTE!'s Second Book of Atari.
(4) ESC - will erase the screen and rerun the program without going through initialization again.
What's an Isometric projection?

Imagine a sheet of square graph paper lying perfectly flat on a table top. One side, say the depth, is the X-axis. The height is the Y-axis, but we'll call it the width, instead.

Isometric box
Isometric projection.

If we raised a line perpendicular to each corner of our graph paper to a certain height, called Z, and joined the top of the lines to each other, we would create a box. If Z=Y=X, then we have a cube, with our graph paper as the bottom.

Let's look at this box from the top. You see the grid and recognize the pattern as a typical coordinate plane (X,Y). If we look at the box perpendicular to the X-axis, we see X, the depth, and Z, the height. The Y-axis is just a point at the left lower corner.

Looking perpendicular to the Y-axis, the X-axis would look like a point in the lower right corner. If X=Y, and you look at this corner so that both the X- and Y-axes appear to be the same length, you would see a 90 degree corner facing away from you.

Now, raise your eye straight up above the table. Our graph paper looks more like a diamond shape than a square. In fact, an isometric box has all three primary axes (X, Y, Z) foreshortened equally. This makes it a good medium to project a three-dimensional plane in, because it does not distort like common oblique projections.

If we put a transparent plane perpendicular to your line of sight and etched the borders of the box on it the way they appear to you, that plane would allow a three-dimensional box. An isometric projection shows the X- and Y-axes to be raised 30 degrees above the lowest point.

How do you plot the height (Z) of any point on the grid at any place, given its X and Y coordinates? Just use a formula such as: Z=SIN(X) + COS(Y).

sin(x)+cos(y)

Program breakdown.
Lines 10-34 - Main loop to draw lines parallel to the X-axis isometrically on the screen.
Lines 36-60 - Main loop to draw lines parallel to the Y-axis isometrically on the screen.
Lines 100-110 - Autoscale feature. These lines will determine the Z maximum and minimum values for the entered function before graphing.
Line 200 - This sound indicates that the program has finished drawing the display and is ready to perform any of the console key commands.
Lines 202-210 - This loop reads the console keys. Note: because all these console key options do not erase the screen, you can perform all of them in any order from a single run!
Lines 300-306 - 49 Second Screen Dump.
Lines 400-432 - Magniprint saving routine supplied verbatim by Magniprint on disk.
Lines 600-900 - Routine to draw isometric box over projection and label the axes.
Lines 1000-1004 - Intialize and load machine language routines. One is POKED into page 6, and the other is stored by a string.
Lines 1008-1012 - These lines provide in run entry of your formula. The actual function is entered as an input statement. The program will then create Lines 14, 40 and 104 using the forced read mode.
Lines 1013-1040 - Prompts for boundaries and screen saving name. Note: if no name is entered for screen saving, it will accept the default name, SCREEN.MP.
Line 1042 - Sets up primary variables and scaling values used in the main routine, for converting a set of (X, Y, Z) points to the 320 by 192 screen display used in graphics 24.
Line 1044 - Sets up display screen.
Lines 1100-1110 - Data for 49 Second Screen Dump.
Lines 1120-1180 - Data for the routine to superimpose text over the graphics 24 screen.
sin(x)*cos(y)

Here are some samples. Hint: rather than using powers such as X^3, BASIC will perform the configuration X*X*X much faster.

                       AUTO     Z      Z     X/Y    X/Y
FORMULA                     or
                      SCALE?  LOWER  UPPER  LOWER  UPPER
Z=1+X*X-Y*Y             NO       0     6     -3      3
Z=SIN(X)               YES     (-1)   (1)     0      6
Z=SIN(X)+COS(Y)        YES     (-2)   (2)     0      6
Z=SIN(X)*COS(Y)        YES     (-1)   (1)     0      6
Z=ABS(X)-ABS(Y)        YES       -     -     -3      3
Z=-ABS(X)-ABS(Y)        NO      -3     0     -3      3
Z=(Y-1)*(X+2)*X*X       NO      -4     4     -3      3
Z=COS(X)*X*(Y-1)        NO      -3     0     -4      4
Z=X*X/1+X*X+Y*Y/1*Y*Y  YES       -     -     -4      4
Z=INT(X)+INT(Y)        YES      (0)   (6)     0      3.9
Z=X*X+Y*Y              YES      (2)   (0)    -1      1
Z=LOG(ABS(X))          YES       -     -     -2      2
   +LOG(ABS(Y))

(y-1)*(x+2)*x*x

Dave Bader is a first-year, dean's list student in Mechanical Engineering. For close to two years now, he has been enthusiastically hacking his way through BASIC, to create both adventure games and programs for mathematics (the original inspiration for Z-Plotter). He's a firm believer in the Atari - as the best home computer on the market.
Listing 1.

0 GOTO 1000
10 FOR Y=YU TO YL STEP -RES*(YU-YL):B=
K0
12 FOR X=XL TO XR STEP RES*(XR-XL)
14 REM  FORMULA (ENTERED DURING RUN) 
16 IF Z>H OR Z<HL THEN B=K0:GOTO 34
18 XX=X*XINC
20 YY=XX*ISO
22 XX=XX-Y*YINC
24 YY=YY+Y*YINC*ISO
26 YY=YY+Z*ZINC
28 YY=191-YY-DBG
30 XX=XX+159:IF B THEN DRAWTO XX,YY:GO
TO 34
32 PLOT XX,YY:B=K1
34 NEXT X:NEXT Y
36 FOR X=XL TO XR STEP RES*(XR-XL):B=K
0
38 FOR Y=YU TO YL STEP -RES*(YU-YL)
40 REM  FORMULA (ENTERED DURING RUN) 

(y-1)*(x+2)*x*x

42 IF Z>H OR Z<HL THEN B=K0:GOTO 60
44 XX=X*XINC
46 YY=XX*ISO
48 XX=XX-Y*YINC
50 YY=YY+Y*YINC*ISO
52 YY=YY+Z*ZINC
54 YY=191-YY-DBG
56 XX=XX+159:IF B THEN DRAWTO XX,YY:GO
TO 60
58 PLOT XX,YY:B=K1
60 NEXT Y:NEXT X:GOTO 200
100 H=K0:HL=K0:FOR Y=YU TO YL STEP -RE
S*(YU-YL)
102 FOR X=XL TO XR STEP RES*(XR-XL)
104 REM  FORMULA (ENTERED DURING RUN) 
105 IF Z>H THEN H=Z
106 IF Z<HL THEN HL=Z
107 NEXT X:NEXT Y
108 IF HL>K0 THEN HL=K0
109 IF H<K0 THEN H=K0
110 RETURN 
200 SOUND K0,100,10,14:FOR T=K0 TO 100
:NEXT T:SOUND K0,K0,K0,K0:POKE 764,255
202 S=PEEK(53279):IF S=6 THEN GOSUB 30
0:GOTO 202
204 IF S=5 THEN GOSUB 400:GOTO 202
206 IF S=3 THEN GOSUB 600:GOTO 202
208 IF PEEK(764)=28 THEN ? "$)":GOTO 1
008
210 GOTO 202
299 REM *"49 SECOND SCREEN DUMP"
300 CLOSE #5:OPEN #5,8,K0,"P:"
302 ? #5;CHR$(27);"A";CHR$(8):FOR X=DM
 TO DM+39
304 A$=CHR$(K0):A$(192)=A$:A$(2)=A$
306 W=USR(1536,X,ADR(A$)):LPRINT CHR$(
27);"K";CHR$(192);CHR$(K0);A$:NEXT X:R
ETURN 
400 REM *400-432 IS 'AS IS' SUBROUTINE
 SUPPLIED BY MAGNIPRINT TO SAVE A GR.2
4SCREEN
402 RW=8:IO=K1:CLOSE #IO:OPEN #IO,RW,K
0,F$

1+x*x-y*y

404 PUT #IO,24:FOR I=704 TO 712:PUT #I
O,PEEK(I):NEXT I
406 RAMTOP=PEEK(106)*256
408 DLIST=PEEK(560)+256*PEEK(561)
410 ADDRESS=DLIST
412 NUMBER=RAMTOP-DLIST+K1
414 IO=16*IO
416 IOCB=832+IO:POKE IOCB+2,RW+3
418 ADRHI=INT(ADDRESS/256)
420 ADRLO=ADDRESS-ADRHI*256
422 POKE IOCB+4,ADRLO:POKE IOCB+5,ADRH
I
424 NUMHI=INT(NUMBER/256)
426 NUMLO=NUMBER-256*NUMHI
428 POKE IOCB+8,NUMLO:POKE IOCB+9,NUMH
I
430 I=USR(ADR(""),IO)
432 CLOSE #IO/16:RETURN 
600 D=K0:F=K0:Q$=FC$:GOSUB 900
601 PLOT 159,191:DRAWTO 20,117:DRAWTO 
159,44:DRAWTO 300,117:DRAWTO 159,191:D
RAWTO 159,147
602 PLOT 20,117:DRAWTO 20,73:PLOT 159,
44:DRAWTO 159,K1:PLOT 300,117:DRAWTO 3
00,73
604 DRAWTO 159,147:DRAWTO 20,73:DRAWTO
 159,K1:DRAWTO 300,73
606 D=K1:F=2:Q$=".-----.":GOSUB 900:F=
3:Q$="|ATARI|":GOSUB 900:F=4:Q$=".----
-.":GOSUB 900
608 D=K0:F=14:Q$=STR$(YU):GOSUB 900:Q$
=STR$(XR):D=39-LEN(Q$):F=14:GOSUB 900
610 D=16:F=23:Q$=STR$(YL):GOSUB 900:D=
23:Q$=STR$(XL):GOSUB 900:D=26:F=K1:Q$=
"HIGH Z=":GOSUB 900
611 D=33:Q$=STR$(H):IF LEN(Q$)>7 THEN 
Q$=Q$(K1,7)
612 GOSUB 900:D=26:F=2:Q$="LOW  Z=":GO
SUB 900:D=33:Q$=STR$(HL):IF LEN(Q$)>7 
THEN Q$=Q$(K1,7)
614 GOSUB 900:D=3:F=19:Q$="Y-AXIS":GOS
UB 900:D=30:Q$="X-AXIS":GOSUB 900:RETU
RN 

log(Abs(x))+log(Abs(y))

900 Q=USR(ADR(Z$),D,F,ADR(Q$),LEN(Q$))
:RETURN :REM *SUB.TO ADD TEXT TO GR.24
1000 K1=1:GRAPHICS 24:RESTORE 1000:FOR
 T=K1 TO 61:READ Q:POKE 1535+T,Q
1001 NEXT T:DM=PEEK(88)+PEEK(89)*256:D
M=DM+40*191
1002 T=K0:DIM Z$(169),Q$(40),A$(193),F
$(20),FC$(40):ISO=0.523598775
1004 RESTORE 1120:FOR T=K1 TO 168:READ
 Q:Z$(LEN(Z$)+K1)=CHR$(Q):NEXT T
1008 POKE 82,K0:GRAPHICS K0:POKE 712,1
48:? " DAVE BADER'S ZPLOTTER! ":? " 3D
 ISOMETRIC PLOTTER PROGRAM ":? 
1009 ? "INPUT FORMULA AS... Z=(IN TERM
S OF X&Y) MAKE SURE THAT SYNTAX IS COR
RECT.":? "(eg: PAIRS OF PARENTHESIS)"
1010 INPUT FC$:? "":POKE 559,K0:POSIT
ION K0,7:? "14 ";FC$:POSITION K0,11:? 
"40 ";FC$
1011 POSITION K0,15:? "104 ";FC$:POSIT
ION K0,21:? "CONT":POSITION K0,K0:POKE
 842,13:STOP 
1012 POKE 559,34:POKE 842,12:? "  ZPL
OTTER!  PARAMETERS ENTRY SCREEN    "
1013 ? "NOTE: ALL THREE PRIMARY AXIS (
X,Y,Z)    MUST BE IN SPECIFIED DOMAINS
!"
1014 ? :? FC$:? :? "AUTOMATIC BOUNDS S
ELECTION ENSURES FULL PLOTTING BUT TAK
ES MORE TIME...":T=K0
1015 ? :? "PLEASE CHOOSE |1] AUTOMATIC
 SCALING     Z-AXIS BOUNDS |2] MANUAL 
SETTINGS.":INPUT T:IF T=K1 THEN 1020
1016 ? :? "INPUT LOWER Z LIMIT";:INPUT
 HL:? "INPUT UPPER Z LIMIT";:INPUT H
1018 IF HL>H OR HL>K0 OR H<K0 THEN ? "
WOOPS!":GOTO 1016
1020 ? :? "X\Y LOWER LIMIT";:INPUT XL:
YL=XL
1022 ? "X\Y UPPER LIMIT";:INPUT XR:YU=
XR
1024 IF XL>XR OR XL>K0 OR XR<K0 THEN ?
 "WOOPS!":GOTO 1020

Abs(x)-Abs
(y)

1026 ? :? "DESIRED RESOLUTION (1=HIGH;
10=LOW)";:INPUT RES:RES=RES+3:RES=RES*
5.0E-03
1028 F$="D:":? :? "INPUT TITLE OF SAVE
D SCREEN (IF SAVED)  IN MAGNIPRINT FOR
MAT (8 CHARACTERS MAX)"
1030 INPUT Q$:IF Q$="" THEN F$="D:SCRE
EN.MP"
1032 F$(LEN(F$)+K1)=Q$
1035 ? :? " OPTION  ADD LABELS & BORDE
RS":? " SELECT  SAVE IN MAGNIPRINT FOR
MAT!"
1036 ? "  START  49 SECOND SCREEN DUMP
!"
1038 ? :? "PRESS ANY KEY TO BEGIN...":
POKE 764,255
1040 IF PEEK(764)=255 THEN 1040
1041 IF T=K1 THEN ? :? "   AUTO SCALIN
G SEQUENCE IN ACTION!":GOSUB 100
1042 XINC=140/(XR-XL):YINC=140/(YU-YL)
:ZINC=43/(H-HL):DBG=ABS(HL*ZINC)+ABS(X
L*XINC*ISO)+ABS(YL*YINC*ISO)
1044 GRAPHICS 24:POKE 710,156:POKE 709
,K0:COLOR K1:GOTO 10
1100 DATA 104,104,141,21,6,104,141,20,
6,104,141,27,6,104,141,26,6,160,193,17
3,255,255,136,240,35,141,255,255,238
1110 DATA 26,6,240,21,173,20,6,56,233,
40,141,20,6,144,4,24,76,19,6,206,21,6,
76,19,6,238,27,6,76,33,6,96
1120 DATA 104,201,4,240,9,170,240,5,10
4,104,202,208,251,96,104,133,215,104,1
33,214,104,104,168,104,133
1130 DATA 217,104,133,216,104,104,240,
236,133,212,24,165,214,101,88,133,214,
165,89,101,215,133,215,152,240,15
1140 DATA 165,214,105,64,133,214,165,2
15,105,1,133,215,136,208,241,132,221,1
60,0,132,220,177,216,160,0,170
1150 DATA 16,1,136,132,213,138,41,96,2
08,4,169,64,16,14,201,32,208,4,169,0,1
6,6,201,64,208,2

y*y+x*x

1160 DATA 169,32,133,218,138,41,31,5,2
18,133,218,169,0,162,3,6,218,42,202,20
8,250,109,244,2,133,219
1170 DATA 164,221,177,218,69,213,164,2
20,145,214,200,132,220,196,212,208,182
,24,165,214,105,40,133,214,144,2
1180 DATA 230,215,230,221,169,8,197,22
1,208,159,96,207,96

cos(x)+cos(y)
CHECKSUM DATA.
(see CCheck, DCheck, or UniCheck)

0 DATA 406,678,112,865,723,946,48,418,
131,441,537,255,624,615,608,7407
38 DATA 852,859,711,940,70,440,125,435
,531,272,646,700,318,630,774,8303
105 DATA 783,959,524,78,800,584,562,21
7,506,510,263,692,164,702,650,7994
304 DATA 801,518,565,687,912,176,213,5
63,772,680,159,434,840,363,675,8358
426 DATA 679,469,621,293,833,939,67,31
3,747,393,748,947,93,108,673,7923
1000 DATA 41,185,534,222,99,788,260,96
5,349,943,12,930,164,979,778,7249
1022 DATA 537,928,941,166,248,771,187,
35,997,841,910,266,426,553,639,8445
1120 DATA 342,204,918,307,85,956,100,2
912

Abs(cox(x)+cos(y))


Previous | Next

Original text copyright 1984 by ANALOG Computing. Reprinted with permission by the Digital ANALOG Archive.