CAPÍTULO IV

# Transformaciones geométricas en 2D y 3D

Las transformaciones geométricas son funciones que nos permiten mapear un conjunto de vectores a otro, esto al ser multiplicados por una matriz de transformación asociada a la transformación deseada. Este tipo de transformaciones son fundamentales en GC, ya que nos permiten modelar objetos, cambiando su posición y/o forma.

En este capítulo se describen las transformaciones geométricas más sencillas que son escalamiento, rotación y traslación, así como el efecto que tienen sobre los diferentes tipos de vectores, como son los vectores de desplazamiento, posición (puntos) y normales.

Se mostrará cómo transformar un conjunto de puntos, esto representando a los puntos como vectores desplazados desde el origen, es decir, los puntos hacen referencia al punto final de los vectores (final de la flecha) con su punto inicial en el origen.

En particular, veremos ejemplos del efecto que tienen dichas transformaciones sobre objetos o modelos (conjunto de puntos) muy simples.

Como se mencionó en el Capítulo 2, los vectores serán representados por vectores columna para el manejo de operaciones. Es importante considerar el tipo de representación a usar, ya que puede afectar tanto al orden en el que se multiplicarían las matrices como al orden de las entradas de éstas.

## Transformaciones geométricas en 2D

Para transformar vectores 2D podemos utilizar matrices $2 \times 2$: $$ \begin{bmatrix} a & b \\ c & d \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} ax + by \\ cx + dy \end{bmatrix} = \begin{bmatrix} x' \\ y' \end{bmatrix} $$

Este tipo de operación es una transformación lineal, donde se toma a un vector

2D y se obtiene a otro vector 2D como resultado. Con esta simple operación podemos tener una variedad de transformaciones muy útiles.

Otra forma de pensarlo es como una transformación del sistema de coordenadas. Asumiendo que las matrices de transformación son invertibles, vale la pena notar que dicha transformación es parecida a un cambio de base, donde se recibe a un vector en la base descrita por los vectores columna de la matriz, y se obtiene a un vector con sus coordenadas descritas en la base canónica.

### Escalamiento

Una transformación de escalamiento como su nombre lo indica, permite cambiar el tamaño de un objeto. En particular, para escalar a un vector, necesitamos multiplicar a cada una de sus coordenadas por un factor de escalamiento, esto es $$ x' = S_x \cdot x \quad \text{ y } \quad y' = S_y \cdot y$$

de modo que si $ \mid S_x \mid > 1 $ se agranda en dirección del eje $x$, y sí $ 0 \leq \mid S_x \mid < 1$ se encoge, análogamente con $S_y$.

Escalamiento. Se aplica la matriz $\mathbf{S}(S_x,S_y)$ sobre cada vértice del triángulo.

Se dice que es un escalamiento uniforme cuando sus factores de escalamiento son iguales $S_x = S_y$, en otro es un escalamiento no uniforme.

Por consiguiente, la matriz de transformación es: $$ \mathbf{S}( S_x, S_y) = \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix} $$

Puesto que $$ \begin{bmatrix} S_x & 0 \\ 0 & S_y \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} S_x \cdot x \\ S_y \cdot y \end{bmatrix} = \begin{bmatrix} x' \\ y' \end{bmatrix} $$

Como mencionamos anteriormente, esta operación es parecida a un cambio de base, en este caso es como si tomáramos a un vector representado por una base escalada y lo describiéramos con la base canónica.

### Rotación

Supongamos que tenemos un vector $\mathbf{v} = (x,y)$ y lo queremos rotar $\phi$ grados con respecto al origen, en sentido contrario a las manecillas del reloj, obteniendo $\mathbf{v}'=(x',y')$.

Rotación de un vector $\mathbf{v}$.

