'===========================================================================
' Subject: 3D ROTATING CUBE                   Date: 02-12-00 (18:30)       
'  Author: Erlend Rovik                       Code: RAPIDQ                 
'  Origin: e-rovik@online.no                Packet: RAPIDQ.ABC
'===========================================================================
'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä-Äúú ú
'³ *** Filled vector ***
'³
'³ (Hidden-line triangle based filled vector source)
'³
'³ Programmed by SkurK/b. (skurk@multinet.no)
'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ä-Äúú ú
'-----------------------------------------------------------------
'Translated to RapidQ by Preacher / Bizarre Designz (Erlend Rovik)
'-----------------------------------------------------------------
DECLARE SUB Vector
    
Dim NumPoints as integer, ConPts as integer, AngleX as integer, AngleY as integer, AngleZ as integer

NumPoints = 8            ' Number of points in object
ConPts = 12              ' How many connect-lines

DIM Points(NumPoints, 3) as integer
DIM Connects(ConPts, 3) as integer
DIM Rotated(NumPoints, 3) as integer
DIM Sinus(1 TO 720) as integer, CoSin(1 TO 720) as integer

 PI = 3.141592
' Precalc Sine and CoSinus table, so we don't have to
' deal with realtime floating-points
 FOR X = 1 TO 720
  Sinus(X) = INT(SIN(PI * 2 / 512 * X) * 256)
  CoSin(X) = INT(COS(PI * 2 / 512 * X) * 256)
 NEXT X
' Copy DATA lines to our tables..
' Points of object
Points(1, 1)=-50:Points(1, 2)=-50:Points(1, 3)=-50
Points(2, 1)=50:Points(2, 2)=-50:Points(2, 3)=-50
Points(3, 1)=50:Points(3, 2)=50:Points(3, 3)=-50
Points(4, 1)=-50:Points(4, 2)=50:Points(4, 3)=-50
Points(5, 1)=-50:Points(5, 2)=-50:Points(5, 3)=50
Points(6, 1)=50:Points(6, 2)=-50:Points(6, 3)=50
Points(7, 1)=50:Points(7, 2)=50:Points(7, 3)=50
Points(8, 1)=-50:Points(8, 2)=50:Points(8, 3)=50
Points(9, 1)=-50:Points(9, 2)=-50:Points(9, 3)=-50
   
' Connect-Lines data
Connects(1, 1)=5:Connects(1, 2)=1:Connects(1, 3)=8
Connects(2, 1)=1:Connects(2, 2)=4:Connects(2, 3)=8
Connects(3, 1)=6:Connects(3, 2)=5:Connects(3, 3)=7
Connects(4, 1)=5:Connects(4, 2)=8:Connects(4, 3)=7
Connects(5, 1)=2:Connects(5, 2)=6:Connects(5, 3)=3
Connects(6, 1)=6:Connects(6, 2)=7:Connects(6, 3)=3
Connects(7, 1)=1:Connects(7, 2)=2:Connects(7, 3)=4
Connects(8, 1)=2:Connects(8, 2)=3:Connects(8, 3)=4
Connects(9, 1)=4:Connects(9, 2)=3:Connects(9, 3)=8
Connects(10, 1)=3:Connects(10, 2)=7:Connects(10, 3)=8
Connects(11, 1)=5:Connects(11, 2)=6:Connects(11, 3)=1
Connects(12, 1)=6:Connects(12, 2)=2:Connects(12, 3)=1

create sr as qrect:top=0:left=0:right=300:bottom=200:end create
create dr as qrect:top=0:left=0:right=300:bottom=200:end create
create bm as qbitmap:width=500:height=500:end create
create tim as qtimer:enabled=1:interval=5:ontimer=vector:end create
create Form AS QForm
create can as qcanvas:width=form.clientwidth:height=form.clientheight:end create
showmodal
end create 

SUB Vector
' Rotate angles
 IF AngleX < 512 THEN:AngleX = AngleX + 3:ELSE:AngleX = 1:end if
 IF AngleY < 512 THEN:AngleY = AngleY + 5:ELSE:AngleY = 1:end if
 IF AngleZ < 512 THEN:AngleZ = AngleZ + 4:ELSE:AngleZ = 1:end if
' Now let's rotate the points according to angles
 FOR N = 1 TO NumPoints
  X = Points(N, 1)
  Y = Points(N, 2)
  Z = Points(N, 3)
  Ty = ((Y * CoSin(AngleX)) - (Z * Sinus(AngleX))) \ 256
  Tz = ((Y * Sinus(AngleX)) + (Z * CoSin(AngleX))) \ 256
  Tx = ((X * CoSin(AngleY)) - (Tz * Sinus(AngleY))) \ 256
  Tz = ((X * Sinus(AngleY)) + (Tz * CoSin(AngleY))) \ 256
  Ox = Tx
  Tx = ((Tx * CoSin(AngleZ)) - (Ty * Sinus(AngleZ))) \ 256
  Ty = ((Ox * Sinus(AngleZ)) + (Ty * CoSin(AngleZ))) \ 256
  Nx = ((128 * Tx) / (200 - Tz)) + 160
  Ny = (100 - (128 * Ty) / (200 - Tz))
  Rotated(N, 1) = Nx
  Rotated(N, 2) = Ny
  Rotated(N, 3) = Tz
 NEXT N
' And now, let's check if face N is visible, and if we should draw it.
 bm.fillrect 0,0,can.width,can.height,&h000000
 FOR N = 1 TO ConPts
  X1 = Rotated(Connects(N, 1), 1)
  X2 = Rotated(Connects(N, 2), 1)
  X3 = Rotated(Connects(N, 3), 1)
  Y1 = Rotated(Connects(N, 1), 2)
  Y2 = Rotated(Connects(N, 2), 2)
  Y3 = Rotated(Connects(N, 3), 2)
  Z1 = Rotated(Connects(N, 1), 3)
  Z2 = Rotated(Connects(N, 2), 3)
  Z3 = Rotated(Connects(N, 3), 3)
  Visibl = (X3 - X1) * (Y2 - Y1) - (X2 - X1) * (Y3 - Y1)
  IF Visibl < -256 THEN
  ' To see the INSIDE, do "Visible > 256" :)
   bm.LINE X1,Y1,X2,Y2,N*10000
   bm.LINE X2,Y2,X3,Y3,N*10000
   bm.LINE X3,Y3,X1,Y1,N*10000
   ' Remove next line to stop filling and increase speed
   bm.PAINT ((X1+X2+X3)\3,(Y1+Y2+Y3)\3,N*10000,N*10000)
  END IF
 NEXT N
 can.copyrect(sr,bm,dr): 'To Avoid Flicker!
END SUB
