This program renders a two-dimensional array as a 3D perspective graph on screen, using a hidden-line removal technique based on a running maximum (variable C) to suppress points lower than previously plotted values. The display loop steps through X from 2 to 255 in steps of 2 and Y from 4 to 170 in steps of 4, mapping array indices A(X/2, Y/4) from a 128×44 element array. An aspect-ratio correction at line 9900 applies a small horizontal offset proportional to Y depth to simulate perspective foreshortening. A built-in demo data generator at lines 9945–9985 populates the array with three overlapping bell-shaped peaks using reciprocal-distance functions, clamped to a maximum value of 175, and then jumps to the display routine.
GO TO 9935 for demo data.
Program Analysis
Program Structure
The listing is a self-contained subroutine block occupying lines 9061 and 9850–9991, intended to be merged into a larger program. The entry point is line 9855 (via GO TO 9875 at line 9860, skipping the DIM statement at 9865), and a separate demo data path starting at line 9935 generates synthetic data before jumping back to the display setup at line 9855. The high line numbers suggest this is a loadable module rather than a standalone program.
| Line Range | Role |
|---|---|
| 9850–9855 | REM header, screen setup (BORDER/PAPER/INK/CLS) |
| 9860–9870 | Entry branch: skips DIM, falls through to GO TO 4000 (caller) |
| 9875–9930 | Main 3D display routine |
| 9935–9990 | Demo data generator and array initializer |
| 9991 | Author credit REM |
Display Routine Logic
The outer loop iterates X from 2 to 255 in steps of 2 (128 columns), and the inner loop iterates Y from 4 to 170 in steps of 4 (42 rows). At each step, the array value is read as A(X/2, Y/4) at line 9905. The screen coordinate used for plotting combines the raw Y screen position with the array value: the plotted vertical position is (Y+Y1)/2, effectively blending depth and data height.
Hidden-Line Removal
Variable C acts as a per-column maximum tracker. A point is only plotted if its computed vertical coordinate exceeds C (line 9910: IF (Y+Y1)/2 > C), which suppresses lines hidden behind nearer surfaces. After each plot, C is updated to the new maximum. C is reset to 0 at the start of each new X column (line 9920), ensuring independent hidden-line tracking per vertical slice. This is a classic painter’s-algorithm variant suited to ordered-scan rendering.
Perspective / Aspect-Ratio Correction
Line 9900 computes a horizontal screen offset:
X1 = X + INT(0.05 * (Y/50) * (127 - X))
This nudges points toward the center of the X axis as Y increases, simulating the convergence of parallel lines toward a vanishing point. The factor 0.05 * (Y/50) grows with depth, producing a gentle but visible perspective effect without trigonometry.
Demo Data Generator
Lines 9945–9985 populate A(X,Y) with the sum of three bell-shaped peaks, each modeled as a product of two reciprocal-distance terms:
INT(amplitude / (1 + ABS(cx - X)) * (scale / (1 + ABS(cy - Y))))
The three peaks are centered at approximately (10,15), (80,28), and (128,44), creating a visually interesting landscape for demonstration. Values are clamped at 175 (line 9970) to prevent overflow of the display coordinate range. A progress indicator is printed at line 9961 during filling.
Notable Techniques and Idioms
- Array dimensions 128×44 exactly match the halved/quartered loop step counts, so every loop iteration maps cleanly to a unique array cell.
- The
DRAW 2,0after eachPLOT(line 9910) draws a short horizontal line segment, thickening each data point for better screen visibility at the Spectrum’s resolution. - Line 9061 (
PRINT AT 3,3;y;" ";x,) appears isolated and is likely a debug remnant from development, unconnected to the main flow of the module. - The
GO TO 4000at line 9870 is a branch to an external caller line that is not present in this listing, confirming the modular design intent. - Black-on-white-inverted scheme (BORDER 0, PAPER 0, INK 7) maximizes contrast for the graph lines.
Potential Anomalies
- Line 9061 is far outside the 9850–9991 block and prints
yandxwithout context; it is almost certainly a stray debug line included by accident in the listing. - The
DIM A(128,44)at line 9865 is skipped by theGO TO 9875at line 9860, so the array must be dimensioned externally or via the demo path at line 9935. If neither path has run, the display routine will produce an error. - The inner loop runs
Yto 170 in steps of 4, giving indices up toY/4 = 42, which is within the declared bound of 44 — no out-of-bounds access occurs.
Content
Source Code
9061 PRINT AT 3,3;y;" ";x,
9850 REM 07;10 PM 05/03/85 GWG GRAPH.2 DISPLAYS A TWO DIMENSION ARRAY IN 3D
9855 BORDER 0: PAPER 0: INK 7: CLS
9860 GO TO 9875
9865 DIM A(128,44)
9870 GO TO 4000
9875 LET A1=0
9880 LET Y1=0
9885 LET C=0
9890 FOR X=2 TO 255 STEP 2: REM DISPLAY ROUTINE
9895 FOR Y=4 TO 170 STEP 4
9900 LET X1=X+INT (((.05*(Y/50))*(127-X))): REM SETS ASPECT RATIO
9905 LET Y1=A(X/2,Y/4): REM READS VALUE OF POINT IN ARRAY
9910 IF (Y+Y1)/2>C THEN PLOT X1,(Y+Y1)/2: DRAW 2,0: LET C=(Y1+Y)/2: REM PLOT IF > THAN LAST PT
9915 NEXT Y
9920 LET C=0
9925 NEXT X
9930 STOP
9935 DIM A(128,44): REM INIT ARRAY
9945 FOR Y=1 TO 44: REM DEMO DATA GENERATOR
9950 FOR X=1 TO 128
9955 LET Y1=INT (70/(1+ABS (10-X))*(10/(1+ABS (15-Y))))
9960 LET Y1=Y1+INT (90/(1+ABS (80-X))*(10/(1+ABS (28-Y))))
9961 PRINT AT 3,3;"Filling A(";x;",";y;")",
9965 LET Y1=Y1+INT (90/(1+ABS (128-X))*(10/(1+ABS (44-Y))))
9970 IF Y1>175 THEN LET Y1=175: REM SETS UPPER CUTOFF LEVEL
9975 LET A(X,Y)=Y1
9980 NEXT X
9985 NEXT Y
9990 GO TO 9855
9991 REM "GRAPH.3" BY Jerry Goegelein
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