Observemos que $r = \lVert \mathbf{v} \rVert$ y además que entre $\mathbf{v}$ y el eje $x$ se forma un ángulo $\theta.$ Entonces, podemos parametrizar a $\mathbf{v}$ como $$ x = r \cos\theta \qquad y = r \sin\theta $$ Y como $\mathbf{v'}$ es $\mathbf{v}$ rotado $\phi$ grados, su longitud sigue siendo $r$ y termina formando un ángulo de $\theta + \phi$, entonces $$ x' = r \cos(\theta + \phi) \qquad y' = r \sin (\theta + \phi) $$

Sustiuímos por sus identidades trigonométricas, quedando $$ x'= r [ \cos\theta \cos\phi - \sin\theta \sin\phi] \qquad y'= r [ \sin\theta \cos\phi + \cos\theta \sin\phi]$$ $$ \Rightarrow \quad x'= {\color{red}\underbrace{\color{black}r \cos\theta}_{\color{black}x}} \cos\phi - {\color{red}\underbrace{\color{black}r\sin\theta}_{\color{black}y}} \sin\phi \qquad y'= {\color{red}\underbrace{\color{black}r \sin\theta}_{\color{black}y}} \cos\phi + {\color{red}\underbrace{\color{black}r\cos\theta}_{\color{black}x}} \sin\phi$$ $$ \Rightarrow \quad x'= x\cos\phi - y\sin\phi \qquad y'= y\cos\phi + x\sin\phi$$

Rotación. Se aplica la matriz $\mathbf{R}(\phi)$ sobre cada vértice del triángulo.

Finalmente la matriz de transformación es $$ \mathbf{R}(\phi) = \begin{bmatrix} \cos \phi & - \sin \phi \\ \sin \phi & \cos \phi \end{bmatrix} $$

Puesto que $$ \begin{bmatrix} \cos \phi & - \sin \phi \\ \sin \phi & \cos \phi \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} x \cos \phi - y \sin \phi \\ x \sin \phi y + \cos \phi \end{bmatrix} = \begin{bmatrix} x' \\ y' \end{bmatrix}$$

Análogamente, en sentido de las manecillas del reloj estaría dada por

$$ \mathbf{R}(\phi) = \begin{bmatrix} \cos \phi & \sin \phi \\ -\sin \phi & \cos \phi \end{bmatrix} $$

Y de manera similar al escalamiento podemos pensar a los vectores recibidos en una base rotada y finalmente descritos con la base canónica.

### Traslación

La transformación de traslación es la más sencilla de todas, ya que basta desplazar ciertas unidades en dirección del eje $x$ o $y$ para generar un movimiento sobre éstos, de modo que $$x' = x + T_x \quad \text{y} \quad y'= y + T_y$$ $$ \begin{bmatrix} x \\ y \end{bmatrix} + \begin{bmatrix} T_x \\ T_y \end{bmatrix} = \begin{bmatrix} x + T_x \\ y + T_y \end{bmatrix} = \begin{bmatrix} x' \\ y' \end{bmatrix}$$

Traslación. Se traslada cada vértice del triángulo sumándole el vector $(T_x,T_y).$

## Transformaciones en coordenadas homogéneas

Con la última transformación podemos notar que para mover un objeto es necesario sumar otro vector a los puntos en lugar de multiplicarlos por una matriz de transformación. Por definición, una transformación lineal es una función que preserva la suma y la multiplicación por escalar; en particular, el origen $(0,0)$ se mantiene fijo. En cambio, con la transformación de traslación vemos que no se satisfacen dichas propiedades.

Esta diferencia hace que se pierda cierta consistencia en el manejo de las transformaciones. Imaginemos que primero queremos escalar y después rotar al punto $P_0$.

Entonces, primero le aplicaríamos una matriz de escalamiento $\mathbf{S}$, obteniendo $$ P_1 = \mathbf{S} \ P_0,$$

y luego la matriz de rotación $\mathbf{R}$, siendo $$P_2 = \mathbf{R} \ P_1$$ Recordemos que la multiplicación de matrices es asociativa, entonces $$P_2 = \mathbf{R} (\mathbf{S} \ P_0) = (\mathbf{RS}) \ P_0 = \mathbf{M} \ P_0 \quad \textrm{donde} \ \mathbf{M} = (\mathbf{RS})$$ Por lo tanto, podemos representar a estas dos transformaciones con una sola matriz, al multiplicar ambas (de izquierda a derecha), a esto se le conoce como composición de transformaciones. Del mismo modo podemos representar a la secuencia de matrices que queramos aplicar como una sola, esto mientras se trate de escalamientos y/o rotaciones (por ahora).

