Vic's QBasic Programming Tutorial Basic Tutorial VIII 3D !!!!!! The half a*s'd way to do it ----------------------------------------------------------------------------- Excuse my language, but there is no other way to describe it... If you are anything like me you have searched the internet for information on how to programm in 3D and came to the conclusion that it is one topic that is best done the H alf A *s'd W ay. Lets refer to that as HAW... With HAW you don't have to go into a great deal of logical crap... That was a very HAW sentance wasn't it?... If you are a genious 3D programmer you understand what is being done and why it is being done... With HAW you only have to remember a few equations... you don't have to understand it, just use it... First off, I will list every equation that you will need to know for 3d and 2d rotations and how to put a 3d object on a 2d screen... I allways print out a copy and put it in my wallet, just in case I need it... ---------------------------------------------------------------------------- If I were you, I would copy what is below into a new document and print it so you don't have to keep looking in this tutorial... --- Start copying ***********************| COSINE TABLES |************************* c! = cos(angle * 3.14 / 180) s! = sin(angle * 3.14 / 180) ***********************| NON 3D ROTATION |*********************** X2 = X * c! + Y * s! Y2 = Y * c! - X * s! ***********************| 3D ROTATIONS |************************** Theta = Left Right Phi = Up Down X2 = -x * s!(theta) + y * c!(theta) Y2 = -x * c!(theta) * s!(phi) - y * s!(theta) * s!(phi) - Z * c!(phi) + p Z2 = -x * c!(theta) * c!(phi) - y * s!(theta) * c!(phi) + Z * s!(phi) ***********************| 2D to 3D Conversion |******************* X3 = 256 * (x2 / (Z2 + zCenter)) + xCenter Y3 = 256 * (y2 / (Z2 + zCenter)) + yCenter ***************| FIND OUT WHAT DIRECTION IT IS GOING |********** stepx = s!(angle) stepy = c!(angle) --- Stop!, open a new document and paste it into it... ----------------------------------------------------------------------------- I copied this out of a document that I wrote earlier in my programming experiance, This also has information that you won't need for this tutorial. But you will find that it will come in handy in later tutorials... When you print this make sure that all of the equations fit in one line. If they are too long then you will have to make the font smaller... ------------- Don't look at the information and try to figure it out unless you are a math proffesor... I admit that I have no idea how some of them work... --- First, what we need to do in 3D programming is set up some Cosine and Sine tables... Why? Because its faster than calculating them each time you ask. If you don't understand what a cosine table is, just remember, It never ever ever ever changes... It will allways equall the same thing no matter what. Do this allways, don't change anything... First, you have to DIM the variables... If you look at the top line of the document you printed up you will see C! =... and S! =... Those are our variables... Dim them like this... Dim C!(360), S!(360) Q. What is the 360 for? A. There are 360 degrees in a complete circle... 360 = 0 and 0 = 360... After you declare your variables, do this... For i = 1 to 360 C!(i) = Cos( i * 3.14 / 180) S!(i) = Sin( i * 3.14 / 180) Next All together now!! --- Dim C!(360), S!(360) For i = 1 to 360 C!(i) = Cos( i * 3.14 / 180) S!(i) = Sin( i * 3.14 / 180) Next --- Thats it, Your Cosine tables are finished... ------------------------- Now, I should go into some explaination of how 3d on a computer works... You will find this in any 3d tutorial, If you allready know this just skip past it... On a 2D plane you have X and Y coordinates right? If you don't remember that I suggest that you look over the past tutorials... On a 3D plane you have X, Y and Z coordinates... What is the Z for? As you can probably guess it stands for how far away an object is from the thing that is viewing it... Here is an ASCII example... | | |Y | | | X 0__________ Z / / / The Zero (0) In the middle Is the point that holds the X,Y, & Z coords... Everything you draw on the screen will be made of individual points that are usually connected by lines... Here is how we would draw a square in 3D... 0----------0 /| / | 0_|_______0 | | | | | | 0_______|_ 0 | / | / |/ |/ 0---------0 Each 0 has its own X,Y, & Z coordinate... Here, lets give a number to each point... 5----------6 /| / | 1_|_______2 | | | | | | 7_______|_ 8 | / | / |/ |/ 3---------4 Lets now draw it so it has walls... 0----------0 / / | 0_________0 | | | | | | 0 | | / | |/ 0---------0 That was just to show you how it is supposed to look... Lets take another look at the numbered one... 5----------6 /| / | 1_|_______2 | | | | | | 7_______|_ 8 | / | / |/ |/ 3---------4 look at points 1 and 5, If you think about it 1 is closer to you than 5 right? that means that point 1 has a lower Z value and point 5 has a greater value because it is farther away. Do you understand About the 3 values yet? Lets review... X shows things left and right Y shows things up and down Z shows things close and far away X and Y are the same 2D and 3D If you trully don't understand what Z is, don't worry you will... --------------------------------------------------------------------------- Now that We have the X,Y,Z values figured out we have to discuss ROTATIONS: Rotations are THE most dificult part of 3D programming... The equations for getting them are very large and uncomprehensible. PLEASE don't ask me what they meen... Besides these formulas there are other things about rotations that you need to know. First Is The ammount to rotate things é = Theta í = Phi This might be reversed, I'm Not sure... Theta controls rotations up and down Phi controls rotations left and right Thats it... ---------------------------------------------------------------------------- Ok, Lets get back to the programming itself... Remember, first we declare the variables... Then what? We tell the computer what the X, Y, Z coord are... In this example lets say that... X=50 Y=50 Z=5 Nice, that means that it is in the middle of the screen and 50 away from the screen, that's In the screen away from you... How do we put the Z coordinate on a 2D screen? Very simple... We convert The X and Y coords to involve the Z coordinate... How? Like this... X = X / Z which is the same as X = X Divided by Z Y = Y / Z Here is an example how to put the X,Y,Z coords on the screen '--- Start X=50 Y=50 Z=5 x2 = x / Z y2 = y / Z screen 13 Pset (x2,y2),15 '--- End That was a very useless example huh, I won't dissapoint you again... I promise... Now, Its time for a rotation!!! Lets rotate that point using the formulas that we printed out earlier... '---- START EXAMPLE 'Remember to get the cosine tables... DIM c!(360), s!(360) FOR i = 1 TO 360 c!(i) = COS(i * 3.14 / 180) s!(i) = SIN(i * 3.14 / 180) NEXT x = 50 'X,Y,Z coords... y = 50 Z = 5 xcenter = 150 'Where you want the sprite to revolve ycenter = 150 'around. zcenter = 256 'Initial distance... Keep it 256 all the time phi = 1 'starting coord... theta = 1 SCREEN 7, 0, 1, 0 'Screen 7 with 1 page... DO 'Start Loop press$ = INKEY$ 'Get keypresses 'The below is directly from the 3D rotations part... '********************************************************************** x2 = -x * s!(theta) + y * c!(theta) y2 = -x * c!(theta) * s!(phi) - y * s!(theta) * s!(phi) - Z * c!(phi) + p Z2 = -x * c!(theta) * c!(phi) - y * s!(theta) * c!(phi) + Z 'The below is directly from the 3D to 2D part... '********************************************************************* x3 = 256 * (x2 / (Z2 + zcenter)) + xcenter y3 = 256 * (y2 / (Z2 + zcenter)) + ycenter CLS CIRCLE (x3, y3), 4, 1 'Draw a circle at X3 and Y3 coords on the screen... PCOPY 1, 0 'Copy the page to the screen... 'Look at this... 'This controls the rotation... 'Phi is up and down and theta is left and right 'Put a ' or REM in front of one of them to see what I mean... phi = phi + 1 theta = theta + 1 IF phi > 360 THEN phi = phi - 360 'All this just makes sure that IF theta > 360 THEN theta = theta - 360 'The Phi and Theta stay under 360 LOOP UNTIL press$ = CHR$(27) '----- THATS IT!! I bet your like, Wow, big deal... If the above confuses you at all, remember... the Big long formulas are taken directly from the page you printed earlier... The Xcenter and Ycenter just give it a point to revolve around... you can keep it 0, but then it would revolve around the uper right corner of the screen... The Zcenter is how far away you want the point that it revolves around... If i were you, I would keep it at 256... ------------- GREAT! you can revolve one point around and around... Its not over yet... Lets now talk about how to revolve more than one point without having to type the formulas over and over again... --- Lets first talk about how to declare more than one value in an array... pretend you want to have X = 3 different things... you want the first x to equall 1, the second to = 15 and the third to equall 22... how would you do that... Like this... First you Dim the variable... DIM X(3) the (3) means that you want it to equall 3 different things... Once it is dimmed you tell it what to equall... X(1) = 1 X(2) = 15 X(3) = 22 Done... Now, X equalls 3 things... Watch 'Copy this in QBASIC '--- Start... DIM X(3) X(1) = 1 X(2) = 15 X(3) = 22 print X(1) Print X(2) print X(3) '--- Finish Look at that... You could do it quicker like this... 'Copy this in QBASIC '--- Start... DIM X(3) X(1) = 1 X(2) = 15 X(3) = 22 for i = 1 to 3 print X(i) next '--- Finish That does the same thing doesn't it? only, you don't have to type in so much... There is one more way to make this faster... That is done by puting the values of X(1) =1... into a DATA statement... It is done like this... 'Copy this in QBASIC '--- Start... DIM X(3) For i = 1 to 3 read X(i) Next for i = 1 to 3 print X(i) next DATA 1, 14, 22 '--- Finish If you count the line numbers it doesn't make that much of a difference... But imagine if you had more than 3 numbers... Lets try 25... 'Copy this in QBASIC '--- Start... DIM X(25) For i = 1 to 25 read X(i) Next for i = 1 to 25 print X(i) next DATA 1,2,55,11,66,15,17,74,89,28,85,28,58,28,58 DATA 18,15,10,61,10,69,18,18,47,40 '--- Finish Now imagine if we had to do that first one and put X(1)=... 25 times!! Now that makes it smaller huh?! -------- OK! Time to make TWO points revolve around... '---- START>>> 'Remember to get the cosine tables... DIM c!(360), s!(360) DIM SHARED x(2), y(2), z(2) 'Declare how many points per DIM x2(2), y2(2), z2(2) 'XYZ coordinate... DIM x3(2), y3(2) FOR i = 1 TO 360 c!(i) = COS(i * 3.14 / 180) s!(i) = SIN(i * 3.14 / 180) NEXT x(1) = 50 y(1) = 50 z(1) = 25 x(2) = 50 y(2) = 50 z(2) = -25 xcenter = 150 'Where you want the sprite to revolve ycenter = 100 'around. zcenter = 256 'Initial distance... Keep it 256 all the time phi = 1 'starting coord... theta = 1 SCREEN 7, 0, 1, 0 'Screen 7 with 1 page... DO 'Start Loop press$ = INKEY$ 'Get keypresses 'The below is directly from the 3D rotations part... '********************************************************************** FOR i = 1 TO 2 'Calculate for both points... x2(i) = -x(i) * s!(theta) + y(i) * c!(theta) y2(i) = -x(i) * c!(theta) * s!(phi) - y(i) * s!(theta) * s!(phi) - z(i) * c!(phi) + p z2(i) = -x(i) * c!(theta) * c!(phi) - y(i) * s!(theta) * c!(phi) + z(i) NEXT 'The below is directly from the 3D to 2D part... '********************************************************************* FOR i = 1 TO 2 'Same here... x3(i) = 256 * (x2(i) / (z2(i) + zcenter)) + xcenter y3(i) = 256 * (y2(i) / (z2(i) + zcenter)) + ycenter NEXT CLS FOR i = 1 TO 2 CIRCLE (x3(i), y3(i)), 4, 1 'Draw a circle at X3 and Y3 coords on the screen... NEXT LINE (x3(1), y3(1))-(x3(2), y3(2)), 15 'connect the 2 dots... PCOPY 1, 0 'Copy the page to the screen... 'Look at this... 'This controls the rotation... 'Phi is up and down and theta is left and right 'Put a ' or REM in front of one of them to see what I mean... phi = phi + 1 theta = theta + 1 IF phi > 360 THEN phi = phi - 360 'All this just makes sure that IF theta > 360 THEN theta = theta - 360 'The Phi and Theta stay under 360 LOOP UNTIL press$ = CHR$(27) '-------- STOP>>> That might not look like much, but it is going around a point in 3d space.. that is a great feet for QBASIC... -------------------------------------------------------------------------- I'll leave you with one more programming example... A ROTATING SQUARE...!!! '---- Start Copying... DIM c!(360), s!(360) 'Now dim the array for Eight points... 'Remember, a cube has Eight Points in it... DIM x(8), y(8), Z(8), x2(8), y2(8), Z2(8), x3(8), y3(8) FOR i = 1 TO 360 c!(i) = COS(i * 3.14 / 180): s!(i) = SIN(i * 3.14 / 180) NEXT FOR i = 1 TO 8: READ x(i): READ y(i): READ Z(i): NEXT phi = 1: theta = 1 xcenter = 150: ycenter = 100: zcenter = 256 delay = 10000 'You know what this is for... change for speed SCREEN 7, 0, 1, 0 DO press$ = INKEY$ CLS FOR i = 1 TO 8 'This makes you do this 8 times... 'Remember, these are right from the paper you printed up... x2(i) = -x(i) * s!(theta) + y(i) * c!(theta) y2(i) = -x(i) * c!(theta) * s!(phi) - y(i) * s!(theta) * s!(phi) - Z(i) * c!(phi) + p Z2(i) = -x(i) * c!(theta) * c!(phi) - y(i) * s!(theta) * c!(phi) + Z(i) * s!(phi) x3(i) = 256 * (x2(i) / (Z2(i) + zcenter)) + xcenter y3(i) = 256 * (y2(i) / (Z2(i) + zcenter)) + ycenter PSET (x3(i), y3(i)), 15 NEXT 'All these lines just make the box by connecting the points... 'If you erase all the lines you will get just pixels drawn on the screen... LINE (x3(1), y3(1))-(x3(3), y3(3)), 15 LINE (x3(1), y3(1))-(x3(4), y3(4)), 15 LINE (x3(1), y3(1))-(x3(5), y3(5)), 15 LINE (x3(2), y3(2))-(x3(3), y3(3)), 15 LINE (x3(2), y3(2))-(x3(4), y3(4)), 15 LINE (x3(2), y3(2))-(x3(6), y3(6)), 15 LINE (x3(7), y3(7))-(x3(6), y3(6)), 15 LINE (x3(7), y3(7))-(x3(3), y3(3)), 15 LINE (x3(7), y3(7))-(x3(5), y3(5)), 15 LINE (x3(8), y3(8))-(x3(5), y3(5)), 15 LINE (x3(8), y3(8))-(x3(4), y3(4)), 15 LINE (x3(8), y3(8))-(x3(6), y3(6)), 15 PCOPY 1, 0 phi = phi + 1: theta = theta + 1 IF phi > 360 THEN phi = phi - 360 IF theta > 360 THEN theta = theta - 360 FOR i = 1 TO delay: NEXT LOOP UNTIL press$ = CHR$(27) 'These are all of the points... predetermined... 'Remember, there are 8 points in a cube... 'These first four are the square farthest 'from the screen DATA 50,50,-50 DATA -50,-50,-50 DATA -50,50,-50 DATA 50,-50,-50 'These are the closest... DATA 50,50,50 DATA -50,-50,50 DATA -50,50,50 DATA 50,-50,50 '---- Stop! That my friends, Is the HAW way of drawing 3d sprites and rotating them... IF you think this is too HAW then look at the program I made using this tecnique... You'll find it on my web page in the files section... My website is at... http://members.aol.com/radiohands/index.html It is a real 3D editor... It is in source code too! Remember, If you don't understand any of this... It's In the Source code... Excuse me... My head is about to explode... Along with my fingers... ----------------------------------------------------------------------------- ***************************************************************************** ----------------------------------------------------------------------------- Thats it for this tutorial, If I didn't get into enough detail in the explanations then just look at the source code and try to figure it out on your own. All else fails E-Mail Me... My current E-Mail address is RADIOHANDS@AOL.com If you are using this tutorial on your page, please leave the tutorial exactly as it is... please don't change anything, unless its spelling errors... Theres alot of them! I don't like using the backspace key... The original website that these were on is http://members.aol.com/radiohands/index.html Thank you Vic Luce Finished November 22 1999 If you want to be notified when a new tutorial is out.. Send An E-mail to RADIOHANDS@AOL.com with the subject saying VQBLIST and then your E-mail address(check website)