   
3D Rotations
in Mathematics & Demos
   
Strange title, isn't it? :) I just finished my exploration of matrices & 3D
(yeah, after 3/4 year of using it :)) so why not to write some lines about
it...
Everyone knows it
=================
We want to rotate a point in 2D space (at first) :
new x := x*cos(phi)  y*sin(phi)
new y := x*sin(phi) + y*cos(phi)
That means if we have a point in Carthesian Coordinate System (CCS), our point
with coordinates (x,y) will be anticlockwise rotated around (0,0) in this
system. Graphically:
^ +y


 . < rotated point with new (x,y)
 /
 / _. < point (x,y)
/
> +x
(0,0)






Clear. But! As you probably know, computer screen doesn't look like this. We
can do two things if we want correct rotations: "convert" carthesian
coordinates to computer ones or derive new rotation formulas.
1. Carthesian vs Computer Coordinates
=====================================
Our situation looks like this:
(0,0)
> +x
\_. < point (x,y)
 \
 \
 \. < rotated point with new (x,y)




v +y
We see two differences: ydirection and anti/clock wise rotation.
In 2D, both differences can be solved by a simple equation y := (yres1)  y
In 3D, it isn't so easy. Remember we're rotating around 3 axes, firstly around
Z (gama angle), then Y (beta) and finally X (alpha)
( +cosG +sinG 0 ) ( +cosB 0 +sinB ) ( 1 +cosA +sinA )
MZ = ( sinG +cosG 0 ) MY = ( 0 1 0 ) MX = ( 0 sinA +cosA )
( 0 0 1 ) ( sinB 0 +cosB ) ( 0 0 0 )
So, we derive our new point by new [P] = [x y z] * MZ*MY*MX, right?
In my short coder's life I've seen as many rotation matrices as sources
released by coders =) After multiplying you will get:
( +cosBcosC +cosAsinCsinAsinBcosC +sinAsinC+cosAsinBcosC )
( cosBsinC +cosAcosC+sinAsinBsinC +sinAcosCcosAsinBsinC )
( sinB sinAcosB +cosAcosB )
Believe me, this is the one and only correct solution :) BUT. This matrix
works in CCS, but not in computer space. So, what's wrong? Let's look at our
two problems:
a) ydirection: here there aren't any changes, we use y := (yres1)  y
b) if you run your 3D engine now, you'll get the feeling everything is alright
(as I did for about 3/4 year ;)) But there's that clockwise problem  if our
engine has to be correct (that means it respects a lefthand rule since we're in
lefthanded CCS = zaxis goes away from us)
a rotation around yaxis has to switch to another direction:
^ +z


 /
 / . < out rotated point (we're breaking the lefthand rule)
 /
/___. < our point (x,y)
*> +x
/
/ 
/ 
/ 
/+y 
So, we need to change from anticlockwise to clockwise rotation.. How do we do
it? Simply ;) Just imagine how we define x & y coordinates on circle in 2D. If
we're going "up" with our point, the yvalue is increased. This is an
anticlockwise rotation. And we want a clockwise one. And its as simple as
negating the y coordinate! And y coordinate = r*sin(phi) > every sin(beta)
becomes sin(beta). Remember "beta" is an angle we're rotating around yaxis.
Our matrix becomes:
( +cosBcosC +cosAsinC+sinAsinBcosC +sinAsinCcosAsinBcosC )
( cosBsinC +cosAcosCsinAsinBsinC +sinAcosC+cosAsinBsinC )
( +sinB sinAcosB +cosAcosB )
And our rotation will look like:
[rotate point using matrix above]
[calculate projected coordinates]
[center on screen: x := x + xres/2; y := (yres/2  1) y ]
[write pixel to screen]
Now you've got a mathematically correct rotation in 2D and 3D... but there's
one stupid thing and that is a need of one more instruction in the projection
loop  you can't do for example "119  y" in one instruction since you need the
value 119 for the next use => at least two instructions are needed, that's bad
if you want to rotate about 1000 points... ok, DSP has a +/ option in
multiplying, but the solution above is a bit stupid ;)
A better solution is :
2. Deriving New Rotation Formulas
===================================
What does this mean? When I began with 3D stuff I thought programs like Neon or
3DS use CCS instead of computer screen for calculating their ycoordinates. But
this isn't true of course  why give coders some additional work? :) So we
have some 3d objects saved in a computer space system and we want to rotate it
in mathematically correct way (ie. not breaking the lefhandrule)
When you try to use original matrix with:
x := x + xres/2
y := y + yres/2
you'll get quite strange result ;) Where's the problem? The original matrix is
"built" for CCS. And... the difference between CCS and computer screen is in
the y coordinate. In the sign of y coordinate. And what affects the y
coordinate in 3D? Rotation around x & z axis. So the only thing you have to do
is negate the sin(alpha) and sin (gama) values:
( +cosBcosC cosAsinC+sinAsinBcosC +sinAsinC+cosAsinBcosC )
( +cosBsinC +cosAcosC+sinAsinBsinC sinAcosC+cosAsinBsinC )
( sinB +sinAcosB +cosAcosB )
So people, this is the one and only matrix for correct rotation in a lefthanded
coordinate system ! For sure, we're in the system which looks like this:
 ^ +x ^ +z ^ +y
   
 /+z   
 /  / +z  / +y  / +x
 /  /  /  /
 /  /  /  /
/ / / /
*> +x *> +y *> +x *> +z
/
/  anticlockwise anticlockwise anticlockwise
/  rotation around rotation around rotation around
/  zaxis yaxis xaxis
/ 
v +y
And here it is... you see all rotations are correct, the lefthand rule stays
unbroken, simply... this is what I like ;) But beware! If you use this way,
your vertices will be swapped in comparison with classic "conversion"!
(clockwise>anticlockwise and vice versa) So you need to modify your backface
culling routine (ble > bge) and maybe some other things (for example, if you
use realtime interpolation, right and left side will be swapped since the next
point in anticlockwise order = the previous point in clockwise one) So, don't
be stupid and use this way from the start and you'll save yourself a lot of
work ;)
MiKRO

MiKRO XE/XL/MegaSTE/Falcon/CT60 mikro.atari.org