Ya que si queremos aplicar además una traslación quedaría del siguiente modo: $$P_3 = \mathbf{M} P_0 + \mathbf{T}$$ Pues ya vimos que no hay forma de trasladar objetos haciendo una multiplicación con matrices de $2 \times 2$. Por lo que, la expresión empieza a complicarse y se va volviendo menos eficiente. No olvidemos también que es común trabajar con objetos grandes, así como con muchos de ellos, por lo que es más conveniente trabajar con una sola matriz, ya que ésta sería aplicada sobre todos los puntos de los modelos y se reducirían los cálculos.

Con el fin de poder seguir trabajando con esta misma idea, se introdujo el concepto de coordenadas homogéneas, donde se agrega una tercera coordenada $W$ a los puntos 2D: $$P = \begin{bmatrix} x \\ y \\ W\end{bmatrix}$$

De modo que si queremos obtener de vuelta a nuestro punto (en coordenadas Cartesianas), basta dividir las coordenadas sobre $W$, es decir, $ P = ( x, y, W) \rightarrow ( x/W, y/W)$, con $W \not = 0$.

Como consecuencia, sí dos puntos en coordenadas homogéneas son múltiplos, quiere decir que son iguales, por ejemplo, el punto $(1,3,2)$ es igual al punto $(2,6,4)$. Sin embargo, se suele utilizar $W=1$ para los vectores de posición.

Del mismo modo, necesitamos usar matrices de transformación de una dimensión mayor, en este caso, una matriz $3 \times 3$, para así poder efectuar la multiplicación con los puntos. Con ello, se puede incluir la traslación en la última columna de la matriz, esto es $$ \mathbf{T}( T_x, T_y) = \begin{bmatrix} 1 & 0 & T_x \\ 0 & 1 & T_y \\ 0 & 0 & 1 \end{bmatrix} $$

Pues como podemos observar al aplicarla sobre un punto arbitrario $P$, obtenemos $$ \mathbf{T} \ P = \begin{bmatrix} 1 & 0 & T_x \\ 0 & 1 & T_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix} x + T_x \\ y + T_y \\ 1 \end{bmatrix}$$ Mientras que las transformaciones de escalamiento y rotación permanecieron en sus mismas entradas $$ \mathbf{S}( S_x, S_y) = \begin{bmatrix} S_x & 0 & 0 \\ 0 & S_y & 0 \\ 0 & 0 & 1 \end{bmatrix} $$ $$ \mathbf{R}(\phi) = \begin{bmatrix} \cos \phi & - \sin \phi & 0 \\ \sin \phi & \cos \phi & 0 \\ 0 & 0 & 1 \end{bmatrix} $$

Por otra parte, también necesitamos transformar vectores de dirección o desplazamiento, los cuales no deberían ser afectados por la traslación. Por esta razón, para este tipo de vectores se decidió cambiar a la última componente por un cero, es decir, $W = 0$.

De este modo, tanto la rotación como el escalamiento siguen siendo efectuados, mientras que la traslación es multiplicada por cero e ignorada.

Por lo que ahora podemos representar a una transformación lineal seguida de una traslación con una sola matriz, y a este tipo de transformaciones se les conoce como transformaciones afín.

Transformaciones afín. Se aplica la matriz $\mathbf{M} = \mathbf{T}(T_x,T_y) \mathbf{R}(\phi) \mathbf{S}(S_x,S_y)$ sobre cada vértice del triángulo.

#### Rotación y escalamiento con respecto a un punto arbitrario.

Una secuencia de transformaciones muy común y bastante sencilla, es cuando queremos rotar $\theta$ grados a un objeto con respecto a un punto arbitrario $Q = (Q_x,Q_y)$ diferente al origen. Por ejemplo, cuando queremos rotarlo sobre su baricentro.

Esta secuencia es la siguiente:

