This program renders a three-dimensional surface plot of the function z = cos(0.1*(x²+y²)) — a radially symmetric ripple — using a perspective projection onto the screen. The projection math in lines 20–30 implements a standard 3D-to-2D camera transform using rotation angles theta and phi, viewer distance rho, and focal length d, with sine/cosine values precomputed in line 40 for efficiency. The outer loop iterates x from 10 to -10 (reverse order for hidden-line suppression), while the inner loop steps y from -10 to 10, computing each projected screen coordinate via GOSUB. A flag variable fl tracks whether the pen is “up” or “down,” and PLOT/DRAW commands connect consecutive projected points to form the wireframe mesh.
The program was converted from the book “Microcomputer Graphics” by Myers and adapted for the TS2068 by James N. Jones of Amarillo, Texas.
Program Analysis
Program Structure
The program is organized into a small set of functional blocks:
- Lines 1–7: REMs and initialization (BRIGHT, INK, starting pen position).
- Line 10:
GO TO 40to skip over subroutines. - Lines 20–30: 3D projection subroutine — computes eye-space coordinates and then screen coordinates.
- Line 40: Camera/view parameter initialization.
- Line 50: Function definition via
DEF FN z(x). - Lines 70–150: Main double loop that iterates over the surface grid and draws it.
- Line 9998:
SAVEwith auto-run.
The Surface Function
The plotted surface is defined in line 50 as DEF FN z(x)=COS(.1*(x*x+y*y)). This produces a rotationally symmetric damped cosine ripple (sometimes called a “Mexican hat” approximation). Note that y is a free variable in the function definition — it refers to the current value of the global variable y from the enclosing loop rather than a formal parameter, which is a common but subtle BASIC idiom.
3D Perspective Projection
Lines 20 and 30 implement a full 3D-to-2D perspective transform. Line 20 computes eye-space coordinates using a rotation matrix parameterized by theta (azimuth) and phi (elevation), with precomputed sines and cosines s1, s2, c1, c2 from line 40. The viewer offset rho shifts the scene along the z-axis of eye space.
Line 30 applies a perspective divide: sx = d*xe/ze + cx and sy = cy + d*ye/ze, where d is the focal length and (cx, cy) is the screen center. This is a standard pinhole camera model.
Hidden-Line Suppression
The outer loop runs x from 10 down to -10 (line 70, STEP -1). This reverse ordering is a classic painter’s-algorithm trick for wireframe surface plots: rows closer to the viewer are drawn last and naturally overwrite more distant rows, giving a rudimentary hidden-line effect without any explicit depth buffer.
Pen-Up / Pen-Down Logic
The flag variable fl acts as a pen-up indicator. It is reset to 0 at the start of each x-row (line 80) and whenever a projected point falls outside the screen boundary (line 110). When fl=0, a PLOT lifts and places the pen at the new point (line 120); subsequent in-bounds points are connected with DRAW (line 130). However, there is a subtle bug: fl is never set to 1 after the initial PLOT, so the condition IF fl=0 on line 120 is always true, meaning every point is PLOTted rather than only the first in a run. The DRAW on line 130 still executes unconditionally, so lines are still drawn, but each step first re-PLOTs the current point unnecessarily.
INK Color Switching
Line 136 sets INK 0 (black) during drawing, while line 145 resets it to INK 7 (white) between x-rows. Combined with BRIGHT 1, this produces a high-contrast white mesh on a black background, with each row’s INK briefly switched to create alternating color effects on the drawn lines.
Key Variables
| Variable | Role |
|---|---|
rho | Viewer distance along optical axis |
d | Focal length (perspective scaling) |
theta | Azimuth rotation angle (radians) |
phi | Elevation rotation angle (radians) |
cx, cy | Screen center coordinates |
s1, c1 | Precomputed SIN/COS of theta |
s2, c2 | Precomputed SIN/COS of phi |
sx1, sy1 | Previous projected screen point |
fl | Pen-up flag (intended; see bug note) |
Notable Techniques
- Trig precomputation in line 40 avoids repeated
SIN/COScalls in the inner loop, significantly improving rendering speed. - The
DEF FNmechanism is used for the surface function, making it easy to substitute a different z(x,y) formula by editing only line 50. GO TO 40at line 10 skips the subroutine lines, a standard BASIC structure for placing subroutines near the top of the listing.- Screen boundary clipping in line 110 prevents
PLOT/DRAWerrors from out-of-range coordinates.
Content
Source Code
1 REM this proqram 6.4
2 REM draws a surface z=f(x,y)
3 BRIGHT 1
4 LET ink=0
5 LET sx1=0: LET sy1=170
6 INK 7
7 REM converted to T/S 2068 by James N. Jones 2242 Locust Amarillo, Texas 79109
8 REM from the book by Myers Microcomputer Graphics
10 GO TO 40
20 LET xe=-x*s1+y*c1: LET ye=-x*c1*c2-y*s1*c2+z*s2: LET ze=-x*s2*c1-y*s2*s1-z*c2+rho
30 LET sx=d*xe/ze+cx: LET sy=cy+d*ye/ze: RETURN
40 LET rho=30: LET d=350: LET theta=.3: LET phi=1: LET cx=127: LET cy=87: LET s1=SIN (theta): LET s2=SIN (phi): LET c1=COS (theta): LET c2=COS (phi)
50 DEF FN z(x)=COS (.1*(x*x+y*y))
60 REM color
70 FOR x=10 TO -10 STEP -1
80 LET fl=0
90 FOR y=-10 TO 10
100 LET z=FN z(x): GO SUB 20
110 IF sx<0 OR sx>255 OR sy<0 OR sy>175 THEN LET fl=0: GO TO 140
120 IF fl=0 THEN LET l=1: PLOT sx,sy
130 DRAW (sx1-sx),(sy1-sy)
135 LET sx1=sx: LET sy1=sy
136 INK 0
140 NEXT y
145 INK 7: LET sx1=0: LET sy1=170
150 NEXT x
9998 SAVE "SrfcPlot" LINE 1
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
