1 rem ***  surface  ***
2 rem  a 3d function plotter for thoreau basic.
3 rem
4 rem  z = f(x,y), drawn as profiles from front to back
5 rem  with hidden-line removal by the floating horizon:
6 rem  a point is drawn only where it rises above, or
7 rem  falls below, every nearer point in its column.
8 rem
9 rem  the whole surface lives in one line - line 40, the
10 rem  def fn. edit that line and you plot a different world.
11 rem
12 rem  here: sin(r)/r, a stone dropped in still water -
13 rem  moor-green in the troughs, gorse-yellow on the
14 rem  crests, over a birchnight field.
15 rem
20 cls
30 gw = gramaxx : gh = gramaxy
40 def fnz(u,v) = sin(sqr(u*u+v*v)+.0001) / (sqr(u*u+v*v)+.0001)
41 rem  other worlds to drop into line 40:
42 rem   def fnz(u,v)=(cos(u)+cos(v))/2      ' egg-carton, set xr=9
43 rem   def fnz(u,v)=(u*u-v*v)/70           ' a saddle
44 rem
50 ns = 70 : xr = 14 : dw = 2*xr/ns
60 cw = .62*gw/ns : sk = .20*gw/ns : ox = .06*gw
70 ch = .30*gh/ns : zh = .20*gh   : oy = .82*gh
80 rem --- lay down the birchnight field ---
90 for y = 0 to gh
100 line (0,y)-(gw,y), 10, 14, 34
110 next y
120 rem --- clear the two horizons ---
130 dim hu(gw) : dim hl(gw)
140 for x = 0 to gw : hu(x) = gh+1 : hl(x) = -1 : next x
150 dim ax(ns) : dim ay(ns) : dim az(ns)
160 rem --- draw, nearest profile first ---
170 for dep = 0 to ns
180 wy = -xr + dep*dw
190 for acr = 0 to ns
200 wx = -xr + acr*dw
210 z = fnz(wx, wy)
220 ax(acr) = ox + acr*cw + dep*sk
230 ay(acr) = oy - dep*ch - z*zh
240 az(acr) = z
250 next acr
260 pd = 0
270 for acr = 1 to ns
280 x1 = ax(acr-1) : y1 = ay(acr-1)
290 x2 = ax(acr)   : y2 = ay(acr)
300 zc = (az(acr-1)+az(acr))/2 : gosub 500
310 xa = int(x1) : xb = int(x2)
320 if acr > 1 then xa = xa + 1
330 if xb < xa then goto 430
340 for xc = xa to xb
350 if x2 = x1 then yv = y1 else yv = y1 + (y2-y1)*(xc-x1)/(x2-x1)
360 vis = 0
370 if yv < hu(xc) then vis = 1 : hu(xc) = yv
380 if yv > hl(xc) then vis = 1 : hl(xc) = yv
390 if vis = 0 then pd = 0 : goto 420
400 if pd = 1 then line (px,py)-(xc,yv),rr,gg,bb else line (xc,yv)-(xc,yv),rr,gg,bb
410 px = xc : py = yv : pd = 1
420 next xc
430 next acr
440 next dep
450 end
460 rem
500 rem --- colour: moor-green troughs to gorse crests ---
510 t = (zc + .3) / 1.3
520 if t < 0 then t = 0
530 if t > 1 then t = 1
540 rr = int(70 + t*175) : gg = int(120 + t*85) : bb = int(70 - t*30)
550 return