1. Trasladar el objeto $\mathbf{T}(-Q_x,-Q_y)$ de modo que $Q$ quede en el origen.
2. Rotar el objeto $\theta$ grados $\mathbf{R}(\theta)$.
3. Trasladar el objeto de regreso $\mathbf{T}(Q_x,Q_y)$ de modo que $Q$ quede en su posición original.

Entonces, la matriz de transformación final está dada por la composición de dichas transformaciones, y se escribiría como $$\mathbf{T}(Q_x,Q_y) \ \mathbf{R}(\theta) \ \mathbf{T}(-Q_x,-Q_y) = \begin{bmatrix} 1 & 0 & Q_x \\ 0 & 1 & Q_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} \cos \theta & - \sin \theta & 0 \\ \sin \theta & \cos \theta & 0 \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & -Q_x \\ 0 & 1 & -Q_y \\ 0 & 0 & 1 \end{bmatrix}$$ $$= \begin{bmatrix} \cos \theta & - \sin \theta & -Q_x \cos \theta + Q_y \sin \theta + Q_x \\ \sin \theta & \cos \theta & -Q_x \sin \theta -Q_y \cos \theta + Q_y \\ 0 & 0 & 1 \end{bmatrix} $$

En el siguiente ejemplo se muestra dicha secuencia, rotando un rectángulo sobre su baricentro $C = (C_x,C_y)$.

De manera análoga se haría un escalamiento con respecto a un punto, al simplemente reemplazar la matriz de transformación en el punto 2 por una matriz de escalamiento.

Es importante recordar que la multiplicación de matrices no es conmutativa, por lo que debemos definir bien el orden, de lo contrario el resultado podría ser diferente al que esperamos.

En el siguiente interactivo se puede apreciar mejor este último punto, en donde se presentan dos secuencias muy sencillas, utilizando únicamente dos matrices: $\mathbf{R}(40\degree)$ y $\mathbf{S}(1,0.5)$, en distinto orden.

## Transformaciones geométricas en 3D

Las transformaciones geométricas en 3D son una extensión de las 2D. Por lo que, de manera análoga a las transformaciones en 2D, éstas pueden efectuarse a través de una matriz de transformación $ 4 \times 4 $.

Ya que, si empezamos analizando el caso de la traslación, podemos notar nuevamente que necesitamos extender nuestras coordenadas, agregando una dimensión más, es decir, utilizando coordenadas homogéneas. Por lo que, nuestros vectores de posición serían de la forma $P = (x, y, z, 1)$ y los de des-

plazamiento $\mathbf{d} = (x, y, z, 0).$

Entonces, la transformación de traslación estaría dada por la transformación $$x' = x + T_x \quad y' = y + T_y \quad z' = z + T_z $$

$$ \text{y su matriz se define como} \quad \mathbf{T}(x,y,z) = \begin{bmatrix} 1 & 0 & 0 & T_x \\ 0 & 1 & 0 & T_y \\ 0 & 0 & 1 & T_z \\ 0 & 0 & 0 & 1 \end{bmatrix}$$

Mientras que la de escalamiento a lo largo de los ejes sería $$x' = S_x \cdot x \quad y' = S_y \cdot y \quad z' = S_z \cdot z$$ $$ \mathbf{S}(x,y,z) = \begin{bmatrix} S_x & 0 & 0 & 0 \\ 0 & S_y & 0 & 0 \\ 0 & 0 & S_z & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} $$

Por otro lado, la transformación de rotación se complica un poco, ya que a diferencia de las transformaciones en 2D (en las que sólo nos preocupábamos por rotar con respecto al origen) tenemos que definir primero con respecto a cuál de los tres ejes se va a rotar.

Cabe recalcar que seguimos tratando con rotaciones positivas, por lo que son en sentido contrario a las manecillas del reloj.

Para la rotación alrededor del eje $z$, podemos notar que se trata de la misma matriz que en las transformaciones en 2D, al simplemente extenderla para la coordenada $z$. Pues las coordenadas $x$ y $y$ cambian, mientras que $z$ permanece igual

$$ \mathbf{R}(\phi,z) = \begin{bmatrix} \cos \phi & - \sin \phi & 0 & 0 \\ \sin \phi & \cos \phi & 0 & 0 \\ 0 & 0 & 1 & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} $$

