2009-07-11 24 views
11

Hola, estoy tratando de crear la transformada afín que me permita transformar un triángulo en otro. Lo que tengo son las coordenadas para los 2 triángulos. ¿Me puedes ayudar?Transformar un triángulo en otro triángulo

Tras la respuesta de Adam Rosenfield me encontré con este código en caso de que alguien se aburre de resolver la ecuación de sí mismo:

public static AffineTransform createTransform(ThreePointSystem source, 
      ThreePointSystem dest) {   
    double x11 = source.point1.getX(); 
    double x12 = source.point1.getY(); 
    double x21 = source.point2.getX(); 
    double x22 = source.point2.getY(); 
    double x31 = source.point3.getX(); 
    double x32 = source.point3.getY(); 
    double y11 = dest.point1.getX(); 
    double y12 = dest.point1.getY(); 
    double y21 = dest.point2.getX(); 
    double y22 = dest.point2.getY(); 
    double y31 = dest.point3.getX(); 
    double y32 = dest.point3.getY(); 

    double a1 = ((y11-y21)*(x12-x32)-(y11-y31)*(x12-x22))/ 
       ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22)); 
    double a2 = ((y11-y21)*(x11-x31)-(y11-y31)*(x11-x21))/ 
       ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21)); 
    double a3 = y11-a1*x11-a2*x12; 
    double a4 = ((y12-y22)*(x12-x32)-(y12-y32)*(x12-x22))/ 
       ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22)); 
    double a5 = ((y12-y22)*(x11-x31)-(y12-y32)*(x11-x21))/ 
       ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21)); 
    double a6 = y12-a4*x11-a5*x12; 
    return new AffineTransform(a1, a4, a2, a5, a3, a6); 
} 
+0

Entonces, ¿tiene que "mover" el triángulo de manera que las coordenadas coincidan con las segundas coordenadas sin cambiar la apariencia del triángulo? ¿Qué tipo de coordenadas tienes? – Janusz

+0

2 triángulos completamente diferentes (tanto en forma como en ubicación). Ambos residen en el mismo sistema de coordenadas. –

+0

Muy útil, gracias! Solo un recordatorio rápido de que si utiliza el lienzo de Javascript html5, la función context.setTransform() toma las salidas exactas de su función, por lo que esta es una gran herramienta para mapear imágenes de un sistema de coordenadas a otro cuando tiene un triángulo de puntos registrados para cada. – JayCrossler

Respuesta

11

Voy a suponer que estás hablando de 2D aquí. Una matriz de transformación afín tiene 9 valores en que:

 
    | a1 a2 a3 | 
A = | a4 a5 a6 | 
    | a7 a8 a9 | 

Hay 3 de entrada vértices x1, x2, y , que cuando se transformó debe convertirse y1, y2, y3. Sin embargo, dado que estamos trabajando en coordenadas homogéneas, aplicar A a x1 no necesariamente da y1 - da un múltiplo de y1. Por lo tanto, también tenemos los multiplicadores desconocidos k1, k2 y k3, con las ecuaciones:

 
A*x1 = k1*y1 
A*x2 = k2*y2 
A*x3 = k3*y3 

Cada uno de ellos es un vector, por lo que realmente tiene 9 ecuaciones con 12 incógnitas, por lo que la solución va a ser underconstrained. Si requerimos que a7=0, a8=0 y a9=1, la solución será única (esta elección es natural, ya que significa que si el punto de entrada es (x, y, 1), el punto de salida siempre tendrá una coordenada homogénea 1, entonces la transformación resultante es solo una transformación de 2x2 más una traducción).

Por lo tanto, esto reduce las ecuaciones para:

 
a1*x11 + a2*x12 + a3 = k1*y11 
a4*x11 + a5*x12 + a6 = k1*y12 
        1 = k1 
a1*x21 + a2*x22 + a3 = k2*y21 
a4*x21 + a5*x22 + a6 = k2*y22 
        1 = k2 
a1*x31 + a2*x32 + a3 = k3*y31 
a4*x31 + a5*x32 + a6 = k3*y32 
        1 = k3 

Así, k1 = k2 = k3 = 1. El tapar estos en y la conversión a la matriz forman rendimientos:

 
| x11 x12 1 0 0 0 | | a1 | | y11 | 
| x21 x22 1 0 0 0 | | a2 | | y21 | 
| x31 x32 1 0 0 0 | * | a3 | = | y31 | 
| 0 0 0 x11 x12 1 | | a4 | | y12 | 
| 0 0 0 x21 x22 1 | | a5 | | y22 | 
| 0 0 0 x31 x32 1 | | a6 | | y32 | 

la solución de este sistema de 6x6 de ecuaciones le da su matriz de transformación afín A. Tendrá una solución única si y solo si los 3 puntos de tu triángulo fuente no son colineales.

+0

¿No es un sistema 6x6 algo pesado? –

+2

Dado que la pregunta especificada "transformación afín" no implica que [a7, a8, a9] == [0, 0, 1]? Sé que ese es el resultado con el que terminaste, parece que pasaste por algunas contorsiones innecesarias para llegar allí. El multiplicador k también parecía demasiado general. –

1

Si entiendo esto correctamente, los triángulos tienen el mismo tamaño y ángulos, por lo deberías poder transformarlos para que tengan (al menos) un punto en común. Después de esto, solo deberían diferir en la rotación o podrían duplicarse, por lo que podría obtener los ángulos entre las líneas del triángulo y probar estos para la rotación y podría reflejar uno de los triángulos si ninguno de los ángulos funciona.

EDITAR: OK, eso no es suficiente, las transformaciones afines también pueden contener cortante y escalado ... El escalado se puede hacer fácilmente, solo divida la longitud de las líneas, esto también le dará información acerca de las líneas correspondientes de los triángulos , pero esquilando será más difícil ...

OTOH, ¿no podrías resolver un sistema de ecuaciones para esto? Después de todo, debe haber una matriz de transformación y 3 puntos (nuevos y viejos) ...

+0

No. Quiero duplicar 1 triángulo a uno completamente diferente (el mismo sistema de coordenadas) –

1

Sólo Formule el problema como un conjunto de ecuaciones y luego resolverlo:

P1 * M = P1' 
P2 * M = P2' 
P3 * M = P3' 

M es una matriz 3x3 como:

[m00, m01, m02; 
m10, m11, m12; 
0 , 0, 1] 

Y P_i es una tupla [k*x_i, k*y_i, k] (coordenadas homogéneas) ...

ahora puede tratar t o expande las 3 ecuaciones matriciales que se muestran arriba y crea un nuevo sistema, con el m_ij como incógnitas y resuélvelo, pero si no me falta algo (y tal vez lo estoy), necesitas un punto más para especificar completamente la transformación, o de lo contrario, tendrá un grado extra de libertad (y, por supuesto, puede solucionarlo).

2

Hola, chicos, sin pérdida de generalidad, hacer que los dos triángulos tengan el origen como un vértice (puede virar en el turno afín después), por lo que están definidos por los puntos 0, a, b, c , d luego multiplicar sus puntos x por la matriz NM

donde

M = inversa (ab) < --- esto es matriz 2x2 con los puntos un y b como su columna s

y

N = (c d)

Eso debería hacerlo.

Cuestiones relacionadas