
                     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)

