archivo

Archivos Mensuales: septiembre 2010

Analizamos un programa que nos permite dibujar formas tridimensionales y hacerlas rotar. Con este pequeño programa podemos pasar un rato de entretenimiento y de paso aprender algunos principios simples de la rotación y manipulación de figuras tridimensionales.

Los comentarios y el programa han sido extraídos de la enciclopedia Mi Computer y adaptados al Sinclair QL y a su SuperBASIC.

La siguiente imagen nos muestra la pantalla del programa en acción.

Rotación 3D en SuperBASIC

Su operatoria es sencilla, el control del punto de vista se ejerce mediante las teclas del cursor individualmente y la tecla CTRL con las teclas de cursor (se muestra un panel de ayuda en la zona derecha de la pantalla). La pulsación de estas teclas proporcionarán respectivamente: un movimiento del punto de vista hacia la izquierda, derecha, arriba, abajo; hacia el objeto o alejándose del mismo; y un aumento del efecto de perspectiva (ojo de pez) o una disminución del efecto de perspectiva (teleobjetivo).

Su código fuente es el siguiente:

100 REMark -----------------------------------------------
110 :
120 :
130 CLEAR: RESTORE
140 :
150 Main
160 :
170 CLEAR: RESTORE
180 STOP
190 :
200 :
210 REMark -----------------------------------------------
220 :
230 :
240 DEFine PROCedure Main
250   LOCal k%, op
260   :
270   Inicializa
280   InicializaVentanas
290   MuestraInstrucciones
300   :
310   REPeat buclePrincipal
320     DibujaFigura (7)
330     k% = CODE(INKEY$(-1))
340     op = k%
350     DibujaFigura (0)
360     :
370     SELect ON op
380       = 200
390         RotaDerecha
400       = 192
410         RotaIzquierda
420       = 208
430         RotaArriba
440       = 216
450         RotaAbajo
460       = 210
470         PerspectivaAumentar
480       = 218
490         PerspectivaDisminuir
500       = 202
510         Acercar
520       = 194
530         Alejar
540       = 81, 113, 27
550         EXIT buclePrincipal
560     END SELect
570     :
580   END REPeat buclePrincipal
590   :
600   Finaliza
610   :
620 END DEFine
630 :
640 :
650 DEFine PROCedure Inicializa
660   LOCal i
670   :
680   REMark --- Variables globales
690   DIM P(50), X(50), Y(50), Z(50), A(50), B(50)
700   n = 16
710   d = 10
720   pp = .5
730   si = SIN(9E-2)
740   co = COS(9E-2)
750   FOR i = 1 TO n
760     READ P(i),X(i),Y(i),Z(i)
770   END FOR i
780 END DEFine
790 :
800 :
810 DEFine PROCedure DibujaFigura (color%)
820   LOCal i
830   FOR i = 1 TO n
840     A(i) = X(i) * 300 / (pp * Z(i) + d)
850     B(i) = Y(i) * 300 / (pp * Z(i) + d)
860     A(i) = A(i) + 60
870     B(i) = B(i) + 50
880   END FOR i
890   INK#4, color%
900   FOR i = 1 TO n
910     IF P(i) = 0 THEN POINT#4, A(i), B(i)
920     IF P(i) = 1 THEN LINE#4 TO A(i), B(i)
930   END FOR i
940 END DEFine
950 :
960 :
970 DEFine PROCedure RotaDerecha
980   LOCal xx, zz, i
990   FOR i = 1 TO n
1000     xx = X(i) * co - Z(i) * si
1010     zz = Z(i) * co + X(i) * si
1020     X(i) = xx
1030     Z(i) = zz
1040   END FOR i
1050 END DEFine
1060 :
1070 :
1080 DEFine PROCedure RotaIzquierda
1090   LOCal xx, zz, i
1100   FOR i = 1 TO n
1110     xx = X(i) * co + Z(i) * si
1120     zz = Z(i) * co - X(i) * si
1130     X(i) = xx
1140     Z(i) = zz
1150   END FOR i
1160 END DEFine
1170 :
1180 :
1190 DEFine PROCedure RotaAbajo
1200   LOCal yy, zz, i
1210   FOR i = 1 TO n
1220     yy = Y(i) * co + Z(i) * si
1230     zz = Z(i) * co - Y(i) * si
1240     Y(i) = yy
1250     Z(i) = zz
1260   END FOR i
1270 END DEFine
1280 :
1290 :
1300 DEFine PROCedure RotaArriba
1310   LOCal yy, zz, i
1320   FOR i = 1 TO n
1330     yy = Y(i) * co - Z(i) * si
1340     zz = Z(i) * co + Y(i) * si
1350     Y(i) = yy
1360     Z(i) = zz
1370   END FOR i
1380 END DEFine
1390 :
1400 :
1410 DEFine PROCedure Acercar
1420   d = d * .9
1430 END DEFine
1440 :
1450 :
1460 DEFine PROCedure Alejar
1470   d = d / .9
1480 END DEFine
1490 :
1500 :
1510 DEFine PROCedure PerspectivaAumentar
1520   pp = pp * 1.5
1530 END DEFine
1540 :
1550 :
1560 DEFine PROCedure PerspectivaDisminuir
1570   pp = pp / 1.5
1580 END DEFine
1590 :
1600 :
1610 DEFine PROCedure InicializaVentanas
1620   CLS:CLS#0:CLS#2
1630   :
1640   OPEN#4,scr_385x256a0x0
1650   BORDER#4,1,3
1660   INK#4,7:PAPER#4,0:CLS#4
1670   SCALE#4,105,0,0
1680   :
1690   OPEN#5,scr_129x256a383x0
1700   BORDER#5,1,3
1710   INK#5,5:PAPER#5,0:CLS#5
1720   :
1730 END DEFine
1740 :
1750 :
1760 DEFine PROCedure MuestraInstrucciones
1770   PRINT#5,""
1780   INK#5,7
1790   PRINT#5, " Rotaci–n 3D"
1800   PRINT#5, " en SuperBasic"
1810   PRINT#5, " -------------"
1820   PRINT#5,""
1830   INK#5,5
1840   PRINT#5, " ½ Rotar derecha"
1850   PRINT#5, " ¼ Rotar izquierda"
1860   PRINT#5, " ¾ Rotar arriba"
1870   PRINT#5, " ¿ Rotar abajo"
1880   PRINT#5, " Ctrl½ Acercar"
1890   PRINT#5, " Ctrl¼ Alejar"
1900   PRINT#5, " Mayus¾ Perspec. +"
1910   PRINT#5, " Mayus¿ Perspec. -"
1920   PRINT#5, " "
1930   PRINT#5, " (Q) Salir"
1940 END DEFine
1950 :
1960 :
1970 DEFine PROCedure Finaliza
1980   CLOSE#4:CLOSE#5
1990   CLS:CLS#2:CLS#0
2000 END DEFine
2010 :
2020 :
2030 DATA 0,1,1,1,     1,1,1,-1,    1,-1,1,-1
2040 DATA 1,-1,1,1,    1,1,1,1
2050 DATA 1,1,-1,1,    1,1,-1,-1,   1,-1,-1,-1
2060 DATA 1,-1,-1,1,   1,1,-1,1
2070 DATA 0,1,-1,-1,   1,1,1,-1
2080 DATA 0,-1,-1,-1,  1,-1,1,-1
2090 DATA 0,-1,1,1,    1,-1,-1,1

