156 lines
2.8 KiB
Plaintext
156 lines
2.8 KiB
Plaintext
open window 100,100
|
|
window origin "cc"
|
|
backcolor 0,0,0
|
|
clear window
|
|
|
|
tonos = 100
|
|
interv = int(255 / tonos)
|
|
dim shades(tonos)
|
|
|
|
shades(1) = 255
|
|
for i = 2 to tonos
|
|
shades(i) = shades(i-1) - interv
|
|
next i
|
|
|
|
dim light(3)
|
|
|
|
light(0) = 30
|
|
light(1) = 30
|
|
light(2) = -50
|
|
|
|
|
|
sub normalize(v())
|
|
local long
|
|
|
|
long = sqrt(v(0)*v(0) + v(1)*v(1) + v(2)*v(2))
|
|
v(0) = v(0) / long
|
|
v(1) = v(1) / long
|
|
v(2) = v(2) / long
|
|
end sub
|
|
|
|
|
|
sub punto(x(), y())
|
|
local d
|
|
|
|
d = x(0)*y(0) + x(1)*y(1) + x(2)*y(2)
|
|
if d < 0 then
|
|
return -d
|
|
else
|
|
return 0
|
|
end if
|
|
end sub
|
|
|
|
|
|
//* positive shpere and negative sphere */
|
|
dim pos(3)
|
|
dim neg(3)
|
|
|
|
// x, y, z, r
|
|
|
|
pos(0) = 10
|
|
pos(1) = 10
|
|
pos(2) = 0
|
|
pos(3) = 20
|
|
|
|
neg(0) = 0
|
|
neg(1) = 0
|
|
neg(2) = -5
|
|
neg(3) = 15
|
|
|
|
|
|
sub hit_sphere(sph(), x, y)
|
|
local zsq
|
|
|
|
x = x - sph(0)
|
|
y = y - sph(1)
|
|
zsq = sph(3) * sph(3) - (x * x + y * y)
|
|
if (zsq < 0) then
|
|
return 0
|
|
else
|
|
return sqrt(zsq)
|
|
end if
|
|
end sub
|
|
|
|
|
|
sub draw_sphere(k, ambient)
|
|
local i, j, intensity, hit_result, result, b, vec(3), x, y, zb1, zb2, zs1, zs2, ini1, fin1, ini2, fin2
|
|
|
|
ini1 = int(pos(1) - pos(3))
|
|
fin1 = int(pos(1) + pos(3) + .5)
|
|
for i = ini1 to fin1
|
|
y = i + .5
|
|
ini2 = int(pos(0) - 2 * pos(3))
|
|
fin2 = int(pos(0) + 2 * pos(3) + .5)
|
|
for j = ini2 to fin2
|
|
x = (j - pos(0)) / 2 + .5 + pos(0)
|
|
|
|
// ray lands in blank space, draw bg
|
|
result = hit_sphere(pos(), x, y)
|
|
|
|
if not result then
|
|
hit_result = 0
|
|
|
|
//* ray hits pos sphere but not neg, draw pos sphere surface */
|
|
else
|
|
zb1 = pos(2) - result
|
|
zb2 = pos(2) + result
|
|
result = hit_sphere(neg(), x, y)
|
|
if not result then
|
|
hit_result = 1
|
|
else
|
|
zs1 = neg(2) - result
|
|
zs2 = neg(2) + result
|
|
if (zs1 > zb1) then
|
|
hit_result = 1
|
|
elseif (zs2 > zb2) then
|
|
hit_result = 0
|
|
elseif (zs2 > zb1) then
|
|
hit_result = 2
|
|
else
|
|
hit_result = 1
|
|
end if
|
|
end if
|
|
end if
|
|
|
|
if not hit_result then
|
|
color 0,0,0
|
|
dot x, y
|
|
else
|
|
switch(hit_result)
|
|
case 1:
|
|
vec(0) = x - pos(0)
|
|
vec(1) = y - pos(1)
|
|
vec(2) = zb1 - pos(2)
|
|
break
|
|
default:
|
|
vec(0) = neg(0) - x
|
|
vec(1) = neg(1) - y
|
|
vec(2) = neg(2) - zs2
|
|
end switch
|
|
|
|
normalize(vec())
|
|
b = (punto(light(), vec())^k) + ambient
|
|
intensity = (1 - b) * tonos
|
|
if (intensity < 1) intensity = 1
|
|
if (intensity > tonos) intensity = tonos
|
|
color shades(intensity),shades(intensity),shades(intensity)
|
|
dot x,y
|
|
end if
|
|
next j
|
|
next i
|
|
end sub
|
|
|
|
|
|
ang = 0
|
|
|
|
while(true)
|
|
//clear window
|
|
light(1) = cos(ang * 2)
|
|
light(2) = cos(ang)
|
|
light(0) = sin(ang)
|
|
normalize(light())
|
|
ang = ang + .05
|
|
|
|
draw_sphere(2, .3)
|
|
wend
|