De manera similar, podemos construir las matrices de rotación alrededor de los ejes $x$ y $y$ descritas a continuación. Podemos pensarlo como si miráramos a lo largo de la mitad positiva del eje de interés con éste en el origen, como se muestra en la .

Rotación sobre un eje 3D. El ojo mira a la mitad positiva del eje de interés.

Por lo que, para la rotación alrededor del eje $y$ $$z' = z \cos \phi - x \sin \phi \quad x' = x \cos \phi + z \sin \phi \quad y' = y $$

$$ \mathbf{R}(\phi,y) = \begin{bmatrix} \cos \phi & 0 & \sin \phi & 0 \\ 0 & 1 & 0 & 0 \\ - \sin \phi & 0 & \cos \phi & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} $$ Finalmente para la rotación con respecto al eje $x$ $$y' = y \cos \phi - z \sin \phi \quad z' = z \cos \phi + y \sin \phi \quad x' = x $$ $$ \mathbf{R}(\phi,x) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos \phi & - \sin \phi & 0 \\ 0 & \sin \phi & \cos \phi & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} $$

Un punto importante es que todas las matrices de transformación que hemos visto hasta ahora son invertibles. Pues podemos deducir de manera intuitiva que la inversa de la transformación de traslación es la traslación misma en dirección contraria. O bien, que la inversa de una matriz de escalamiento está dada por $\mathbf{S}(1/s_x, 1/s_y, 1/s_z)$.

Por último, podemos invertir todas las matrices de rotación al simplemente hacer la rotación en sentido contrario, o aprovechando que son matrices ortogonales, con su transpuesta.

Y ya que podemos definir a una matriz de transformación como una composición de matrices $\mathbf{M} = \mathbf{M}_1, \mathbf{M}_2, \dots, \mathbf{M}_n$, entonces podemos obtener

su inversa como $\mathbf{M}^{-1} = \mathbf{M}^{-1}_n, \dots, \mathbf{M}^{-1}_2, \mathbf{M}^{-1}_1$, es decir, multiplicando sus matrices inversas en orden contrario.

Transformaciones 3D. Se aplica la matriz $\mathbf{M} = \mathbf{T}(T_x,T_y) \mathbf{R}(\phi,z) \mathbf{R}(\phi,y) \mathbf{R}(\phi,x) \mathbf{S}(S_x,S_y)$ sobre cada vértice del cubo.

#### Rotación sobre un eje arbitrario.

Digamos que queremos rotar a un vector $\mathbf{v}$ en un ángulo $\theta$ alrededor de un eje arbitrario cuya dirección está dada por un vector unitario $\mathbf{a}$. Para ello, podemos descomponer a $\mathbf{v}$ como la suma de dos vectores $\mathbf{v}_{\parallel}$ y $\mathbf{v}_{\perp}$, siendo el vector paralelo y el vector perpendicular a $\mathbf{a}$ respectivamente, es decir, $\mathbf{v} = \mathbf{v}_{\parallel} + \mathbf{v}_{\perp}$.

De modo que si rotamos a ambos vectors alrededor de $\mathbf{a}$ podemos obtener $\mathbf{v}'$ nuevamente como $\mathbf{v}' = \mathbf{v}_{\parallel}' + \mathbf{v}_{\perp}'$. Y como $\mathbf{v}_{\parallel}$ no cambia durante la rotación, entonces $\mathbf{v}_{\parallel}' = \mathbf{v}_{\parallel}$, reduciendo el problema a encontrar solo a $\mathbf{v}_{\perp}'$.

Como $\mathbf{v}_{\parallel}$ es la proyección de $\mathbf{v}$ sobre $\mathbf{a}$, y además $\mathbf{a}$ es un vector unitario tenemos que $$ \mathbf{v}_{\parallel} = (\mathbf{v} \cdot \mathbf{a}) \mathbf{a}$$

