Contour

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Graphics

Contour is an interactive 3D terrain visualization program that lets the user draw two elevation profiles — a lower (south) curve and an upper (north) curve — by pressing keys to adjust height in real time as a cursor advances across the screen. The two profiles are stored in arrays L() and H() indexed by horizontal position. From these profiles, the program can render a south-to-north cross-section using DRAW with a radian-angle argument, a west-to-east cross-section by interpolating 20 intermediate points per column, or both combined. A built-in sine-wave terrain generator (lines 1000–1060) auto-populates the L() array with a sinusoidal landscape for users who prefer not to draw manually. The program reuses the same two 127-element arrays for both drawing passes, with the second pass offset by D=127 so the cursor plots into the right half of the display.


Program Structure

The program is organized into three functional phases:

  1. Profile drawing (lines 10–130): The user interactively draws two elevation curves — a lower (L) and an upper (H) — using key presses, or jumps to the sine-wave generator at line 1000.
  2. Rendering (lines 140–290): The user chooses a projection direction and the stored profiles are rendered as a contour plot in one or both orientations.
  3. Sine-wave generator (lines 1000–1060): Auto-populates the L() array with a sinusoidal curve before falling through to the rendering phase.

Interactive Profile Drawing

Lines 40–130 run a FOR T=1 TO 2 outer loop that collects two profiles. In pass 1 (T=1), values are stored in L(G); in pass 2 (T=2), in H(G). The variable D is used as a horizontal offset: D=-1 in the first pass (so G+D starts at 0) and D=127 in the second pass, shifting the second curve to the right half of the display. The variable A tracks the current height, modified by key presses:

  • "9" — hold height (no change)
  • "0" — increment A by 1
  • "5" — decrement A by 1
  • "7" — increment A by 0.5
  • "6" — decrement A by 0.5
  • "1" — jump to sine-wave auto-generator

Line 95 loops back to line 60, so the inner FOR G loop only advances when a valid key is pressed and a PLOT is made — effectively pausing until user input.

Rendering: South-to-North Projection (Lines 150–192)

For option 1, the program steps through A=0 TO 126 STEP 4 and for each column plots a point at L(A+1) then uses DRAW 128, delta, D where D is a user-supplied radian angle and delta = (H(A+1)-88) - L(A+1). This uses the three-argument form of DRAW (x, y, angle) to draw arcs, giving the contour lines a curved perspective appearance. The midpoint 88 is used as a vertical reference baseline.

Rendering: West-to-East Projection (Lines 200–260)

For option 2, the program iterates over all 127 columns and for each interpolates 20 intermediate points between the lower and upper elevations. Each step advances A (horizontal) by 6.35 and B (vertical) by 4.4 plus a proportional share of (H(T+1)-88) - L(T+1) divided by 20. The constants 6.35 and 4.4 scale the 127-pixel-wide profile into a diagonal perspective raster across the screen.

Sine-Wave Auto-Generator (Lines 1000–1060)

Instead of drawing a profile manually, pressing "1" routes to line 1000, which synthesizes a sine-wave terrain into L(). A sine accumulator A (angle, starting at 1) advances by 0.04 per step, while D (horizontal position) advances by 0.5 and B (elevation, starting at 43) accumulates SIN A. The loop runs until D >= 127, storing each computed elevation via L(INT D) = B. After generation, execution falls through to line 130 to set up the second profile pass using GO TO 130.

Notable Techniques and Idioms

  • The OVER 1 mode at line 140 is used to erase the axes drawn in line 10 by redrawing them in XOR mode, clearing them before the contour plot begins.
  • The FOR loop variable G is reused as a horizontal pixel counter, with plotting done inside the loop body conditionally — the loop only advances when a key is pressed and a plot occurs.
  • The program uses RUN (lines 192, 290) rather than GO TO 10 to restart, which also clears all variables and arrays, giving a clean slate.
  • The midpoint constant 88 appears to represent the vertical center of the drawing area (175/2 ≈ 87.5), used as a baseline reference for computing the arc height delta.

Bugs and Anomalies

  • The sine-wave generator only fills L() and then goes to line 130, which resets A=131 and D=127 and runs a second manual-draw pass for H() — so the user must still draw the upper profile by hand even when using the auto-generator.
  • Arrays are dimensioned as DIM L(127) and DIM H(127) (1-indexed, 127 elements), but the loops reference indices from G=1 to 127, and line 205 uses T+1 for T=0 TO 126 — all accesses stay within bounds.

Source Code

   10 PLOT 127,0: DRAW 0,175: PLOT 0,87: DRAW 255,0
   20 DIM L(127): DIM H(127)
   30 LET A=43
   35 LET D=-1
   40 FOR T=1 TO 2
   50 FOR G=1 TO 127
   60 IF INKEY$="9" THEN PLOT G+D,A: GO TO 100
   70 IF INKEY$="0" THEN LET A=A+1: PLOT G+D,A: GO TO 100
   75 IF INKEY$="5" THEN LET A=A-1: PLOT G+D,A: GO TO 100
   80 IF INKEY$="7" THEN LET A=A+.5: PLOT G+d,A: GO TO 100
   90 IF INKEY$="6" THEN LET A=A-.5: PLOT G+D,A: GO TO 100
   91 IF INKEY$="1" THEN GO TO 1000
   95 GO TO 60
  100 IF T=1 THEN LET L(G)=A: GO TO 115
  110 LET H(G)=A
  115 NEXT G
  130 LET A=131: LET D=127: NEXT T
  140 OVER 1: PLOT 127,0: DRAW 0,175: PLOT 0,87: DRAW 255,0: OVER 0
  145 PRINT "(1) SOUTH TO NORTH or           (2) WEST  TO EAST ?": INPUT O
  146 IF O=1 THEN INPUT "RADIANS ?";D: PRINT AT 0,0;"                                                   ": GO TO 150
  147 IF O=2 THEN GO TO 200
  148 GO TO 145
  150 FOR A=0 TO 126 STEP 4
  160 PLOT A,L(A+1)
  170 DRAW 128,88+((H(A+1)-88)-L(A+1)),D
  180 NEXT A
  190 INPUT "WEST TO EAST ASWELL ?";O$
  191 IF o$="Y" OR o$="y" THEN GO TO 200
  192 RUN 
  200 PRINT AT 0,0;"                                                   "
  205 FOR t=0 TO 126
  210 LET B=L(T+1): LET A=T
  220 FOR G=1 TO 20
  230 LET A=A+6.35: LET B=B+4.4
  240 LET B=B+((H(T+1)-88)-L(T+1))/20
  245 PLOT A,B
  250 NEXT G
  260 NEXT T
  270 INPUT "SOUTH TO EAST ASWELL ?";O$
  280 IF O$="Y" OR O$="y" THEN LET O=1: GO TO 146
  290 RUN 
 1000 LET B=43
 1010 LET A=1
 1015 LET D=1
 1020 LET L(INT D)=B
 1021 PLOT D,B
 1030 LET B=B+(SIN A)
 1040 LET A=A+.04: LET D=D+.5
 1045 IF D>=127 THEN GO TO 1060
 1050 GO TO 1020
 1060 GO TO 130

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.