'=========================================================================== ' Subject: 3D BOX ROTATION Date: 11-28-97 (23:55) ' Author: The ABC Programmer Code: QB, QBasic, PDS ' Origin: voxel@freenet.edmonton.ab.ca Packet: GRAPHICS.ABC '=========================================================================== 'PUBLIC DOMAIN 1993 Peter M. Gruhn 'Converted from Pascal to BASIC by William Yu (11-28-97) 'Program draws a box on screen. Allows user to rotate the box around 'the three primary axes. Viewing transform is simple ignore z. 'I used _Computer_Graphics:_Principles_and_Practice_, Foley et al 'ISBN 0-201-12110-7 as a reference 'Okey dokey. This is kinda slow, and does a nice job of demonstrating the 'problems of repeatedly modifying the same data set. That is, the more and 'more you rotate the box, the more and more distorted it gets. This is 'because computers are not perfect at calculations, and all of those little 'errors add up quite quickly. 'It's because of that that I used reals, not reals. I used floating point 'because the guy doesn't know what is going on at all with 3d, so better to 'look at only the math that is really happening. Besides, I still have to 'think to use fixed point. Whaddaya want for .5 hour programming. ' DIRECTIONS: ' ',' - rotates around the x axis ' '.' - rotates around the y axis ' '/' - rotates around the z axis ' ESC - quits ' All rotations are done around global axes, not object axes. DEFINT A-Z DECLARE SUB Init () DECLARE SUB myline (x1!, y1!, z1!, x2!, y2!, z2!) DECLARE SUB Drawit () DECLARE SUB RotX () DECLARE SUB RotY () DECLARE SUB RotZ () CONST radTheta = 1 * 3.1415926535# / 180'per degrees ' sin and cos on computers are done in radians. TYPE tpointr ' Just a record to hold 3d points x AS SINGLE y AS SINGLE z AS SINGLE END TYPE DIM SHARED box(0 TO 7) AS tpointr ' The box we will manipulate DIM SHARED SetColor AS INTEGER SCREEN 12 Init SetColor = 14 Drawit DO A$ = INKEY$ IF A$ = "," THEN RotX IF A$ = "." THEN RotY IF A$ = "/" THEN RotZ LOOP UNTIL A$ = CHR$(27) END DEFSNG A-Z SUB Drawit ' my model is hard coded. No cool things like vertex and edge and face lists. CALL myline(box(0).x, box(0).y, box(0).z, box(1).x, box(1).y, box(1).z) CALL myline(box(1).x, box(1).y, box(1).z, box(2).x, box(2).y, box(2).z) CALL myline(box(2).x, box(2).y, box(2).z, box(3).x, box(3).y, box(3).z) CALL myline(box(3).x, box(3).y, box(3).z, box(0).x, box(0).y, box(0).z) CALL myline(box(4).x, box(4).y, box(4).z, box(5).x, box(5).y, box(5).z) CALL myline(box(5).x, box(5).y, box(5).z, box(6).x, box(6).y, box(6).z) CALL myline(box(6).x, box(6).y, box(6).z, box(7).x, box(7).y, box(7).z) CALL myline(box(7).x, box(7).y, box(7).z, box(4).x, box(4).y, box(4).z) CALL myline(box(0).x, box(0).y, box(0).z, box(4).x, box(4).y, box(4).z) CALL myline(box(1).x, box(1).y, box(1).z, box(5).x, box(5).y, box(5).z) CALL myline(box(2).x, box(2).y, box(2).z, box(6).x, box(6).y, box(6).z) CALL myline(box(3).x, box(3).y, box(3).z, box(7).x, box(7).y, box(7).z) CALL myline(box(0).x, box(0).y, box(0).z, box(5).x, box(5).y, box(5).z) CALL myline(box(1).x, box(1).y, box(1).z, box(4).x, box(4).y, box(4).z) END SUB SUB Init ' turns on graphics and creates a cube. Since the rotation routines ' rotate around the origin, I have centered the cube on the origin, so ' that it stays in place and only spins. box(0).x = -75: box(0).y = -75: box(0).z = -75 box(1).x = 75: box(1).y = -75: box(1).z = -75 box(2).x = 75: box(2).y = 75: box(2).z = -75 box(3).x = -75: box(3).y = 75: box(3).z = -75 box(4).x = -75: box(4).y = -75: box(4).z = 75 box(5).x = 75: box(5).y = -75: box(5).z = 75 box(6).x = 75: box(6).y = 75: box(6).z = 75 box(7).x = -75: box(7).y = 75: box(7).z = 75 END SUB SUB myline (x1!, y1!, z1!, x2!, y2!, z2!) ' Keeps the draw routine pretty. Pixels are integers, so I round. Since the ' cube is centered around 0,0 I move it over 200 to put it on screen. ' if you think those real mults are slow, here's some rounds too... hey, you ' may wonder, what happened to the stinking z coordinate? Ah, says I, this ' is the simplest of 3d viewing transforms. You just take the z coord out of ' things and boom. Looking straight down the z axis on the object. If I get ' inspired, I will add simple perspective transform to these. There, got ' inspired. Made mistakes. Foley et al are not very good at tutoring ' perspective and I'm kinda ready to be done and post this. LINE (INT(x1!) + 200, INT(y1!) + 200)-(INT(x2!) + 200, INT(y2!) + 200), SetColor END SUB SUB RotX ' if you know your matrix multiplication, the following equations ' are derived from ' [x [ 1 0 0 0 [x',y',z',1] ' y 0 c -s 0 = ' z 0 s c 0 ' 1] 0 0 0 1] DIM i AS INTEGER SetColor = 0 Drawit FOR i = 0 TO 7 box(i).x = box(i).x box(i).y = box(i).y * COS(radTheta) + box(i).z * SIN(radTheta) box(i).z = -box(i).y * SIN(radTheta) + box(i).z * COS(radTheta) NEXT i SetColor = 15 Drawit END SUB SUB RotY ' if you know your matrix multiplication, the following equations ' are derived from ' [x [ c 0 s 0 [x',y',z',1] ' y 0 1 0 0 = ' z -s 0 c 0 ' 1] 0 0 0 1] DIM i AS INTEGER SetColor = 0 Drawit FOR i = 0 TO 7 box(i).x = box(i).x * COS(radTheta) - box(i).z * SIN(radTheta) box(i).y = box(i).y box(i).z = box(i).x * SIN(radTheta) + box(i).z * COS(radTheta) NEXT i SetColor = 15 Drawit END SUB SUB RotZ ' if you know your matrix multiplication, the following equations ' are derived from ' [x [ c -s 0 0 [x',y',z',1] ' y s c 0 0 = ' z 0 0 1 0 ' 1] 0 0 0 1] DIM i AS INTEGER SetColor = 0 Drawit FOR i = 0 TO 7 box(i).x = box(i).x * COS(radTheta) + box(i).y * SIN(radTheta) box(i).y = -box(i).x * SIN(radTheta) + box(i).y * COS(radTheta) box(i).z = box(i).z NEXT i SetColor = 15 Drawit END SUB