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)