485 lines
18 KiB
Plaintext
485 lines
18 KiB
Plaintext
|
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ% VLA Proudly Presents %<25><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ
|
|||
|
<20> <20>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Three Dimensional Rotations For Computer Graphics
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
By Lithium /VLA
|
|||
|
|
|||
|
|
|||
|
|
|||
|
One of the most difficult programming difficulties you will face is that
|
|||
|
of representing a 3D world on that 2D screen in front of you. It requires
|
|||
|
some linear alegbra that may be difficult for some, so I will spend some
|
|||
|
bytes explaining the mathmatic computations of using matricies in addition
|
|||
|
to the equations to get you going. This document is intended to be an aid
|
|||
|
to anyone programming in any language, as a result it will use mathmatic
|
|||
|
notation. If you are worthy of using these routines, you ought to be able
|
|||
|
to get them into your favorite language. All I ask is that you pay a little
|
|||
|
tribute to your programming buddies in VLA.
|
|||
|
|
|||
|
|
|||
|
If you aren't a math person, skip to the end and get the final equations.
|
|||
|
Just be forewarned, implimenting these equations into a coherient 3D world
|
|||
|
is hard enough when you undersand the mathmatics behind them...
|
|||
|
|
|||
|
|
|||
|
REAL PROGRAMMERS AREN'T AFRAID OF MATH
|
|||
|
|
|||
|
|
|||
|
3D Coordinates
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
Just so we all understand each other, 3D is defined in of course three
|
|||
|
directions, we'll call them (X,Y,Z). X will be the horizontal plane of your
|
|||
|
screen, Z will stretch vertically, and Y will extend out of and into your
|
|||
|
screen. Got it? Hope so, becuase it gets a bit tricky now. The next
|
|||
|
system is called Sphereical Coordinates it is defined by angles and distance
|
|||
|
in (<28>,<2C>,p) These Greek letters are Theta (<28>), Phi (<28>), and Roe (p)
|
|||
|
|
|||
|
Z Z
|
|||
|
| | <20> - Angle in the XY
|
|||
|
| |\ plane
|
|||
|
| |\\
|
|||
|
| | \\ <20> - Angle from the Z
|
|||
|
|______ X |<7C>_|\___X axis
|
|||
|
/ / \ v \
|
|||
|
/ / <20> \ o p - Distance to point
|
|||
|
/ /\ \ | from the origin
|
|||
|
/ / --> \ | (0,0,0)
|
|||
|
Y Y \|
|
|||
|
|
|||
|
|
|||
|
To relate the two systems you can use these equations.
|
|||
|
|
|||
|
X = p(sin<69>)(cos<6F>) <20> = arctan (X/Y)
|
|||
|
Y = p(sin<69>)(sin<69>) <20> = arccos (Z/p)
|
|||
|
Z = p(cos<6F>) p = <20>(X^2 + Y^2 + Z^2)
|
|||
|
|
|||
|
If these don't seem right, do a couple of example problems for yourself,
|
|||
|
it should make since after a bit of trig.
|
|||
|
|
|||
|
|
|||
|
Matrix Notation
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
Lets say I can define Xt and Yt with the equations:
|
|||
|
|
|||
|
Xt = aX + bY Where a,b,c,d are coeffiencets
|
|||
|
Yt = cX + dY
|
|||
|
|
|||
|
The matrix notation for this system of equations would be:
|
|||
|
<20> <20>
|
|||
|
(Xt,Yt) = (X,Y)<29>a c<>
|
|||
|
<20> <20> And we solve for this with these steps
|
|||
|
<20>b d<>
|
|||
|
<20> <20>
|
|||
|
|
|||
|
<20> <20>
|
|||
|
Xt = (X,Y)<29>a .<2E> = aX + bY
|
|||
|
<20> <20> We move across the coordinates left to right
|
|||
|
<20>b .<2E> and multiply them by the coeffients in the
|
|||
|
<20> <20> matrix, top to bottom
|
|||
|
<20> <20>
|
|||
|
Yt = (X,Y)<29>. c<> = cX + dY
|
|||
|
<20> <20> For Y, the second number, we use the second
|
|||
|
<20>. d<> column of the matrix
|
|||
|
<20> <20>
|
|||
|
|
|||
|
We can also multiply matricies in this fashion
|
|||
|
<20> <20> <20> <20>
|
|||
|
T = T1*T2 Where T1 = <20>a c<> and T2 = <20>e g<>
|
|||
|
<20> <20> <20> <20>
|
|||
|
<20>b d<> <20>f h<>
|
|||
|
<20> <20> <20> <20>
|
|||
|
|
|||
|
<EFBFBD> <20><> <20> <20> <20>
|
|||
|
<EFBFBD>a c<><63>e g<> <20>(ae + cf) (ag + ch)<29> rows -> columns |
|
|||
|
<EFBFBD> <20><> <20> = <20> <20> v
|
|||
|
<EFBFBD>b d<><64>f h<> <20>(be + df) (bg + dh)<29>
|
|||
|
<EFBFBD> <20><> <20> <20> <20>
|
|||
|
|
|||
|
This product is dependent on position, so that means that
|
|||
|
T1*T2 *DOES NOT* equal T2*T1
|
|||
|
|
|||
|
In English, the process above went like this, we move left to right in
|
|||
|
the first matrix, T1, and top to bottom in the second, T2. AE + CF is our
|
|||
|
first position.
|
|||
|
|
|||
|
The numbers in the first row are multiplied by the numbers in the
|
|||
|
first column. 1st * 1st + 2nd * 2nd is our first value for the new matrix.
|
|||
|
Then you repeat the process for the next column of the second matrix.
|
|||
|
|
|||
|
After that, you move down to the next row of the first matrix, and
|
|||
|
multiply it by the 1st column of the second matrix. You then do the same
|
|||
|
for the next column of the second matrix. This process is repeated until
|
|||
|
you've done all of the rows and columns.
|
|||
|
|
|||
|
If this is your introduction to matricies, don't feel bad if you're a bit
|
|||
|
confused. They are a different mode of thinking about equations. The
|
|||
|
operations above give the same results as if you were to do the long hand
|
|||
|
algebra to solve them. It may seem a bit more difficult for these examples,
|
|||
|
but when you get to systems of equations with many variables, this way is
|
|||
|
MUCH faster to compute. Trust me, especially when you make your program do
|
|||
|
it.
|
|||
|
|
|||
|
|
|||
|
So, now you have the basic math....
|
|||
|
|
|||
|
|
|||
|
One important point for these matricies below. I will use a homogeneous
|
|||
|
coordinate system, (X/r, Y/r, Z/r, r) Now I'll use r=1, so nothing will
|
|||
|
really be different in my calculations, but you need to understand the
|
|||
|
purpose.
|
|||
|
|
|||
|
This form is very convienent for the translations and rotation
|
|||
|
equations we will need to do because it allows for scaling of our points with
|
|||
|
respect to a center point.
|
|||
|
|
|||
|
Consider a point (2,2,2) in an object centered at (1,1,1). If we were
|
|||
|
to scale the X direction by 3,(the X length to the center is 3 times what it
|
|||
|
was) the point we want would be (4,2,2). Our new X = 3*(OldX-CenterX).
|
|||
|
Without the added factor of the homogeneous system, calculations assume all
|
|||
|
objects are centered at the origin, so our point would have turned out to be
|
|||
|
(6,2,2), NOT the one we wanted. So that's why we are going to do it that way.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ROTATIONS AND TRANSFORMATIONS
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
Translation
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
We will start with translation from the origin. Most objects are not
|
|||
|
at (0,0,0,1), so we'll call their center (Tx,Ty,Tz,1).
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 1 0 0 0<> = T1
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 1 0 0<> This physically moves the object, so it is centered
|
|||
|
<EFBFBD> <20> at the origin for our calcuations, eliminating the
|
|||
|
<EFBFBD> 0 0 1 0<> need for a -Tx for each X, the matrix will factor it
|
|||
|
<EFBFBD> <20> in when we multiply it by the others
|
|||
|
<EFBFBD>-Tx -Ty -Tz 1<>
|
|||
|
<EFBFBD> <20> But, we need sphereical coordinates...
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 1 0 0 0 <20>
|
|||
|
<EFBFBD> <20> = T1
|
|||
|
<EFBFBD> 0 1 0 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 0 1 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD>-p(cos<6F>)(sin<69>) -p(sin<69>)(sin<69>) -p(cos<6F>) 1 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
|
|||
|
XY Clockwise Rotation
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
This will be our first rotation, about the Z-Axis
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> sin<69> cos<6F> 0 0 <20>
|
|||
|
<EFBFBD> <20> = T2
|
|||
|
<EFBFBD>-cos<6F> sin<69> 0 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 0 1 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 0 0 1 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
|
|||
|
YZ Counter-Clockwise Rotation
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Now we rotate about the X axis
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 1 0 0 0 <20>
|
|||
|
<EFBFBD> <20> = T3
|
|||
|
<EFBFBD> 0 -cos<6F> -sin<69> 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 sin<69> -cos<6F> 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 0 0 1 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
Notice that with two rotations that we can get any position in 3D space.
|
|||
|
|
|||
|
Left Hand Correction
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
This will flip the X coordinates. Think about when you
|
|||
|
look into the mirror, your left hand looks like your right.
|
|||
|
These rotations do the same thing, so by flipping the X, it
|
|||
|
will make your X move right when you increase it's value.
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> -1 0 0 0 <20>
|
|||
|
<EFBFBD> <20> = T4
|
|||
|
<EFBFBD> 0 1 0 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 0 1 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 0 0 1 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
|
|||
|
The Final Viewing Matrix
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
This is the net transformation matrix for our viewing perspective
|
|||
|
|
|||
|
The math for this one is really messy, and I would need to go over even
|
|||
|
more matrix stuff to get it reduced, so I will ask you to trust my
|
|||
|
calculations
|
|||
|
|
|||
|
V = T1*T2*T3*T4
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> -sin<69> -(cos<6F>)(cos<6F>) -(cos<6F>)(sin<69>) 0 <20>
|
|||
|
<EFBFBD> <20> = V
|
|||
|
<EFBFBD> cos<6F> -(sin<69>)(cos<6F>) -(sin<69>)(sin<69>) 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 sin<69> -cos<6F> 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 0 p 1 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
|
|||
|
Lets say our original (X,Y,Z,1) were just that, and the point after the
|
|||
|
rotation is (Xv,Yv,Zv,1)
|
|||
|
|
|||
|
(Xv,Yv,Zv,1) = (X,Y,Z,1) * V
|
|||
|
|
|||
|
|
|||
|
Xv = -Xsin<69> + Ycos<6F>
|
|||
|
|
|||
|
Yv = -X(cos<6F>)(cos<6F>) - Y(sin<69>)(cos<6F>) + Zsin<69>
|
|||
|
|
|||
|
Zv = -X(cos<6F>)(sin<69>) - Y(sin<69>)(sin<69>) - Zcos<6F> + p
|
|||
|
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
|
|||
|
Some people have had trouble concepts of this implimentation, so I have
|
|||
|
another way of setting up the equations. This works off of the straight
|
|||
|
X,Y, and Z coordinates too, but uses another angle.
|
|||
|
|
|||
|
|
|||
|
We will define the following variables
|
|||
|
|
|||
|
Xan = Rotation about the X-Axis
|
|||
|
Yan = Rotation about the Y-Axis
|
|||
|
Zan = Rotation about the Z-Axis
|
|||
|
|
|||
|
|
|||
|
Rotation about the Y Axis
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> cos(Yan) 0 sin(Yan) <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 1 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> -sin(Yan) 0 cos(Yan) <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
|
|||
|
Rotation about the Z Axis
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 1 0 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 cos(Zan) -sin(Zan) <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 sin(Zan) cos(Zan) <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
|
|||
|
Rotation about the X Axis
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> cos(Xan) -sin(Xan) 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> sin(Xan) cos(Xan) 0 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> 0 0 1 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
|
|||
|
For simplification, lets call sin(Yan) = s1, cos(Xan) = c3,
|
|||
|
sin(Zan) = s2, etc
|
|||
|
|
|||
|
Final Rotation Matrix
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> c1c3 + s1s2s3 -c1s3 + c3s1s2 c2s1 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> c2s3 c2c3 -s2 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
<EFBFBD> -c3s1 + c1s2s3 s1s3 + c1c3s2 c1c2 <20>
|
|||
|
<EFBFBD> <20>
|
|||
|
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
Xv = x(s1s2s3 + c1c3) + y(c2s3) + z(c1s2s3 - c3s1)
|
|||
|
|
|||
|
Yv = x(c3s1s2 - c1s3) + y(c2c3) + z(c1c3s2 + s1s3)
|
|||
|
|
|||
|
Zv = x(c1s2s3 - c3s1) + y(-s2) + z(c1c2)
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
|
|||
|
Where Xv,Yv, and Zv are the final rotated points and the little x,y,z are
|
|||
|
the original points.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Normal Vectors - The Secret To Shading and Plane Elimination
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
|
|||
|
So, now you have the rotation equations... But, how do we make it fast?
|
|||
|
Well, one of the best optimizations you can impliment is plane elimination.
|
|||
|
It boils down to not displaying the planes that won't be seen. With that
|
|||
|
said, here comes more math....
|
|||
|
|
|||
|
BE A MAN, KNOW YOUR NORMALS
|
|||
|
|
|||
|
A 'normal' vector is perpendicular to a plane. Imagine the face of a
|
|||
|
clock as a plane. Take your right hand and point your thumb toward yourself
|
|||
|
and the other end toward the clock. Now curl your fingers in the
|
|||
|
counter-clockwise direction. Your thumb is pointing in the direction of the
|
|||
|
normal vector. This is called 'The Right Hand Rule' and it is the basis for
|
|||
|
figuring the facing of planes.
|
|||
|
|
|||
|
A plane can be determined with three points, try it. That's the minimum
|
|||
|
you need, so that's what we will base our process on. Now if we have a line
|
|||
|
segment, we could move it to the origin, maintaining it's direction and
|
|||
|
lenght by subtracting the (X,Y,Z) of one of the points from both ends. This
|
|||
|
is our definition of a vector. A line segment, starting at the origin and
|
|||
|
extending in the direction (X,Y,Z).
|
|||
|
|
|||
|
Here will be our plane, built from the three points below.
|
|||
|
|
|||
|
(X1,Y1,Z1) V = (X1-X2, Y1-Y2, Z1-Z2)
|
|||
|
(X2,Y2,Z2) W = (X1-X3, Y1-Y3, Z1-Z3)
|
|||
|
(X3,Y3,Z3)
|
|||
|
|
|||
|
So, we have our three points that define a plane. From these points we
|
|||
|
create two vectors V and W. Now if you where to use the right hand rule with
|
|||
|
these vectors, pointing your fingers in the direction of V and curling them
|
|||
|
toward the direction of W, you would have the direction of the Normal vector.
|
|||
|
This vector is perpendicular to both vectors, and since we have defined the
|
|||
|
plane by these vectors, the normal is perpendicular to the plane as well.
|
|||
|
|
|||
|
The process of finding the normal vector is called the 'Cross Product' and
|
|||
|
it is of this form:
|
|||
|
|
|||
|
<20> <20>
|
|||
|
V*W =<3D> i k j <20>
|
|||
|
<20> <20>
|
|||
|
<20> X1-X2 Y1-Y2 Z1-Z2 <20>
|
|||
|
<20> <20>
|
|||
|
<20> X1-X3 Y1-Y3 Z1-Z3 <20>
|
|||
|
<20> <20>
|
|||
|
|
|||
|
i = (Y1-Y2)(Z1-Z3) - (Z1-Z2)(Y1-Y3)
|
|||
|
|
|||
|
-k = (Z1-Z2)(X1-X3) - (X1-X2)(Z1-Z3)
|
|||
|
|
|||
|
j = (X1-X2)(Y1-Y3) - (Y1-Y2)(X1-X3)
|
|||
|
|
|||
|
The Normal to the plane is (i,-k,j)
|
|||
|
|
|||
|
|
|||
|
NOTE: V*W *DOESN'T* equal W*V, it will be pointing in the negative direction
|
|||
|
To prove that to yourself, lets go back to how I explained it before
|
|||
|
We pointed in the direction of V and curled our fingers toward W, the
|
|||
|
normal vector in the direction of your thumb. Try it in the
|
|||
|
direction of W, toward V. It should be in the opposite direction.
|
|||
|
Your normal, still perpendicular to both vectors, but it is negative.
|
|||
|
If you use in your program, you will have the planes appearing when
|
|||
|
they shouldn't and dissapearing when they are coming into view.
|
|||
|
|
|||
|
So, now that we have a way to determin the direction of the plane,
|
|||
|
how do we hide the plane? If the angle between the view point and the
|
|||
|
normal is greater than 90 degrees, don't show it. One quick way that I
|
|||
|
always use is to place the view point on an axis. I tipically set the
|
|||
|
Z axis to come out of the screen, Y up and X across. Set the view point
|
|||
|
to be at a positive point on the Z and then, if that normal vector has Z
|
|||
|
greater than zero, I display it, otherwise I skip to the next one.
|
|||
|
|
|||
|
This also has an application in shading. If you define a light scource,
|
|||
|
just like the view point, you find the angle the normal and the light form.
|
|||
|
Since you don't usually just want two colors, our 90 degree trick won't work
|
|||
|
for you, but by finding this angle, and dividing all of the possible angles
|
|||
|
by the number of colors you will allow in the shading, that color can be
|
|||
|
assigned to the plane and, presto-chango, it looks like you know what your
|
|||
|
doing...
|
|||
|
|
|||
|
As you do your rotations, just rotate the coordinates of the normal and
|
|||
|
that will keep everything updated.
|
|||
|
|
|||
|
|
|||
|
Tips To Speed-Up Your Routines
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
Pre-Calculate as many values as possible
|
|||
|
The main limitation you will have is the speed of your math, using
|
|||
|
precalculated values like Normals, Sin/Cos charts, and distance from the
|
|||
|
origin are all good candidates.
|
|||
|
|
|||
|
If you can get away with using a math-coprocessor, well...
|
|||
|
This will greatly increase the speed of your routine. Unfortunately,
|
|||
|
not everyone has one.
|
|||
|
|
|||
|
Only figure values once
|
|||
|
If you multiply (Sin<69>)(Cos<6F>) and will use that same value later, by all
|
|||
|
means, keep it and use it then instead of doing the multiplication again.
|
|||
|
|
|||
|
Another thing to keep in mind
|
|||
|
The order of rotations *DOES* make a difference. Try it out and you'll
|
|||
|
understand. Also, when you start to use these routines, you'll find
|
|||
|
yourself making arrays of points and plane structures.
|
|||
|
|
|||
|
|
|||
|
Counter-Clockwise points
|
|||
|
Be sure to list your points for the planes in counter-clockwise order.
|
|||
|
If you don't, not all of your planes will display correctly when you
|
|||
|
start hiding planes.
|
|||
|
|
|||
|
And as always, be clever
|
|||
|
Just watch out, because when you have clever ideas you can lose a foot.
|
|||
|
My brother once had a clever idea to cut his toe nails with an axe and
|
|||
|
he lost his foot.
|
|||
|
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
Books to look for...
|
|||
|
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
Any math book, the topics I covered will be found in:
|
|||
|
|
|||
|
Normal Vectors - Analytic Geometry
|
|||
|
Matrix Operations - Linear Algebra
|
|||
|
Sines and Cosines - Trigonometry
|
|||
|
|
|||
|
The Art of Graphics, by Jim McGregor and Alan Watt
|
|||
|
1986 Addison-Wesley Publishers
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Read the VLA.NFO file to find out how to contact us.
|