--- title: "Contour" id: 70771 type: "computer_media" slug: "contour" url: "http://localhost/computer_media/contour/" markdown_url: "http://localhost/computer_media/contour.md" published_at: "2026-08-23T15:08:14+00:00" modified_at: "2026-08-23T17:18:27+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "Draw two terrain profiles by hand or let a sine-wave generator do it, then watch the program project a contoured 3D landscape in three different orientations." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Graphics" slug: "graphics" taxonomy: "genre" url: "http://localhost/type/graphics/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Contour%20%28198x%29%28-%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" media_type_tags: "Graphics" --- # Contour 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 ```