Drop

Developer(s): James Jones
Date: 198x
Type: Program
Platform(s): TS 2068

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.

VariableMeaningValue
rhoDistance from origin to eye30
dPerspective scale factor350
thetaAzimuth angle (radians)0.3
phiElevation angle (radians)1
cx, cyScreen center offsets127, 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.

Content

Appears On

Capital Area Timex Sinclair User Group’s Library Tape.

Related Products

Related Articles

Related Content

Image Gallery

Drop

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

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

Scroll to Top