Representación matricial de transformaciones
Una matriz m×n es un conjunto de números organizados en filas m y n columnas. En la ilustración siguiente se muestran varias matrices.
Puede agregar dos matrices del mismo tamaño agregando elementos individuales. En la ilustración siguiente se muestran dos ejemplos de suma de matrices.
Una matriz m×n se puede multiplicar por una matriz n×p y el resultado es una matriz m×p . El número de columnas de la primera matriz debe ser el mismo que el número de filas de la segunda matriz. Por ejemplo, una matriz de 4 ×2 se puede multiplicar por una matriz de 2 ×3 para generar una matriz de 4 ×3.
Los puntos del plano y las filas y columnas de una matriz pueden considerarse vectores. Por ejemplo, (2, 5) es un vector con dos componentes y (3, 7, 1) es un vector con tres componentes. El producto escalar de dos vectores se define de la siguiente manera:
(a, b) • (c, d) = ac + bd
(a, b, c) • (d, e, f) = ad + be + cf
Por ejemplo, el producto escalar de (2, 3) y (5, 4) es (2)(5) + (3)(4) = 22. El producto escalar de (2, 5, 1) y (4, 3, 1) es (2)(4) + (5)(3) + (1)(1) = 24. Tenga en cuenta que el producto escalar de dos vectores es un número, no otro vector. Tenga en cuenta también que solo puede calcular el producto escalar si los dos vectores tienen el mismo número de componentes.
Deje que A(i, j) sea la entrada de la matriz A en la filai y la columna j. Por ejemplo, A(3, 2) es la entrada de la matriz A en la fila 3rd y lasegunda columna. Supongamos que A, B y C son matrices y que AB = C. Las entradas de C se calculan de la siguiente manera:
C(i, j) = (fila i de A) • (columna j de B)
En la ilustración siguiente se muestran varios ejemplos de multiplicación de matrices.
Si piensa en un punto del plano como una matriz de 1 × 2, puede transformar ese punto multiplicando por una matriz de 2 × 2. En la ilustración siguiente se muestran varias transformaciones aplicadas al punto (2, 1).
Todas las transformaciones que se muestran en la ilustración anterior son transformaciones lineales. Algunas otras transformaciones, como la traducción, no son lineales y no se pueden expresar como multiplicación por una matriz de 2 × 2. Supongamos que quiere empezar con el punto (2, 1), girarlo 90 grados, trasladarlo 3 unidades en la dirección x y trasladarlo 4 unidades en la dirección y. Para ello, realice una multiplicación de matriz seguida de una adición de matriz.
Una transformación lineal (multiplicación por una matriz de 2 × 2) seguida de una traducción (adición de una matriz de 1 × 2) se denomina transformación afín. Una alternativa al almacenamiento de una transformación afín en un par de matrices (una para la parte lineal y otra para la traducción) es almacenar toda la transformación en una matriz de 3 × 3. Para que esto funcione, un punto del plano debe almacenarse en una matriz de 1 × 3 con una coordenada ficticía 3. La técnica habitual es hacer que todas las terceras coordenadas sean iguales a 1. Por ejemplo, el punto (2, 1) se representa mediante la matriz [2 1 1]. En la ilustración siguiente se muestra una transformación afín (girar 90 grados; traducir 3 unidades en dirección x, 4 unidades en la dirección y) expresadas como multiplicación por una sola matriz de 3 × 3.
En el ejemplo anterior, el punto (2, 1) se asigna al punto (2, 6). Tenga en cuenta que la tercera columna de la matriz 3 × 3 contiene los números 0, 0, 1. Esto siempre será el caso de la matriz 3 × 3 de una transformación afín. Los números importantes son los seis números de las columnas 1 y 2. La parte superior izquierda 2 × 2 de la matriz representa la parte lineal de la transformación y las dos primeras entradas de la tercera fila representan la traducción.
En Windows GDI+ puedes almacenar una transformación afín en un objeto Matrix . Dado que la tercera columna de una matriz que representa una transformación afín siempre es (0, 0, 1), solo se especifican los seis números de las dos primeras columnas al construir un objeto Matrix . La instrucción Matrix myMatrix(0.0f, 1.0f, -1.0f, 0.0f, 3.0f, 4.0f);
construye la matriz que se muestra en la ilustración anterior.
Transformaciones compuestas
Una transformación compuesta es una secuencia de transformaciones, una seguida de la otra. Tenga en cuenta las matrices y las transformaciones en la lista siguiente:
- Matriz A Girar 90 grados
- Escala de matriz B por un factor de 2 en la dirección x
- Matrix C Translate 3 unidades en la dirección y
Si comienza con el punto (2, 1) ( representado por la matriz [2 1 1] y multiplicado por A, B, después C, el punto (2,1) se somete a las tres transformaciones en el orden indicado.
[2 1 1] ABC = [ –2 5 1]
En lugar de almacenar las tres partes de la transformación compuesta en tres matrices independientes, puede multiplicar A, B y C juntos para obtener una sola matriz de 3 × 3 que almacena toda la transformación compuesta. Supongamos que ABC = D. Entonces, un punto multiplicado por D da el mismo resultado que un punto multiplicado por A, luego por B y después por C.
[2 1 1] D = [ –2 5 1]
En la ilustración siguiente se muestran las matrices A, B, C y D.
El hecho de que la matriz de una transformación compuesta se pueda formar multiplicando las matrices de transformación individuales significa que cualquier secuencia de transformaciones afín se puede almacenar en un único objeto Matrix .
Nota
El orden de una transformación compuesta es importante. En general, girar, luego escalar y después trasladar no es lo mismo que escalar, luego girar y después trasladar. Del mismo modo, el orden de multiplicación de matriz es importante. En general, ABC no es lo mismo que BAC.
La clase Matrix proporciona varios métodos para crear una transformación compuesta: Matrix::Multiply, Matrix::Rotate, Matrix::RotateAt, Matrix::Scale, Matrix::Shear y Matrix::Translate. En el ejemplo siguiente se crea la matriz de una transformación compuesta que gira primero 30 grados y, a continuación, se escala por un factor de 2 en la dirección y y y, a continuación, se traducen 5 unidades en la dirección x.
Matrix myMatrix;
myMatrix.Rotate(30.0f);
myMatrix.Scale(1.0f, 2.0f, MatrixOrderAppend);
myMatrix.Translate(5.0f, 0.0f, MatrixOrderAppend);
En la siguiente ilustración se muestra la matriz.