El programa utiliza algunos principio geométricos para crear proyecciones en perspectiva de objetos que se pueden contemplar desde cualquier ángulo o distancia. Todos los datos para los objetos están, en nuestro ejemplo, almacenados en sentencias DATA dentro del programa. Éstos comprenden coordenadas tridimensionales para cada punto final de una línea del objeto. Para cada punto hay, asimismo, una cifra que indica si está al comienzo de una línea o en su final, esto nos informará si la línea se ha de trazar desde o hacia dicho punto.

La conversión de estas coordenadas tridimensionales en valores bidimensionales que representen puntos en la pantalla es una cuestión simple, aunque extensa, y puramente matemática. Las coordenadas X e Y de cada punto, en el plano de la pantalla, se dividen por un factor que representa la distancia del objeto en relación a nosotros. Además, la coordenada resultante se escala en función de un factor apropiado para el sistema de coordenadas de nuestro ordenador. Cambiando el factor distancia, se puede lograr que el objeto se encoja o agrande a medida que se acerca o se aleja del observador.

Se puede utilizar una tercera constante para cambiar el efecto de proyección en perspectiva. Incrementado el valor de esta constante, se exagera la vista en perspectiva del objeto, como si se estuviera contemplando con una lente de ojo de pez. La disminución de esta constante da el efecto de aplanar la vista, como si estuviésemos mirando a través de un teleobjetivo.

