|
|
Artículo realizado por
¿Qué tal ha ido el mes de Agosto?...a los ordenadores ya sabéis
que fatal porque eso de 40 grados a la sombra les sienta como un ladrillo
al estomago!!!
Bueno pues aquí ando de nuevo para seguiros llenando la cabeza
de "3Dmanias" mías...8). Si recordáis, en el anterior capítulo
hablábamos de interacción y programación orientada
al evento. Gracias a eso ya debiéramos ser medianamente capaces
de crear una ventana para "graficar" sobre ella. Además hablamos
de control del ratón, del teclado, de menús... Finalicé
el capitulo puntualizando la necesidad de utilizar el "frame buffer"
para así evitar el "flicker" o molesto parpadeo en pantalla.
¿Intentásteis compilar el programa de la pasada edición?,
espero que funcionara correctamente y os aclarara muchísimas dudas.
Hoy inauguramos un nuevo capítulo que considero el más
importante de todos. Antes de poder crear un escenario tendremos que modelar
y posicionar toda la geometría en su sitio. Esto solo será
posible mediante la correcta aplicación de diferentes conceptos
algebraicos que hoy mismo empezaré a relataros.
Sé que puede parecer algo pesado hablar un poco de Algebra
pero creedme si os digo que es totalmente IMPRESCINDIBLE si queréis
generar imágenes realistas 3D. Si nó, ¿cómo
sabríais la trayectoria que sigue un proyectil en un juego?, o ¿cómo
deduciríais lo que el personaje debe ver si gira el cuello a la
derecha un ángulo de 20 grados?, o ¿cómo generaríais
correctamente proyecciones del mundo 3D a la pantalla 2D?
Vamos a ello que me parece que ya os tengo medio convencidos/as...
Algebra afín.
En gráficos trabajamos con conjuntos de objetos geométricos
como puntos, líneas, polígonos...pero en definitiva podemos
generar cualquier objeto por complejo que sea a partir de tres entidades
mínimas, siempre necesarias:
Espacios vectoriales
Un espacio vectorial es un conjunto, ¿de?, venga hombre ¿de?...pues
de vectores claro...por eso se llama vectorial, ¿no?. Además
de vectores existen dos operaciones definidas en el espacio. Suelen ser:
En un espacio vectorial siempre existe un elemento distinguido y especial.
Es lo que suele llamarse origen o vector nulo 0. Respecto
a este se cumplen algunas propiedades casi siempre obvias como que:
Oscar García "Kokopus".
Capitulo 5
Objetos geométricos y sus transformaciones.
Paralelamente necesitamos definir conjuntos de entidades que cumplan unos
ciertos requisitos. Me refiero a los "temidos" espacios que suelen mencionarse
en toda clase de Algebra lineal y matricial que se precie. Comentaré
3 de ellos:
Suenan rarísimos pero ya veréis que la parte mas difícil
es precisamente esa, el nombre!!
Con los vectores y con estas operaciones asociadas podremos hacer "maravillas"
que en pantalla deleitarán a nuestros ojos por medio de animaciones,
transformaciones y efectos especiales.
Operando entre dos vectores (o sea sumándolos) se cumplirá:
Hombre creo que las imágenes ya hablan por sí solas. Además probablemente ya te hayan explicado esto en alguno de tus cursos. De todas formas lo comentaré por si acaso....que pa esssooo soy el profeeeee!!!!
La multiplicación de un vector por un escalar cambia su longitud pero jamas su dirección (recordad que la dirección es la línea imaginaria sobre la que el vector se apoya...). También podríamos cambiar el sentido de un vector si lo multiplicáramos por un escalar negativo.
En cuanto a la suma de vectores, se define por el "axioma cabeza-cola" como dicen los americanos. Creamos el vector
w = u + v
a partir de unir la cabeza de u a la cola de v, como tenéis reflejado en la figura anterior.
En temas gráficos hablaremos sobre todo de un espacio vectorial, Rn llamado producto cartesiano de n valores reales. ¿A qué me refiero?, hombre suena fatal pero es muy sencillo:
Se cogen n números reales u1, u2, u3, ... , uN...
y se escriben como un vector de los de toda la vida (u1, u2, u3, ... , uN) y ya tenemos un nuevo miembro de Rn.
Por tanto usaremos vectores geométricos que escritos sobre el papel serán miembros de Rn.
Hablemos de combinaciones lineales.....¿por favor nooooo?, ¿que hemos hecho para merecer estoooo?...no fastidiéis que no es para tanto!.....ehemmm. Se define una combinación lineal "a pelo" como algo así:
Dados v1, v2, ... , vN vectores y a1, a2, ... , escalares reales....pues su combinación lineal será un nuevo vector w tal que:
Infinidad de objetos complejos pueden representarse internamente, antes de dibujarlos, como combinaciones lineales de otros. Mirad cómo podemos generar una línea recta o un plano a partir de combinaciones lineales:
Se dice que un vector u es linealmente dependiente de un conjunto de vectores S cuando puede obtenerse el citado vector u como una combinación lineal de los vectores de S. En caso contrario se dice que u es linealmente independiente de S.
En el primer caso hablamos de crear un objeto a partir de otros ya existentes. En el segundo caso es imposible crear el susodicho objeto a partir de los que ya tenemos. Veremos ejemplos en breve, no desesperéis.
Todo espacio vectorial puede generarse siempre a partir de unos pocos vectores. Es decir que todo vector que forme parte de un espacio vectorial podré generarlo siempre como una combinación lineal de otros vectores....siempre y cuando los escoja adecuadamente.O sea...
El vector (1,2,5) de R3 puede obtenerse como 1·(1,0,0) + 2·(0,1,0) + 5·(0,0,1). Es decir que el vector se obtiene como una combinación lineal de los vectores (1,0,0), (0,1,0) y (0,0,1) que son base de R3 y por tanto este es un espacio de dimensión igual a 3.
A los números 1,2 y 5 se les llama las componentes o coordenadas del vector (1,2,5) en función de la base (1,0,0), (0,1,0), (0,0,1). Esta es la base mas típica de todas y se la conoce como base canónica.
Un mismo espacio puede tener muchas bases. Puede darse el caso de que deseemos "pasar de una base a otra". Un vector expresado en función de una base tendremos que expresarlo en función de otra distinta, ¿como?...pues utilizando una matriz de cambio de base.
En gráficos nos daremos de bruces con este problema continuamente. Mirad la figura:
NOTA: con "sqr" me refiero al valor de la raiz cuadrada.
El mismo vector tiene unas componentes a1, a2 y a3 respecto a un eje y otras componentes b1, b2 y b3 respecto del segundo. Pensad que las componentes en cada dirección coinciden con el valor de las proyecciones del vector en cada eje.
Son dos sistemas de referencia o ejes (SR) distintos respecto a los cuales podemos referenciar a nuestro vector. Para pasar de un eje al otro aplicaremos una matriz de transformación, tal y como veremos mas adelante en profundidad.
Bueno bueno...¿os vais situando al menos un poquitín?...ya se que es duro y deberéis practicarlo ante todo para acabar teniéndolo claro.
Espacios afines
Un espacio afín es básicamente un espacio vectorial al cual le añadimos una tercera entidad: puntos. Por tanto en un espacio afín contamos con:
Si P, Q son dos puntos y v, w son vectores...
P + v = Q, o sea que si a un punto le añadimos un vector...tenemos un nuevo punto!!! y por tanto Q - P = v, una resta entre dos puntos es un vector.
Mas claro....mirad la figura:
Observad que es super-intuitivo y claro... fácil de imaginar en definitiva.
Solemos hablar en estos espacios de combinaciones afines entre puntos. Dados P, Q puntos y t escalar real...entonces:
De hecho estamos haciendo justo lo que comentábamos. Q - P es un vector, a este le aplicamos un factor de escala (o sea cambiamos su longitud) al multiplicarlo por el escalar t. Obtenemos un nuevo vector que añadimos a un punto, o sea a P, y por tanto al final hemos generado un nuevo punto llamado H.
Observad que la única multiplicación existente es t·(Q - P), que es un escalar por un vector y por tanto la hemos definido. Si yo retoco la expresión anterior y la dejo así:
entonces nos quedan dos productos ( (1 - t)·P y t·Q ) de un escalar por un punto y eso ni lo hemos definido ni lo imaginamos geométricamente. ¿Que es un punto al cual se le multiplica por un escalar?. No os preocupéis por esto, son jugadas matemáticas que pueden apartarnos de nuestro camino. No le daremos mas importancia pero lo usaremos si se nos antoja pues MATEMATICAMENTE es correcto.
Se dice que la combinación afín es convexa si el parámetro escalar t tiene un valor comprendido entre 0 y 1.
Ecuación de una línea
Pues ya lo hemos hecho. Si a un punto inicial le sumo un vector...puedo obtener cualquier otro punto que pertenece a la línea que los contiene a ambos (punto y vector). Mirad la figura 4 para tenerlo más claro.
Nuestra línea tiene la ecuación:
donde P es un punto, la resta Q-P nos da un vector y lo alargamos más o menos con el escalar t...
o en forma paramétrica (el parámetro es t):
recordando siempre que t es un número real.
Ecuación de un plano
Similar a la de una línea pero algo mas compleja. Supongamos que tenemos tres puntos P, Q y R que no son colineales (no pertenecen a la misma línea). El plano en el que los tres se encuentran se define como:
¿y eso de que manga te lo has sacado Oscar?. Se trata de obtener una expresión que nos permita obtener a su vez cualquier punto del plano al cual nos referimos (o sea el plano que contiene a P, Q y R). En ese caso podemos generar todo el plano ya que podemos encontrar todos sus puntos.
es una combinación afín de P y Q según t que me genera un nuevo punto H. Pues solo tengo que combinar ahora el nuevo punto H con otro que ya poseo, R:
y obtengo el punto final K que pertenece al plano. Si substituyo H por su valor obtengo la ecuación que os mostré 5 líneas arriba!!!
Mirad la figura:
Sistemas de referencia
Todo...ya sean puntos o vectores, puede referenciarse a un SR (sistema de referencia). Para definir un SR necesito:
Dificilmente trabajaremos en gráficos con un único sistema de referencia. Como mínimo usaremos tres: el del mundo 3D, el de la cámara y el de pantalla. Si recordáis el "pipeline" gráfico de los primeros capítulos, ya comenté que toda la geometría se crea en función del SR del mundo, es decir con coordenadas referidas al SR del mundo. Después debemos hacer un cambio de coordenadas del SR mundo al SR de la cámara, que es "la que ve" la escena. Después de esto hacemos un tercer cambio de coordenadas de 3D a 2D (frame buffer/pantalla).
Espacios euclidianos
Hemos hablado de escalares, de vectores, de puntos y de operaciones entre ellos. ¿Nos dejamos algo?, yo creo que sí. Aún no hemos hablado de distancias como la distancia entre dos puntos o el valor de la longitud que tiene un vector.
Señores/as, si queremos detectar colisiones entre objetos o reaccionar con un impacto a estas nos será imprescindible el conocimiento de lo que ahora os detallo.
En un espacio euclidiano tienen especial importancia los escalares y los vectores. Añadiremos una nueva operación que llamaremos producto escalar (en inglés "dot product") y que genera un número real a partir de dos vectores. Esta operación se define así:
El producto escalar cumple lo siguiente:
Es muy interesante también asociar el tema de proyecciones al producto escalar. Muchísimas veces nos interesa qué cantidad de un vector se encuentra en la dirección de otro. ¿Por que?, imaginemos un sencillo ejemplo. Un cubo esta a punto de rebotar en el suelo con un cierto ángulo, ¿como responderemos a eso?. Posiblemente miraremos el vector correspondiente a la velocidad del cubo, lo descompondremos en dos componentes: una normal (perpendicular) al plano de colisión y otra tangencial (paralela) a este. La componente normal al plano la negaremos y la multiplicaremos por un escalar que elimine parte de la velocidad en esa dirección (simulando la perdida energética que se produce en cualquier choque). Por ultimo sumaremos la componente tangencial con la normal "retocada" y dejaremos al sistema que siga simulando. Señores y señoras...acabamos de reaccionar a una colisión!!!
Ha sido necesario conocer que parte de la velocidad de nuestro cubo estaba orientada perpendicular y tangencialmente al plano de colisión. Y esa información la hemos obtenido porque sabíamos lo que ahora mismito os comento.
Mirad esta figura:
La cantidad del vector w en la dirección del vector v es lo que observáis como vector u. Por tanto, u es la proyección de w sobre v!!! y sabiendo u sabemos qué cantidad de nuestro vector w esta orientado en la dirección del otro vector v.
Observad que también podemos deducir el ángulo entre w y v tal y como expongo en la figura.
Veamos algunas aplicaciones de todo lo comentado hasta ahorita mismo.
Convexidad.
Se dice que un objeto es convexo cuando toda línea entre dos puntos que pertenecen al objeto está también incluida dentro de este. Os lo mostré en la segunda figura del capítulo 2.
La noción de convexidad es sumamente importante en el diseño de curvas y superficies así como en la detección de colisiones entre objetos complejos.
Muchas veces es necesario encontrar lo que en USA llaman el "convex hull" o mínimo envolvente convexo de un conjunto de puntos salteados. Se trata de la mínima superficie que los incluye a todos y se usa continuamente en detección de colisiones. Lo tenéis en la siguiente figura:
Circulo
La ecuación del circulo de la figura 8, apartado 1...
puede obtenerse como:
o sea que...
La deducción os la dejo a vosotros y a estas alturas, si me estáis siguiendo, no debería seros muy difícil...
Plano
El plano de la figura 8, apartado 2 lo definimos así:
(Q - P)·v = 0, porque (Q - P) es un vector, v es otro, son perpendiculares y por tanto su producto escalar tiene que ser forzosamente igual a 0.
Al vector v se le llama la "normal" al plano y es sumamente útil en cuanto a la iluminación de superficies, cosa que ya veremos en su momento.
Solo para documentaros algo mas, la ecuación del plano con vector normal de componentes (A,B,C,0) y que pasa por el punto (Xo,Yo,Zo,1) es:
El por qué el vector y el punto tienen 4 coordenadas lo veremos mas adelante cuando hablemos de coordenadas homogéneas, tema obligado en gráficos.
Distancia punto-plano
Miremos la figura 8, apartado 3, y pensemos que deseamos saber la mínima distancia entre...
Esta distancia es la proyección del vector R - P sobre el vector normal al plano v. Por tanto necesito calcular el producto escalar de R - P y v, para después dividirlo por || v ||.
Entonces si las coordenadas del punto R son (r,s,t), la distancia es:
Tened en cuenta que en la expresión tomamos la ecuación del plano A·x + B·y + C·z + D = 0, ecuación que podéis obtener directamente operando sobre A·(x - Xo) + B·(y - Yo) + C·(z - Zo) = 0.
Distancia punto-linea
Queremos saber cual es la distancia del punto R a la línea definida como P(t) en la figura 8, apartado 4.
La distancia mínima será la perpendicular de R a P(t). Por tanto deberá cumplirse que:
es el valor del parámetro t para tener la distancia mínima d.
NOTA: ni se os ocurra simplificar en la división el v del numerador con uno de los v's del término v·v del denominador. Son vectores y no se simplifican!!!
Si introducimos este valor de t en la expresión de P(t):
P' = Po + [(R - Po)·v / v·v ]·v, que es el punto de la línea P(t) mas próximo a R. Ahora solo nos falta obtener el vector entre R y P', cosa que ya sabemos hacer, y calcular su módulo. Esa es la distancia mínima d que buscábamos.
NOTA: si v = 0 "la cosa falla". Claro que si pero es que si v = 0 entonces P(t) tampoco es realmente una línea, ¿no os parece?.
Intersección plano-línea
Suponed que os interesa saber cual es la intersección entre la línea y el plano, es decir el punto P':
Analogamente al caso anterior, calcularemos el valor del parámetro t necesario para después introducirlo en la ecuación de nuestra línea obteniendo el punto de intersección P'.
Nuestro plano es (X - P)·v = 0 y nuestra línea es Q(t) = Q + t·w. Debemos resolver:
(Q(t) - P)·v = 0 ---> (Q + t·w -P)·v = 0 de donde t = (P - Q)·v / w·v. Por tanto el punto de intersección P’ es:
Producto vectorial
Podemos utilizar dos vectores u y v que no sean paralelos para generar un tercero w que sea ortogonal a ambos.
Este tercer vector w viene dado por el producto vectorial de los dos anteriores. Dentro de un SR determinado, si las coordenadas de u vienen definidas por a1, a2, a3 y las de v por b1, b2, b3...entonces el producto vectorial de ambos se define como:
Por otra parte podemos conocer el ángulo ANG entre u y v como:
donde || u x v || es el producto vectorial entre u y v.
Modelado de primitivas
En nuestro mundo 3D podemos tener una cantidad ingente de objetos geométricos mayor a la que tendríamos en una representación 2D. Su representación matemática puede complicarse mucho y esto no nos interesa si deseamos crear un aplicativo eficiente a nivel computacional. No queremos perder demasiado tiempo "calculando valores" para situar nuestra geometría en pantalla.
Existen complicadas representaciones basadas en curvas y superficies. Al fin y al cabo todo se acaba reduciendo a un objeto cuyas fronteras son planas y por tanto descriptibles usando:
A un sistema gráfico le es enormemente cómodo trabajar con triángulos. Si todas las caras de nuestros objetos están definidas por uniones de triángulos conseguiremos rendimientos fenomenales. Solo tenéis que mirar prestaciones de cualquier tarjeta aceleradora 3D del mercado para observar como "se las dan" generando millones de triángulos por segundo en pantalla.
¿A qué se debe esto?. Tres vértices que definan un triángulo estarán siempre en un mismo plano...seguro!!!...son lo que se dice coplanares. En cambio 4 vértices generando un rectángulo no tienen porque serlo...pensad un poco, agudizad vuestra capacidad de abstracción 3D y lo iréis viendo claro.
Generando triángulos estamos seguros de tener siempre vértices coplanares y os aseguro que la descarga de trabajo computacional que eso le supone a la CPU es impresionante.
En caso de tener una figura modelada con otro tipo de polígonos que no sean triángulos, siempre podemos arreglarlocon lo que los anglosajones llaman un proceso de "tesselation", o sea descomposición en triángulos. Cualquier polígono puede "partirse" literalmente en triángulos. Eso nunca es un problema. Mirad la figura 2 del segundo capítulo para recordar esto graficamente.
Existen algunas excepciones a este proceso de modelización como la geometría sólida constructiva (Constructive Solid Geometry - CSG en inglés). En esta aproximación se crean objetos complejos a partir de operar mediante uniones e intersecciones de objetos volumétricos más simples. Los resultados suelen ser buenos pero es una técnica muy complicada y costosa, y por eso muchas veces desechada.
Cambio entre sistemas de coordenadas
Un vector expresado en función de un SR determinado puede expresarse en función de otro SR. Nada más tendremos que aplicarle a las componentes del vector en función del primer SR una matriz de transformación que nos genere las componentes del mismo vector en función del segundo SR.
Es importante que entendáis que el vector en sí no cambia, sigue estando en el mismo sitio!!, lo que pasa es que lo referenciamos a otra parte.
Si no os ha quedado claro aquí va un ejemplo simple pero muy educativo. Si tenemos el coche aparcado en la calle y un amigo viene a casa y nos lo pide tendremos que explicarle dónde está ¿no?. Bien para facilitarle esa información podríamos decirle:
y en ambos casos el coche está en el mismo sitio pero lo "referenciamos" a dos SR’s diferentes...¿lo pilláis?. Espero que este ejemplillo os haga empezar a vislumbrar la luz!!.....8)
Matemáticamente hablando y cuando nos sea necesario implementarlo, usaremos la matriz de cambio de esta forma:
Asumamos que la base origen es S={v1,v2,v3}, o sea 3 vectores, y que la base final a la que deseamos "convertirnos" es S’={u1,u2,u3}. Todos los vectores de una base seguro que pueden ponerse como combinación lineal de los de la otra (ya que todos pertenecen al mismo espacio vectorial). Algo así:
u1 = a11·v1 + a12·v2 + a13·v3
u2 = a21·v1 + a22·v2 + a23·v3
u3 = a31·v1 + a32·v2 + a33·v3
entonces la matriz 3 x 3 (3 filas y 3 columnas):
| a11 a12 a13 |
M = | a21 a22 a23 |
| a31 a32 a33 |
nos da el cambio de base de S a S’. Análogamente la matriz inversa M-1 nos da el cambio de S’ a S.
En este caso si tenemos un vector w = (c1,c2,c3) componentes según la base S, entonces:
w’ = M·w
es el mismo vector pero expresado con componentes referidas a la base S’. Algo como:
w’ = (c1’,c2’,c3’), y que os quede claro que... w = (c1,c2,c3) = w’ = (c1’,c2’,c3’)...ya que es el mismo vector.
Sé sobradamente que muchos de los conceptos que os estoy presentando son difíciles de asimilar pero es algo por lo que forzosamente tendréis que pasar si queréis realizar aplicaciones 3D dignas.
Si contáis con algún manual o libro sobre Álgebra lineal y matricial os aconsejo que le echéis una mirada, al menos a lo que yo os he presentado.
Creo que sería muy interesante que tratarais de echar mano a papel y a lápiz para inventar más ejemplos de lo explicado. Luego deberíais codificarlos, por ejemplo en C, y probarlos en vuestra máquina observando los resultados numéricos que obtenéis y verificándolos con los obtenidos a puño y letra.
Para los más interesados ahí va una dirección interesantísima referida a la programación de algoritmos usando nuestro querido lenguaje C. La tenéis aquí.
Bueno ya os dejo por esta edición. Continuaremos en el próximo número en este mismo capítulo y bien metidos en faena con coordenadas homogéneas y transformaciones (traslaciones, rotaciones...) que ya podremos poner en práctica programando pues dispondremos de los conocimientos requeridos para ello.
Un abrazote y hasta ahora mismo!!!
|
|