Saltar al contenido

Encontrar la matriz de transformación a partir de 4 puntos proyectados (con Javascript)

Si encuentras algún detalle que no comprendes nos puedes dejar un comentario y trataremos de ayudarte rápidamente.

Solución:

Calcular una transformación proyectiva

Una transformación proyectiva del plano (proyectivo) se define de forma única por cuatro puntos proyectados, a menos que tres de ellos sean colineales. Así es como puede obtener el $ 3 veces 3 $ matriz de transformación de la transformación proyectiva.

Paso 1: Comenzando con las 4 posiciones en la imagen de origen, llamadas $ (x_1, y_1) $ mediante $ (x_4, y_4) $, resuelves el siguiente sistema de ecuaciones lineales:

$$ begin pmatrix x_1 & x_2 & x_3 \ y_1 & y_2 & y_3 \ 1 & 1 & 1 end pmatrix cdot begin pmatrix lambda \ mu \ tau end pmatrix = begin pmatrix x_4 \ y_4 \ 1 end pmatrix $$

Las columnas forman coordenadas homogéneas: una dimensión más, creada agregando un $ 1 $ como última entrada. En los pasos siguientes, se utilizarán múltiplos de estos vectores para denotar los mismos puntos. Consulte el último paso para ver un ejemplo de cómo convertirlos nuevamente en coordenadas bidimensionales.

Paso 2: Escale las columnas según los coeficientes que acaba de calcular:

$$ A = left ( begin array lll lambda cdot x_1 & mu cdot x_2 & tau cdot x_3 \ lambda cdot y_1 & mu cdot y_2 & tau cdot y_3 \ lambda & mu & tau finarray derecha) $$

Esta matriz mapeará $ (1,0,0) $ a un múltiplo de $ (x_1, y_1,1) $, $ (0,1,0) $ a un múltiplo de $ (x_2, y_2,1) $, $ (0,0,1) $ a un múltiplo de $ (x_3, y_3,1) $ y $ (1,1,1) $ para $ (x_4, y_4,1) $. Entonces mapeará estos cuatro vectores especiales (llamados vectores de base en explicaciones posteriores) a las posiciones especificadas en la imagen.

Paso 3: Repita los pasos 1 y 2 para las posiciones correspondientes en la imagen de destino, para obtener una segunda matriz denominada $ B $.

Este es un mapa desde los vectores base hasta las posiciones de destino.

Paso 4: Invertir $ A $ para obtener $ A ^ – 1 $ (o use el adyuvante como se describe a continuación).

$ A $ mapea desde los vectores base a las posiciones de la fuente, por lo que la matriz inversa mapea en la dirección inversa.

Paso 5: Calcule la matriz combinada $ C = B cdot A ^ – 1 $.

$ A ^ – 1 $ mapas de las posiciones de origen a los vectores base, mientras que $ B $ mapas desde allí hasta las posiciones de destino. Por lo tanto, la combinación asigna las posiciones de origen a las posiciones de destino. Esta es la matriz de la transformación que solicitaba.

Paso 6: Para mapear una ubicación $ (x, y) $ desde la imagen de origen a su ubicación correspondiente en la imagen de destino, calcule el producto

$$ begin pmatrix x ‘\ y’ \ z ‘ end pmatrix = C cdot begin pmatrix x \ y \ 1 end pmatrix $$

Estas son las coordenadas homogéneas de su punto transformado.

Paso 7: Calcule la posición en la imagen de destino de esta manera:

begin align * x ” & = frac x ‘ z’ \ y ” & = frac y ‘ z’ end align *

Se llama deshomogeneización del vector de coordenadas.

Cómo utilizar esta transformación proyectiva con CSS

En general, tal transformación no Sea una transformación afín, por lo que no puede expresar esto en términos de transformaciones afines como escalar, rotar y esquilar, ya que no pueden expresar la perspectiva. Sin embargo, puede intentar simplemente establecer las dos primeras entradas de la última fila en cero, de modo que obtenga una transformación afín que podría estar lo suficientemente cerca de su transformación deseada.

