Can anybody provide de-obfuscated/minified source so those of us who understand the principle (tracing rays of light around a scene) can understand the maths?
10 REMĀĘĆĞ$Č*Ēĉ!ăě-ĕ'ď
rem dithering table in comment above consulted by GCOL line?
rem raytracer from https://bbcmic.ro/?t=9ctpk by https://mastodon.me.uk/@coprolite9000
rem deobfuscated and possibly broken by kragen javier sitaker (untested)
20 MODE 1
VDU 5
30 FOR N = 8 TO 247 : rem loop over rows (n) and columns (m) of pixels
FOR M = 0 TO 319
40 X = 0 : rem three-dimensional vector
Y = -.1
Z = 3
U = (M - 159.5)/160 : rem xform screen coords to direction vector
V = (N - 127.5)/160
W = 1/SQR(U*U + V*V + 1) : rem normalize direction vector
U = U * W
V = V * W
I = SGN U : rem derive coordinate of sphere center (i, i, 1)?
G = 1
50 E = X - I : rem beginning of do-while loop
F = Y - I
P = U*E + V*F - W*Z
D = P*P - E*E - F*F - Z*Z + 1
IF D <= 0 then goto 60
T = -P - SQR D
IF T <= 0 then goto 60
X = X + T*U
Y = Y + T*V
Z = Z - T*W
E = X - I
F = Y - I
G = Z
P = 2*(U*E + V*F - W*G)
U = U - P*E
V = V - P*F
W = W + P*G
I = -I : rem if we are reflecting then check other sphere now
GOTO 50 : rem end of do-while loop, we have our escape from the scene geometry
rem color according to y-component of direction vector to get sky gradient
rem if instead y component is negative, make a checkerboard of pieces of sky
60 IF V < 0 then P = (Y + 2)/V : V = -V*((INT(X - U*P) + INT(Z - W*P) AND 1)/2 + .3) + .2
70 GCOL 0, 3 - (48*SQR V + ?(PAGE + 5 + M MOD 4 + N MOD 4*4)/3) DIV 16
80 PLOT 69, 4*M, 4*N
NEXT,
> rem if instead y component is negative, make a checkerboard of pieces of sky
I'd maybe phrase this a bit differently – in both cases it uses the v coordinate to calculate the shade but whereas the sky is a simple gradient, the plane has a "ground fog" type effect that can be adjusted with those +.3 and +.2 magic constants.
The value of v corresponds to how far away the intersection point is. At the horizon v=0 so the color value is just constant 0.2. The closer to the camera, the more the checker value (0 or 1) contributes. The exact values are probably chosen experimentally, but note the important property that -v*(checker/2+0.3)+0.2 is always between 0 and 1. Note also that 1 means black and 0 white here, as ultimately the value is negated at line 70.
see also https://news.ycombinator.com/item?id=39026517 and https://news.ycombinator.com/item?id=39026495