Basicprogramming(.org) > Code and examples

Raytracing

(1/3) > >>

ZXDunny:
I know it's probably been done before, but this is kinda fun.

A chap on one the BASIC facebook groups I'm involved in wrote a small Sinclair BASIC raytracer - monochrome (naturally) and took 8 hours to complete.

It pretty much pasted into SpecBAS with only one line needing to be altered (and a bug in my INT implementation to be fixed) before it worked - and a bonus was that it took less than 1 second to produce the same image :)

Get the SpecBAS update here: https://drive.google.com/open?id=0B6gXsz43xir_eV9JbWhUZ1Rxc0k

Here's the SpecBAS code:


--- Code: ---10 PAPER 0: INK 15: CLS:
 palette 16,255,255,255:
 palette 32,0,192,255:
 palette 255,0,0,192:
 rainbow 16 to 32:
 rainbow 32 to 255
20 read spheres:t=msecs:
 DIM c(spheres,3),r(spheres),q(spheres),cl(4):
 w=scrw/2,h=scrh/2,s=0:
 cl(1)=6,cl(2)=1,
 cl(3)=cl(1)+8,cl(4)=cl(2)+8
30 FOR k=1 TO spheres:
    READ c(k,1),c(k,2),c(k,3),r:
    r(k)=r,q(k)=r*r:
 NEXT k
40 data 6:
 DATA -0.3,-0.8,3,0.6
50 DATA 0.9,-1.4,3.5,0.35:
 data 0.7,-0.45,2.5,0.4:
 data -0.5,-0.3,1.5,0.15:
 DATA 1.0,-0.2,1.5,0.1:
 DATA -0.1,-0.2,1.25,0.2
60 FOR i=1 TO scrh:
    FOR j=0 TO scrw-1
70       x=0.3,y=-0.5,z=0,ba=3:
       dx=j-w,dy=h-i,dz=(scrh/480)*600,
       dd=dx*dx+dy*dy+dz*dz
80       n=-(y>=0 OR dy<=0):
       IF n=0 THEN
          s=-y/dy
90       FOR k=1 TO spheres:
          px=c(k,1)-x,py=c(k,2)-y,pz=c(k,3)-z,
          pp=px*px+py*py+pz*pz,
          sc=px*dx+py*dy+pz*dz:
          IF sc<=0 THEN
             GO TO 120
100          bb=sc*sc/dd,
          aa=q(k)-pp+bb:
          IF aa<=0 THEN
             GO TO 120
110          sc=(SQR bb-SQR aa)/SQR dd:
          IF sc<s OR n<0 THEN
             n=k,s=sc
120       NEXT k
130       IF n<0 THEN
          plot ink 16+(dy*dy/dd)*240;j,scrh-i:
          go to 200
140       dx=dx*s,dy=dy*s,dz=dz*s,dd=dd*s*s,
       x+=dx,y+=dy,z+=dz:
       IF n<>0 THEN
           nx=x-c(n,1),ny=y-c(n,2),nz=z-c(n,3),
          nn=nx*nx+ny*ny+nz*nz,
          l=2*(dx*nx+dy*ny+dz*nz)/nn,
          dx=dx-nx*l,dy=dy-ny*l,dz=dz-nz*l:
          GO TO 80
160       FOR k=1 TO spheres:
          u=c(k,1)-x,
          v=c(k,3)-z:
          IF u*u+v*v<=q(k) THEN
             ba=1:
             go to 180
170       NEXT k
180       IF (x-INT x>.5)=(z-INT z>.5) THEN
          ik=cl(ba)
       else
          ik=cl(ba+1)
190       plot ink ik;j,scrh-i       
200    NEXT j:
 NEXT i
210 print at 0,0;transparent 1;ink 0;"Time: ";(msecs-t)/1000;" secs":
 pause 0:

--- End code ---

It looks better in the SpecBAS editor, I promise.

And finally, here's the image (I changed the output up to 1920x1024 so it takes almost 30 seconds to make this image):



Had a nice fun day with this one - it's not something I personally would have done in Sinclair BASIC but I'm glad someone did!

Mike Lobanovsky:
Impressive! 8)

Exactly what was the problem with INT? Was it the need to round it rather than truncate or vice versa?

ZXDunny:

--- Quote from: Mike Lobanovsky on October 01, 2018, 01:39:49 PM ---Exactly what was the problem with INT? Was it the need to round it rather than truncate or vice versa?

--- End quote ---

On the Sinclair Spectrum, INT rounds down to negative infinity - 2.8 == 2, -3.6 == -4. In SpecBAS, I was rounding towards zero instead which caused the grid at the bottom (a simple XOR pattern) to fail to draw for any x < 0. So a bonus is that I'm now a little more compatible with the original 80s BASIC.

Mike Lobanovsky:

--- Quote from: ZXDunny on October 01, 2018, 02:39:01 PM ---... 2.8 == 2, -3.6 == -4.
--- End quote ---

That is, it rounds towards the nearest even whole number. IIRC VB and PB also behave in that manner.

ZXDunny:

--- Quote from: Mike Lobanovsky on October 01, 2018, 06:56:12 PM ---
--- Quote from: ZXDunny on October 01, 2018, 02:39:01 PM ---... 2.8 == 2, -3.6 == -4.
--- End quote ---

That is, it rounds towards the nearest even whole number. IIRC VB and PB also behave in that manner.

--- End quote ---

Almost, as -3.1 will also round to -4.

Navigation

[0] Message Index

[#] Next page

Go to full version