Si por otro lado puedes usar un matrix3d transformación, entonces puede tomar la matriz de transformación proyectiva 2D $ C $ calculado como se describe arriba, y use sus entradas para construir una matriz de transformación proyectiva 3D como esta:

$$ begin pmatrix C_ 1,1 & C_ 1,2 & 0 & C_ 1,3 \ C_ 2,1 & C_ 2,2 & 0 & C_ 2 , 3 \ 0 & 0 & 1 & 0 \ C_ 3,1 & C_ 3,2 & 0 & C_ 3,3 end pmatrix $$

Esta transformación transformará $ x $ y $ y $ coordinar como arriba, pero dejar el $ z $ coordenadas de los vectores de coordenadas homogéneos solamente. La deshomogeneización aún podría cambiar el valor de la $ z $ coordinar en el espacio, pero como en realidad no te importan, esto debería ser lo suficientemente bueno.

Escribí una implementación de prueba de concepto. La interfaz de usuario es bastante burda, pero las matemáticas funcionan bastante bien. La implementación usa la matriz adjunta en lugar de la inversa, tanto para resolver las ecuaciones lineales en el paso 1 como para la transformada inversa en el paso 4. El resultado difiere solo por un factor escalar, que es irrelevante para las coordenadas homogéneas. El beneficio es que esto evita calcular un montón de determinantes y realizar un montón de divisiones.

Si quisiera, podría jugar el mismo juego por cinco puntos en el espacio 3D, para calcular la matriz de transformación proyectiva espacial completa. Pero eso solo tiene sentido si realmente tiene profundidad, ya que no cuatro de los cinco puntos pueden ser coplanares.

Estoy bastante seguro de que no existe una solución general de forma cerrada para este problema, lo que te deja con aproximaciones numéricas. Una técnica simplificadora sería eliminar la perspectiva de su problema e imaginar que los cuatro puntos que dibujan sus visitantes son la sombra proyectada por una luz que brilla desde el infinito. Luego, básicamente, podría adivinar y verificar, utilizando conjeturas de la sofisticación que desee.

Escribí una demostración muy aproximada de lo que estoy hablando que contiene algunas suposiciones poco sofisticadas. Debido a que elimina la perspectiva, no resuelve con precisión su pregunta, pero vea si los resultados pueden ser satisfactorios.

El usuario ingresa cuatro puntos en un lienzo HTML con su mouse. Luego, el script intenta converger iterativamente en una transformación CSS de un cuadrado para que coincida con la forma.

Me he vinculado a una salida de muestra. A la izquierda, el cuadrilátero amarillo es el dibujo original a mano, los grises son las aproximaciones sucesivas y el rojo es la estimación final. A la derecha, verá un div cuadrado con el estilo de la transformación CSS.

Captura de pantalla de salida del script

Una actualización obvia sería una mejor función de convergencia, tal vez usando el método de Newton o algo similar, pero no me he tomado el tiempo para averiguar las ecuaciones diferenciales parciales que esto requeriría.

(El código se ejecuta en el navegador en Javascript sincrónico y bloquea el navegador en mi computadora durante un promedio de entre 5 y 20 segundos, así que tenga cuidado).

Esta no es mi solución, solo un enlace a lo que, para mí, fue la solución perfecta:

http://franklinta.com/2014/09/08/computing-css-matrix3d-transforms/

De la forma en que está hecho, puede pegar el JS en la página en la que está trabajando y alinear los puntos exactamente como lo desea, luego copiar el CSS del inspector.

Por lo que puedo decir (que es solo superficialmente), esto hace lo mismo que JS Fiddle de MvG, pero está empaquetado de una manera que fue más útil para mí. HTH!

Comentarios y valoraciones del artículo

Si haces scroll puedes encontrar las reseñas de otros creadores, tú también tienes el poder mostrar el tuyo si dominas el tema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *