--- title: "Drop" id: 64603 type: "computer_media" slug: "drop" url: "http://localhost/computer_media/drop/" markdown_url: "http://localhost/computer_media/drop.md" published_at: "2026-03-04T19:46:16+00:00" modified_at: "2026-03-30T21:41:45+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/03/7-DROP.png" excerpt: "A ripple-surface 3D plotter uses perspective projection and trigonometric rotation to render z=cos(0.1·(x²+y²)) as a connected wireframe mesh." 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/" indiv: - name: "James Jones" slug: "james-jones" taxonomy: "indiv" url: "http://localhost/indiv/james-jones/" genre: - name: "Graphics" slug: "graphics" taxonomy: "genre" url: "http://localhost/type/graphics/" media_contents: - id: 64507 title: "CATS Library Tape 9" type: "computer_media" url: "http://localhost/computer_media/cats-library-tape-9/" media_type: "Program" programmers: - name: "James Jones" slug: "james-jones" taxonomy: "indiv" url: "http://localhost/indiv/james-jones/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Drop%20%28198x%29%28Jones%2C%20James%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/03/7-DROP.png" media_type_tags: "Graphics" --- # Drop This program renders a 3D surface plot of the function z = cos(0.1·(x²+y²)) — a “ripple” or “drop” surface — using perspective projection onto the screen. It implements a full 3D-to-2D coordinate transform at lines 20–30, applying rotation angles theta and phi with precomputed sine/cosine values, plus a perspective divide by ze (the depth coordinate). The plot is drawn as a series of connected line segments using DRAW, scanning x from 10 to -10 and y from -10 to 10, with boundary clipping at line 110 to avoid off-screen coordinates. The program is a TS2068 conversion of an algorithm from the book “Microcomputer Graphics” by Roy E. Myers, credited to James N. Jones of Amarillo, Texas. *** ## Program Analysis ### Program Structure The program is organized into a few distinct functional blocks: 1. **Lines 1–7:** REMs, screen setup (BRIGHT, INK), and initial values for `sx1`/`sy1`. 2. **Line 10:**`GO TO 40` skips over the subroutine definitions at lines 20–30. 3. **Lines 20–30:** Subroutine — performs 3D rotation and perspective projection, returning screen coordinates `sx`, `sy`. 4. **Line 40:** Initializes all projection parameters. 5. **Line 50:** Defines the surface function `FN z(x)` (also uses the outer variable `y`). 6. **Lines 70–150:** Double nested loop over x and y, computing and drawing the surface. 7. **Line 9998:** Saves the program. ### 3D Projection Subroutine (Lines 20–30) The subroutine at lines 20–30 implements a standard perspective projection pipeline. Line 20 computes eye-space coordinates using a rotation matrix parameterized by `theta` (azimuth) and `phi` (elevation), with precomputed values `s1`, `s2`, `c1`, `c2`. Line 30 applies the perspective divide — dividing by `ze` (depth) and scaling by `d` — to produce screen pixel coordinates `sx` and `sy`, offset by the screen center `cx`, `cy`. | Variable | Meaning | Value | | --- | --- | --- | | `rho` | Distance from origin to eye | 30 | | `d` | Perspective scale factor | 350 | | `theta` | Azimuth angle (radians) | 0.3 | | `phi` | Elevation angle (radians) | 1 | | `cx`, `cy` | Screen center offsets | 127, 87 | ### Surface Function Line 50 defines `DEF FN z(x)=COS(.1*(x*x+y*y))`. Notably, the formal parameter is `x`, but the function also references the outer variable `y` from the enclosing loop — a common BASIC technique where `DEF FN` closes over the current value of non-parameter variables. This means the function is effectively a two-variable surface z = cos(0.1·(x²+y²)), producing the classic circular “water drop” ripple pattern. ### Drawing Loop and Clipping The outer loop (line 70) iterates `x` from 10 down to -10 in steps of -1; the inner loop (line 90) iterates `y` from -10 to 10. For each (x, y) pair, the surface value is computed and the subroutine called. Line 110 clips points that project outside the display area (0–255 horizontally, 0–175 vertically), resetting the `fl` flag to force a new `PLOT` rather than a `DRAW` on the next valid point. Line 120 issues a `PLOT` only when starting a new stroke (`fl=0`), and line 130 issues a `DRAW` relative to the previous screen point stored in `sx1`/`sy1`. This pen-up/pen-down idiom avoids drawing lines across clipped gaps. ### Notable Techniques and Idioms - **Precomputed trig:**`s1`, `s2`, `c1`, `c2` are computed once at line 40 and reused in every iteration of the inner subroutine, avoiding repeated calls to `SIN`/`COS`. - **Relative DRAW:** Line 130 uses `DRAW (sx1-sx),(sy1-sy)` rather than absolute coordinates, consistent with the Spectrum/TS2068 `DRAW` syntax which takes relative offsets. - **INK color cycling:**`INK 0` is set at line 136 (inside the y loop) and `INK 7` is restored at line 145 (after each x row), suggesting an intent to draw successive rows in alternating ink — though since `ink=0` is set at line 4 and never otherwise used, this coloring scheme has limited practical effect beyond the final state. - **Flag variable `fl`:** The variable `fl` acts as a pen-state flag. It is reset to 0 at the start of each y-row (line 80) and on clipping (line 110), but is never explicitly set to 1 after the initial `PLOT` at line 120 — meaning every visible point after a clip or row-start triggers a `PLOT` and then a `DRAW` from the previous stored position. This is intentional: the `DRAW` at line 130 always executes regardless of `fl`, connecting back to `sx1`/`sy1`. ### Bugs and Anomalies - The variable `l` is set to 1 at line 120 (`LET l=1`) but is never read anywhere else in the program. This appears to be vestigial code, possibly a remnant from the original book listing where `l` may have tracked pen state more explicitly. - The `fl` flag is never set back to 1 after a successful plot, so after a clipped point the logic correctly starts a new stroke, but between unclipped points the `DRAW` at line 130 runs unconditionally regardless of `fl`‘s value. The visual result is still correct because `sx1`/`sy1` are updated at line 135 and the relative draw connects adjacent projected points. - The initial values `sx1=0`, `sy1=170` (lines 5 and 145) are arbitrary starting points for the first `DRAW` of each row; the first segment of each row will draw from this fixed screen position, which may produce stray lines at the beginning of each x-iteration. ## 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 "DROP" LINE 1 ```