- -- - ------------------------------------------------------------------------
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: y-direction and anti/clock- wise rotation.
In 2D, both differences can be solved by a simple equation y := (yres-1) - 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 +cosAsinC-sinAsinBcosC +sinAsinC+cosAsinBcosC )
( -cosBsinC +cosAcosC+sinAsinBsinC +sinAcosC-cosAsinBsinC )
( -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) y-direction: here there aren't any changes, we use y := (yres-1) - 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 = z-axis goes away from us)
a rotation around y-axis 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 y-value 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 y-axis.
Our matrix becomes:
( +cosBcosC +cosAsinC+sinAsinBcosC +sinAsinC-cosAsinBcosC )
( -cosBsinC +cosAcosC-sinAsinBsinC +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 y-coordinates. 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 lefhand-rule)
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
/ | z-axis y-axis x-axis
/ |
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
-------------------------------------------------------------------------------
|