Por otra parte, como $\mathbf{v} = \mathbf{v}_{\parallel} + \mathbf{v}_{\perp}$ entonces podemos calcular al vector perpendicular como $$ \mathbf{v}_{\perp} = \mathbf{v} - (\mathbf{v} \cdot \mathbf{a}) \mathbf{a}$$

Ahora solo hace falta rotar a $\mathbf{v}_{\perp}$ sobre $\mathbf{a}$ para obtener a $\mathbf{v}'$. Notemos que $\mathbf{v}'$ se encuentra sobre el plano perpendicular al eje $\mathbf{a}$, por lo que podemos expresarlo como una combinación lineal de $\mathbf{v}_{\perp}$ y el vector obtenido de rotar $90\degree$ a $\mathbf{v}_{\perp}$ sobre $\mathbf{a}$, el cual podemos obtener fácilmente con $(\mathbf{a} \times \mathbf{v}_{\perp})$. Pudiendo así obtener a $\mathbf{v}_{\perp}'$ como la combinación lineal de estos dos vectores base $$\mathbf{v}_{\perp}' = \cos\theta \mathbf{v}_{\perp} + \sin\theta (\mathbf{a} \times \mathbf{v}_{\perp})$$

Rotación sobre un eje arbitrario. Se invita al lector a modificar el valor del ángulo de rotación $\mathbf{\theta}$, así como cambiar la posición de la cámara.

$ \begin{aligned} \text{Y como} \kern{1em} \mathbf{a} \times \mathbf{v}_{\perp} &= \, \mathbf{a} \times (\mathbf{v} - \mathbf{v}_{\parallel}) = \mathbf{a} \times \mathbf{v} - \mathbf{a} \times \mathbf{v}_{\parallel} \\ &= \mathbf{a} \times \mathbf{v} - \mathbf{0} = \mathbf{a} \times \mathbf{v} \end{aligned} $

Entonces podemos obtener al vector rotado $\mathbf{v}'$ como la suma $$\begin{aligned} \mathbf{v}' &= (\mathbf{v} \cdot \mathbf{a}) \mathbf{a} + \cos\theta (\mathbf{v} - (\mathbf{a} \cdot \mathbf{v}) \mathbf{a}) + \sin\theta (\mathbf{a} \times \mathbf{v})\\ &= (1 - \cos\theta) (\mathbf{v} \cdot \mathbf{a}) \mathbf{a} + \cos\theta \mathbf{v} + \sin\theta (\mathbf{a} \times \mathbf{v}) \kern{.7em} \end{aligned} $$ Los vectores se muestran en la .

Para construir la matriz de transformación, llamémosla $\mathbf{R}(\theta,\mathbf{a})$, empezamos por obtener las matrices equivalentes de los vectores en la ecuación de $\mathbf{v}'$ $$ (\mathbf{v} \cdot \mathbf{a}) \mathbf{v} = (p_{x}a_{x} + p_{y}a_{y} + p_{x}a_{y}) \begin{bmatrix} a_{x} \\ a_{y} \\ a_{z} \end{bmatrix} = \begin{bmatrix} a_{x}^2 & a_{x}a_{y} & a_{x}a_{z} \\ a_{x}a_{y} & a_{y}^2 & a_{y}a_{z} \\ a_{x}a_{z} & a_{y}a_{z} & a_{z}^2\\ \end{bmatrix} \begin{bmatrix} p_{x} \\ p_{y} \\ p_{z} \end{bmatrix} $$

$$ (\mathbf{a} \times \mathbf{v}) = \begin{bmatrix} a_{y}p_{z} - a_{z}p_{y} \\ a_{z}p_{x} - a_{x}p_{z} \\ a_{x}p_{y} - a_{y}p_{x} \end{bmatrix} = \begin{bmatrix} 0 & -a_{z} & a_{y} \\ a_{z} & 0 & -a_{x} \\ -a_{y} & a_{x} & 0 \end{bmatrix} \begin{bmatrix} p_{x} \\ p_{y} \\ p_{z} \end{bmatrix} $$

Por último, sustituimos las matrices en la ecuación. Sea $s = \sin\theta$ y $c = \cos\theta$ $$ \mathbf{v}' = (1 - \cos\theta) (\mathbf{v} \cdot \mathbf{a}) \mathbf{a} + \cos\theta \mathbf{v} + \sin\theta (\mathbf{a} \times \mathbf{v}) \kern{3em} $$

