Graph 2

Developer(s): Gerald W. Goegelein
Date: 1985
Type: Program
Platform(s): TS 2068
Tags: Demo

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 RangeRole
9850–9855REM header, screen setup (BORDER/PAPER/INK/CLS)
9860–9870Entry branch: skips DIM, falls through to GO TO 4000 (caller)
9875–9930Main 3D display routine
9935–9990Demo data generator and array initializer
9991Author 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,0 after each PLOT (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 4000 at 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 y and x without 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 the GO TO 9875 at 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 Y to 170 in steps of 4, giving indices up to Y/4 = 42, which is within the declared bound of 44 — no out-of-bounds access occurs.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Graph 2

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.

Scroll to Top