Además de crear una vista en perspectiva del objeto, el programa también permite hacerlo rotar de modo que se lo pueda contemplar desde cualquier ángulo. Ello se consigue mediante trigonometría. Los ejes giran el ángulo deseado de forma que cuando se efectúa la proyección en perspectiva parece que la imagen de la pantalla ha girado. Esto se puede hacer bien como una rotación a través del eje Y (el punto de vista parece moverse alrededor del objeto) o bien alrededor del eje X (el punto de vista de desplaza por arriba o por debajo del objeto).

Las coordenadas tridimensionales corrientes se almacenan en tres matrices: X, Y y Z. Los cambios en estas matrices y los cambios en las constantes utilizadas para la transformación de la perspectiva se llevan a cabo en una serie de subrutinas. Cada vez que se detecta una pulsación de tecla, se borra la imagen de la pantalla dibujándola en el color de fondo, se realiza el cambio deseado con una llamada a la subrutina apropiada y se vuelve a dibujar la nueva imagen.

La transformación de la perspectiva se realiza en la subrutina que dibuja la imagen. Ésta pasa por cada juego de coordenadas tridimensionales, las traduce a bidimensionales y las traza en la pantalla (desplazándose a los puntos o dibujando líneas de acuerdo al cuarto dato para cada punto).

Crearnos nuestros propios datos de objetos para este programa es una cuestión algo tediosa pero relativamente fácil. Los datos se almacenan en sentencias al final del programa, con cuatro valores para cada punto del objeto. El número total de puntos se establece en una variable del programa, la cual habrá de modificarse para adaptarla a los datos propios de cada caso. Los datos que proporcionamos en este programa de ejemplo crean un cubo.

Cada juego de cuatro valores está por este orden: valor trazar o dibujar, coordenada X, coordenada Y, coordenada Z. Los valores se calcula siguiendo mentalmente el boceto del objeto en tres dimensiones. Utilizando un lápiz imaginario, debes visitar cada vértice del esquema del objeto uno a uno. Si tu lápiz se desplaza hasta un punto sin dibujar una línea, se utiliza el valor 0 para el primer valor. Un valor de 1 indica que se ha de trazar una línea hasta el punto desde el punto precedente.

El origen de las coordenadas (0,0) está en el centro de la pantalla. Lo mejor es hacer que éste sea el centro de tu objeto. El eje X es eje horizontal y el eje Y es el vertical, con valores positivos yendo hacia la derecha y hacia arriba respectivamente. El eje Z es el eje hacia dentro y hacia fuera de la pantalla.

Mantén los valores de X, Y y Z tan pequeños como sea razonablemente posible. Alterando los valores de escalado podemos ajustar el objeto al tamaño deseado. Un ejercicio entretenido pude ser experimentar con objetos sólidos simples (una pirámide, un cubo) y luego pasar o otros objetos más complicados.

Nuestro programa se podría ampliar aún más para proporcionar efectos adicionales. Se podría incorporar una facilidad de traslación para desplazar el objeto, sin rotación, en relación al origen de las coordenadas (esto es bastante simple). Otra mejora es intentar incorporar una rutina para eliminar las líneas y las posiciones de líneas que quedan ocultas a la vista. Con ello se lograría hacer que la actual imagen, como construida en alambre, tuviera un aspecto más realista. No obstante, la eliminación de estas líneas ocultas es un asunto enormemente complicado ya que exige unas matemáticas muy complejas.


Funete: Enciclopedia “Mi Computer”, fascículo 47.

Anuncios