$$ = (1 - c) \begin{bmatrix} a_{x}^2 & a_{x}a_{y} & a_{x}a_{z} \\ a_{x}a_{y} & a_{y}^2 & a_{y}a_{z} \\ a_{x}a_{z} & a_{y}a_{z} & a_{z}^2\\ \end{bmatrix} \begin{bmatrix} p_{x} \\ p_{y} \\ p_{z} \end{bmatrix} + c \begin{bmatrix} p_{x} \\ p_{y} \\ p_{z} \end{bmatrix} + s \begin{bmatrix} 0 & -a_{z} & a_{y} \\ a_{z} & 0 & -a_{x} \\ -a_{y} & a_{x} & 0 \end{bmatrix} \begin{bmatrix} p_{x} \\ p_{y} \\ p_{z} \end{bmatrix} $$ $$ = \begin{bmatrix} (1 - c) \begin{bmatrix} a_{x}^2 & a_{x}a_{y} & a_{x}a_{z} \\ a_{x}a_{y} & a_{y}^2 & a_{y}a_{z} \\ a_{x}a_{z} & a_{y}a_{z} & a_{z}^2\\ \end{bmatrix} + c \begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix} + s \begin{bmatrix} 0 & -a_{z} & a_{y} \\ a_{z} & 0 & -a_{x} \\ -a_{y} & a_{x} & 0 \end{bmatrix} \end{bmatrix} \begin{bmatrix} p_{x} \\ p_{y} \\ p_{z} \end{bmatrix} $$

Finalmente $$ \mathbf{R}(\theta,\mathbf{a}) = \begin{bmatrix} (1 - c)a_{x}^2 + c & (1 - c)a_{x}a_{y} - sa_{z} & (1 - c)a_{x}a_{z} + sa_{y} & 0\\ (1 - c)a_{x}a_{y} + sa_{z} & (1 - c)a_{y}^2 + c & (1 - c)a_{y}a_{z} - sa_{x} & 0\\ (1 - c)a_{x}a_{z} - sa_{y} & (1 - c)a_{y}a_{z} + sa_{x} & (1 - c)a_{z}^2 + c & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} $$

## Transformación de la normal

Un vector es un vector normal si es perpendicular al plano tangente de una superficie, en particular, a los vectores que sean tangentes a la superficie.

Cuando transformamos un objeto con una matriz $\mathbf{M}$, necesitamos transformar no solo sus posiciones si no también sus vectores normales.

Por un lado, los vectores tangentes pueden ser calculados tomando la diferencia entre los vértices que conforman la superficie, entonces, también podríamos obtener los nuevos vectores tangentes transformados como la diferencia de los nuevos vértices transformados. Por lo que la misma matriz $\mathbf{M}$, puede usarse para obtener los nuevos vectores tangentes correctamente.

Pero para los vectores normales no es tan simple, ya que si usamos una matriz no ortogonal la normal transformada puede terminar apuntando a una dirección que no es perpendicular a la nueva superficie transformada (Ver ).

Ejemplo de la transformación de la normal. La pirámide de la izquierda (verde) muestra lo que ocurre cuando se usa una matriz no ortogonal para transformar al vector normal, el cual termina apuntando en una dirección que ya no es perpendicular a la superficie transformada, mientras que la pirámide de la derecha (amarilla) muestra cómo debería permanecer dicha normal, es decir, siempre perpendicular a la superficie. También podemos observar que el sombreado resulta afectado por la normal, en especial sobre los picos de las pirámides.

Ahora bien, como el vector tangente $\mathbf{t}$ y el vector normal $\mathbf{n}$ deben ser perpendiculares se satisface que su producto punto es cero, lo cual puede expresarse como el producto de dos matrices $\mathbf{n} \cdot \mathbf{t} = \mathbf{n}^T \mathbf{t} = 0$.

Por lo que necesitamos que esta misma ecuación se siga cumpliendo para el vector tangente transformado $\mathbf{t}'$ y la normal transformada $\mathbf{n}'$.

