Vic's QBasic Programming Tutorial Basic Tutorial XIV 2D Rotation... Has more uses than you would first think... ----------------------------------------------------------------------------- Ok, I admit that I made a mistake... I should of wrote this before the 3d tutorial... But who cares? Ok, In the 3d Tutorial I told you to print up a bunch of little programming algorithms... We'll need that again... If you didn't print it then, then here it is... Make sure to print it up! --- 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... ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- Ok, The formulas that You will use for this tutor is... ***********************| 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! ***************| FIND OUT WHAT DIRECTION IT IS GOING |********** stepx = s!(angle) stepy = c!(angle) --- Ok... This is going to be about the same (i mean confusing) as the 3d tutor. First, We have to set our Cosine tables... Don't worry about what a cosine is... Just do it... It's the same everytime... Do it like this... FOR i = 0 TO 360 c!(i) = COS(i * 3.14 / 180) S!(i) = SIN(i * 3.14 / 180) NEXT why 360? because there are 360 degrees in a circle... 0=360 and 360=0... Ok thats done... Now what? Lets set up are points... Lets make our center. (where all the points will revolve around...) centerx = 160 centery = 100 that would be the center of SCREEN 13... lets make a point on the screen... ( this means 10 points from the center) x = 10 y = 10 Sounds great!!! Lets show those points on the screen!!!! SCREEN 13 pset (x + centerx, y + centery),1 pset (centerx,centery),4 All together now! '--------- FOR i = 0 TO 360 c!(i) = COS(i * 3.14 / 180) S!(i) = SIN(i * 3.14 / 180) NEXT centerx = 160 centery = 100 x = 10 y = 10 SCREEN 13 PSET (x, y),1 PSET (centerx, centery),4 '--------- The red pixel is what we will revolve around, and blue is what is revolving.. It is time for one of my classic LOOPS to make sure the program continues... DO press$ = INKEY$ LOOP UNTIL press$ = CHR$(27) --- I left little or no explaination in what I just showed you, because I am sure anyone could do that... Here comes some explaining... In order to make the point revolve, we must use the formulas that I mentioned above... Remember? ***********************| NON 3D ROTATION |*********************** X2 = X * c! + Y * s! Y2 = Y * c! - X * s! Ok... this is very simple to use... First type out then entire formulas... X2 = X * c! + Y * s! Y2 = Y * c! - X * s! Now, lets modify them so we can use them... the C! and S! you can't just use by themselves... We set them up into an array, we have to give them a rotation angle that was precalculated... It would look like this... X2 = X * c!(angle) + Y * s!(angle) Y2 = Y * c!(angle) - X * s!(angle) Right now, the angle = 0... so if you run the program now, nothing would happen... since we are in a loop we might as well continually change the angle... We can do it like this... angle = angle + 1 Right? But what happens when angle is greater than ( > ) 360? It would crash, because we only set the array up for 360 degrees... ----- I hope you're getting all of this... Just follow the formulas and figure it out yourself if you don't understand my explainations... sorry... ----- to make sure that angle does not go greater than 360 degrees we can do this.. angle = angle + 1 IF angle >= 360 THEN angle = 0 This way, if angle = 360 or is greater than 360 it would start itself back at 0 degrees... 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 centerx = 160 centery = 100 X = 10 Y = 10 SCREEN 13 DO press$ = INKEY$ PSET (X + centerx, Y + centery), 1 PSET (centerx, centery), 4 angle = angle + 1 IF angle >= 360 THEN angle = 0 x2 = X * c!(angle) + Y * s!(angle) y2 = Y * c!(angle) - X * s!(angle) PSET (x2 + centerx, y2 + centery), 2 LOOP UNTIL press$ = CHR$(27) '------------ end example... In this example, a circle is drawn on the screen... if you want to control the speed it rotates at you have to put some controls in it... you have to control the angle that it is being turned at... so to controll the angle you cant just tell it to keep getting bigger and bigger non stop... you have to let it get bigger when you want it too.. lets use the space bar to let it get higher... so, when you press the space bar the angle will get bigger... type this, if press$ = " " then angle = angle + 1 instead of just angle = angle + 1 ---- ok, lets rotate 4 points... for this we need to make some more arrays for the points... right now, we just have this... X = 10 Y = 10 that is one point, we need to make four points... First, we have to think where we want to put the points... ---- ok, first I have to explain why the x and y only equall 10 but they are in the center of the screen... SCREEN 13 is 320 x 200, so half of this would be 160 x 100 So, in our program above, you will see this... centerx = 160 centery = 100 the center of the screen is declared in these two variables.. and since we want to revolve around the center, we must tell the points to revolve around centerx and centery... so, can you guess why x and y only equall 10? that just means that they are 10 pixels(points) away from the center... look at it like this... cx & cy just represents CENTERX & CENTERY |--------------------------------------------| | | | | | | | | | | | ------- | | |Cx,Cy| --------> | | ------- x=10 points | | | | | | y=10 points | | | | | v 0 <--x,y | | | | | | | | | | | |--------------------------------------------| I hope this helps... ---- Ok, now its time for the multiple points... instead of just x and y we will use x1,y1,x2,y2,x3... ok, first,lets have x1 & y1 equall the same as x and y did... x1 = 10 y1 = 10 for x and y 2 we will make a point that is farther to the left of centerx so, we need x2 to equall -10... and y2 to equall the same... x2 = -10 y2 = 10 why -10? when -10 is added to 160 then it now equalls 150... it would look like this... |--------------------------------------------| | | | | | | | | | | | ------- | | <-----|Cx,Cy| | | x ------- | | | | | | y | | | | | x2,y2---> 0 v | | | | | | | | | | | |--------------------------------------------| some of you may ask why not have x2 equall 0? If x2 equalled 0 then the point that it will revolve around (centerx,centery) will not be in the center... so the (sprite) will move around the point, and not turn in a circle itself... ok, we have... x1 = 10 y1 = 10 x2 = -10 y2 = 10 we need 2 more points... Can you guess what they will be? x3 = 10 y3 = -10 x4 = -10 y4 = -10 Easy?... ------- Now, lets remake the program to use these 4 points... '------------------ ROTATE EXAMPLE 2.0 ---------------- 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 centerx = 160 centery = 100 angle = 90 X1 = 10 Y1 = 10 X2 = -10 Y2 = 10 X3 = 10 Y3 = -10 X4 = -10 Y4 = -10 SCREEN 7, 0, 1, 0 DO press$ = INKEY$ IF press$ = " " THEN angle = angle + 1 IF angle >= 360 THEN angle = 0 xx1 = X1 * c!(angle) + Y1 * s!(angle) yy1 = Y1 * c!(angle) - X1 * s!(angle) xx2 = X2 * c!(angle) + Y2 * s!(angle) yy2 = Y2 * c!(angle) - X2 * s!(angle) xx3 = X3 * c!(angle) + Y3 * s!(angle) yy3 = Y3 * c!(angle) - X3 * s!(angle) xx4 = X4 * c!(angle) + Y4 * s!(angle) yy4 = Y4 * c!(angle) - X4 * s!(angle) LINE (0, 0)-(320, 2000), 0, BF LINE (xx1 + centerx, yy1 + centery)-(xx2 + centerx, yy2 + centery), 1 LINE (xx2 + centerx, yy2 + centery)-(xx4 + centerx, yy4 + centery), 1 LINE (xx3 + centerx, yy3 + centery)-(xx4 + centerx, yy4 + centery), 1 LINE (xx1 + centerx, yy1 + centery)-(xx3 + centerx, yy3 + centery), 1 PSET (xx1 + centerx, yy1 + centery), 2 PSET (xx2 + centerx, yy2 + centery), 2 PSET (xx3 + centerx, yy3 + centery), 2 PSET (xx4 + centerx, yy4 + centery), 2 PCOPY 1, 0 LOOP UNTIL press$ = CHR$(27) '---------------- END EXAMPLE 2 ------------------------------------------ In this example, you have to use the space bar to rotate the square... NEXT... --------------------------------- Using better arrays... instead of going x1 = xx x2 = xx and going through all of our points, we can use arrays like this... First, you have to dim the arrays... We still want 4 points... DIM x(4), y(4) Ok, we have them dimmed, now how do we get information in them... Well, you could go x(1) = -10... and do it for all 4, but thats not very organized, and is a waste of space and time... What you would be better off doing is store them with the DATA statement and call them up... ok, first lets do the X values... remember what they are? x1 = 10 x2 = -10 X3 = 10 x4 = -10 lets put them in the DATA in order... DATA 10, -10, 10, -10 thats our X values... now for the Y values... remember what they are? y1 = 10 y2 = 10 y3 = -10 y4 = -10 this is what it will look like in the DATA... DATA 10, 10, -10, -10 Ok, we stored them as DATA, how do we get them in the arrays? Use the READ statement... like this READ x(1) READ x(2) DATA 10, -10, 10, -10 DATA 10, 10, -10, -10 in this example, x1 = 10 x2 = -10 everytime you call the READ command, it reads the next number declared in the DATA... So this is how you would grab all of them quickly... FOR i = 1 to 4 READ x(i) NEXT FOR i = 1 to 4 READ y(i) NEXT DATA 10, -10, 10, -10 DATA 10, 10, -10, -10 in this example, all of the points (8) are read and stored... can you see how... I hope so... you may think to yourself, how does this make things shorter? well, imagine if you had 100 x values... the only thing that would really get bigger is the DATA and the FOR i = to XX... --------------- Ok, now, how do we change those values since they arn't x1,y1,x2,y2...? Like this... look closely... DIM xx(4), yy(4) FOR i = 1 to 4 xx(i) = X(i) * c!(angle) + Y(i) * s!(angle) yy(i) = Y(i) * c!(angle) - X(i) * s!(angle) NEXT we first make new arrays to store the changed values of X and Y... DIM xx(4), yy(4) Now, I will point out what has changed in the other stuff... xx(i) = X(i) * c!(angle) + Y(i) * s!(angle) yy(i) = Y(i) * c!(angle) - X(i) * s!(angle) xx(i) x(i) x(i) yy(i) Y(i) Y(i) that is what changed from the old formula, look and try to find out why... That stuff is not needed but can help (if you understand it)... ------------- Lets put it all together... '------------------ Last example.... 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 centerx = 160 centery = 100 angle = 90 dim x(4), y(4) DIM xx(4), yy(4) FOR i = 1 to 4 READ x(i) NEXT FOR i = 1 to 4 READ y(i) NEXT DATA 10, -10, 10, -10 DATA 10, 10, -10, -10 SCREEN 7, 0, 1, 0 DO press$ = INKEY$ IF press$ = " " THEN angle = angle + 1 IF angle >= 360 THEN angle = 0 FOR i = 1 to 4 xx(i) = X(i) * c!(angle) + Y(i) * s!(angle) yy(i) = Y(i) * c!(angle) - X(i) * s!(angle) NEXT LINE (0, 0)-(320, 2000), 0, BF LINE (xx(1) + centerx, yy(1) + centery)-(xx(2) + centerx, yy(2) + centery), 1 LINE (xx(2) + centerx, yy(2) + centery)-(xx(4) + centerx, yy(4) + centery), 1 LINE (xx(3) + centerx, yy(3) + centery)-(xx(4) + centerx, yy(4) + centery), 1 LINE (xx(1) + centerx, yy(1) + centery)-(xx(3) + centerx, yy(3) + centery), 1 PSET (xx(1) + centerx, yy(1) + centery), 2 PSET (xx(2) + centerx, yy(2) + centery), 2 PSET (xx(3) + centerx, yy(3) + centery), 2 PSET (xx(4) + centerx, yy(4) + centery), 2 PCOPY 1, 0 LOOP UNTIL press$ = CHR$(27) '---------------- END EXAMPLE 3! ----------------------------------------- Ok thats it... That is all you really need to know, if you want to rotate more than just points and you would like to turn things like bitmaps, you just have to work a bit harder... ----------------------------------------------------------------------------- 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... I want to make these tutorials as easy to understand as posible!!! 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 Febuary 10 2000 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)