
ÉPOCA II. ENERO 1993
INICIACIÓN A LA PROGRAMACIÓN EN TRES DIMENSIONES
Artículo escrito por Spanish Archer/Darkness & Warlord/Impulse
Spanish Archer/Warlord productions 1992
¡Hola!, aquí estoy otra vez con un nuevo artículo. ¿Qué os creías?. En
esta ocasión se trata de una pequeña iniciación a la programación en 3D.
Este pretende ser el primero (y más teórico) de una serie de artículos
que poco a poco irán describiendo técnicas para animación vectorial 3D en
nuestro Amiga. Estos artículos (??#í) irán destinados principalmente a la
programación en ensamblador y se supone que el lector tiene un nivel medioalto (¿qué hace un move?). Los artículos tratarán temas como la programación de sine-vectors, filled vectors, dots, fuentes de luz e incluso una
introducción a la programación de rutinas de ray-tracing. ¡Empecemos!
Lo más importante de la programación en 3D es tener unos conceptos muy
claros y para esto empezaré con lo más básico:
Imaginemos que tenemos un punto P=(x,y,z) perteneciente a un espacio tridimensional. Los principales problemas que vamos a tener para tratarlo en
el ordenador van a ser:
- La rotación del punto
- La traslación
- La transformación del punto de 3D a 2D.
ROTACION CON RESPECTO A LOS 3 EJES:
Para rotar un punto con respecto a los tres ejes, hay varias formas de
hacerlo. Podemos realizar la rotación con respecto a los 3 ejes simultáneamente, o bien podemos hacerlo eje a eje. De todos modos, la rotación simultánea respecto a los tres ejes, no es más que la composición de tres rotaciones más simples: Una respecto al eje x, otra respecto al y, y otra respecto al z.
Veamos. La rotación respecto a un eje, puede ser como sigue:
x'=x
y'=ycosa-zsena
z'=ysena+zcosa
¿Cómo actúa este giro?. ¿Hacia la derecha?, ¿hacia la izqda?. Para saberlo, conviene ponerlo así:
/ \
|1 0 0 |
(x',y',z') = (x,y,z) |0 cosa sena|
|0 -sena cosa|
\ /
Es la llamada notación matricial. Para aquellos que no lo sepan (ver
Álgebra I ... ¡¡AAAAAaaagggggghhh!!). Ponerme a explicar cómo se multiplican matrices, sería muy largo. Sorry!
Un giro como el anterior, es simplemente uno de los muchos movimientos que
podemos hacer en el espacio. La matriz anterior, define completamente al
movimiento y se llama MATRIZ DEL MOVIMIENTO. Ahora, probar a hacerle el determinante.... da .... Mmmmmm .... ¡¡¡ 1 !!!!. ¿Casualidad? .... ¡no!. Esto lo que nos dice, es que es un giro DIRECTO, esto es en el sentido de las
agujas del reloj (esto hace mucho que lo estudié. Espero que no esté metiendo la "pata")
Podríamos cambiar por ejemplo, a algo así:
/ \
|1 0 0 | Ahora el determinante es -1. Se trata
(x',y',z') = (x,y,z) |0 -cosa sena| de un giro inverso. (en el sentido con
|0 sena cosa| trario a las agujas del reloj). Lo de
\ / las agujas del reloj, es un decir,pues
os recuerdo que estamos en 3D.
Podríamos hacer ahora otro giro respecto al eje "y" y otro respecto al "z".
Algo así:
y'=y
x'=xcosa-zsena
z'=xsena+zcosa
z'=z
y'=ycosa-xsena
x'=ysena+xcosa
Estos nos darían otras 2 matrices. Podríamos programarlo uno a uno o los
tres simultáneamente (para mayor velocidad). Para hallar el giro conjunto,
hay que multiplicar las 3 matrices. El orden en el que se deben multiplicar
las 3 matrices serían en sentido inverso al orden en que queremos que se
realicen los giros. Una vez multiplicadas, obtendríamos las ecuaciones del
giro.
Como ya sabréis, para introducir senos y cosenos en nuestro programa, hacemos una pequeña tabla que son algunos valores del seno y coseno, multiplicados por una constante (generalmente 16384). Algo así:
tablaseno: dc.l 8,10,11,12,13,14,14,15,15,14,14,13,12,11,10,8
dc.l 7,5,4,3,2,1,1,0,0,1,1,2,3,4,5,7
Una vez salvado el obstáculo de los senos y cosenos nos queda aún uno mayor
como es la imprecisión de los cálculos. Cada cierto número de rotaciones el
objeto se va deformando poco a poco. ¿Qué hacemos?. La solución es tan fácil
como ingeniosa, sólo tenemos que mantener las coordenadas del objeto original y una variable para cada eje que indique el número de grados que ha rotado. Por ejemplo, nuestro objeto ya se ha rotado anteriormente 45 grados,
luego tenemos el objeto original y una variable que indica 45. Si queremos
girarlo dos grados más, lo que tenemos que hacer es rotar el original 45+2
grados, en lugar de aumentar el anterior en dos, y posteriormente, poner la
variable a 47. Con este sistema el error es mínimo.
TRASLACION DE UN PUNTO:
Fácil, sólo tenemos que sumarle los valores de la traslación a las coordenadas del punto. Sería algo así:
(x',y',z')=(a+x,b+y,c+z).
Poner esto en forma de matrices, es más complicado
y se necesita otra coordenada más. Fijaos, algo así:
/ \
|1 a b c |
(1,x',y',z') = (1,x,y,z) |0 1 0 0 |
|0 0 1 0 |
\0 0 0 1 /
Podemos hacer igualmente lo de antes: Componer giro+traslación a la vez o
bien hacerlo simultáneamente. El problema de hacerlo a la vez, es que la matriz del giro no nos vale y hay que pasarla a 4x4 ... mejor lo olvidamos. Es
más fácil hacer cada uno por separado, aunque sea más lento.
TRANSFORMACIÓN 3D->2D
Vamos a deducir la fórmula ...
Imaginaos que tenéis un plano que queréis pasar a la pantalla en perspectiva cónica (repasar ese dibujo y esa geometría ....).El dibujo es el siguiente: (espero que lo veáis más o menos)
PANTALLA
Y P <--- Plano Plano
| /. | |
| / . | V
|/ . X' .......|........ -
/ . \ | / |
/| . \ | / |
/ | . X'' \ P' | / |
-------------------------------> Z -----\----|----/-------- - |
\ | . PANTALLA \ | / X | | Z'
\| . \ | / |d |
\ . ALZADO \ | / | |
|\ . \|/ | |
| \ . | - -
| \
|--|
d
|------|
Z'
Lo que debemos calcular es y'',y,x'' (que se vería igual). En fin, que por
triángulos semejantes, la relación es:
y'' y'
- = -*d
d z'
Por lo tanto ya tenemos la fórmula de la transformación. Sería:
y'=(y/z)*d Siendo x',y' las coordenadas de la pantalla (2D) y
(x,y,z) las coordenadas del punto en 3D. "d" es la
x'=(x/z)*d llamada distancia al plano de visión y según el valor
que tenga, deformará mas o menos la perspectiva
Prueba con varios valores y ya lo entenderás.
Bueno, esto es todo por esta vez. Esperamos que estos conceptos te sean de
utilidad para desarrollar tu propio sistema 3D.
NOTA ENCANTA: La dirección postal ha sido omitida. |