Sabemos que $\mathbf{t}' = \mathbf{M}\mathbf{t}$, entonces necesitamos encontrar una matriz $\mathbf{N}$ tal que $$ \mathbf{n}'^{T} \mathbf{t}'= (\mathbf{Nn})^T (\mathbf{Mt}) = 0$$

Si desarrollamos un poco más tenemos que $$(\mathbf{Nn})^T (\mathbf{Mt}) = \mathbf{n}^T \mathbf{N}^T \mathbf{M} \mathbf{t}$$

Por otro lado, como sabemos que $\mathbf{n}^T \mathbf{t} = 0$, entonces podemos agregar a la matriz identidad dentro del producto punto y tomar ventaja de que $\mathbf{I} = \mathbf{M^{-1}M}$ $$ \mathbf{n}^{T} \mathbf{t}= \mathbf{n}^T \mathbf{I} \mathbf{t} = \mathbf{n}^T \mathbf{M^{-1}M} \mathbf{t} = 0$$ Así pues, es claro ver que la ecuación para los vectores transformados solo se satisface sí $\mathbf{N}^T \mathbf{M} = \mathbf{I}$, por consiguiente $\mathbf{N} = (\mathbf{M}^{-1})^{T}$, es decir, los vectores normales pueden ser correctamente transformados con la transpuesta de la inversa de la matriz que se use para transformar los puntos.

Nótese que si la matriz de transformación es ortogonal entonces $(\mathbf{M}^{-1})^{T} = (\mathbf{M}^{T})^{T} = \mathbf{M}$.

## Referencias bibliográficas

W3schools. https://www.w3schools.com/ Htmlcolorcodes. https://htmlcolorcodes.com/es/ WebGL2 2D Translation. s.f. WebGL2Fundamentals. https://webgl2fundamentals.org/webgl/lessons/webgl-2d-translation.html Tavares, Gregg. TWGL: A Tiny WebGL helper Library. https://twgljs.org/docs/ Tavares, Gregg. TWGL: A Tiny WebGL helper Library. Github. https://github.com/greggman/twgl.js/ WebGL2 Shaders and GLSL. s.f. WebGL2Fundamentals. https://webgl2fundamentals.org/webgl/lessons/webgl-shaders-and-glsl.html WebGL2 - Less Code, More Fun. s.f. WebGL2Fundamentals. https://webgl2fundamentals.org/webgl/lessons/webgl-less-code-more-fun.html
WebGL2 - Animation. s.f. WebGL2Fundamentals. https://webgl2fundamentals.org/webgl/lessons/webgl-animation.html WebGL2 2D Matrices. s.f. WebGL2Fundamentals. https://webgl2fundamentals.org/webgl/lessons/webgl-2d-matrices.html WebGL2 Multiple Views, Multiple Canvases. s.f. WebGL2Fundamentals. https://webgl2fundamentals.org/webgl/lessons/webgl-multiple-views.html Variable scope, closure. JAVASCRIPT.INFO. Recuperado 8 de Agosto del 2020 de https://javascript.info/closure WebGL2 - Drawing Multiple Things. s.f. WebGL2Fundamentals. https://webgl2fundamentals.org/webgl/lessons/webgl-drawing-multiple-things.html Ferdinandi, Chris. Debouncing events with requestAnimationFrame() for better performance. GoMakeThings. 11 de Octubre del 2017. https://gomakethings.com/debouncing-events-with-requestanimationframe-for-better-performance/ Ho Ahn, Song. 2005-2018. OpenGL Rotation About Arbitrary Axis. Songho.ca. http://www.songho.ca/opengl/gl_rotate.html Belousov, Boris. 31 de Mayo del 2016. Change of basis vs linear transformation. Boris Belousov. http://boris-belousov.net/2016/05/31/change-of-basis/ BananaCoding. 4 de Abril del 2019. JavaScript + CSS Range Slider | Costum Value Range Slider Webdesign Tutorial. [Archivo de Vídeo]. Youtube. https://youtu.be/BrpiNUf2XCk/