2009-02-24 13 views
13

Con referencia a this programming game Estoy construyendo.WPF: Conseguir nuevas coordenadas después de una rotación

alt text http://img12.imageshack.us/img12/2089/shapetransformationf.jpg

Para traducir un lienzo en WPF, estoy usando dos formas: TranslateTransform (para moverlo), y RotateTransform (rotarlo) [niños de la mismaTransformationGroup]

puedo conseguir fácilmente los mejores x izquierdo, y coordenadas de una lona cuando no es girado (o gira a 90 grados, ya que será el mismo), pero el problema que estoy enfrentando es conseguir la parte superior izquierda (y los otros 3 puntos) coordenadas

Esto es porque cuando se aplica una RotateTransform, la TranslateTransform 's X y Y propiedades no se cambian (y por lo tanto todavía indican que la parte superior izquierda del cuadrado es igual que el de puntos cuadrados (de la imagen)

el lienzo se gira desde su centro, de modo que sea su origen.

así cómo puedo obtener la "nueva" coordenadas X e y de los 4 puntos después de una rotación?

[ACTUALIZACIÓN]

alt text http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg

he encontrado una manera de encontrar el parte superior izquierda coordenadas después de una rotación (como se puede ver en la nueva imagen), añadiendo la OffsetX y OffsetY de la rotación a las coordenadas iniciales X e Y.

Pero ahora estoy teniendo problemas para averiguar el resto de las coordenadas (los otros 3).

Con esta forma de girar, cómo puedo averiguar las coordenadas X e Y de las 3 esquinas restantes?

[editar]

Los puntos en la segunda imagen no son puntos precisión y exactitud. Hice los puntos con estimaciones en mi cabeza.

[ACTUALIZACIÓN] Solución:

En primer lugar, me gustaría dar las gracias a Jason S para ese puesto larga y muy informativo en el que describe las matemáticas detrás de todo el proceso; Ciertamente aprendí mucho leyendo tu publicación y probando los valores.

Pero ahora he encontrado un fragmento de código (gracias a EugeneZ 's mención TransformBounds) que hace exactamente lo que quiero:

public Rect GetBounds(FrameworkElement of, FrameworkElement from) 
{ 
    // Might throw an exception if of and from are not in the same visual tree 
    GeneralTransform transform = of.TransformToVisual(from); 

    return transform.TransformBounds(new Rect(0, 0, of.ActualWidth, of.ActualHeight)); 
} 

Referencia: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/86350f19-6457-470e-bde9-66e8970f7059/

+0

Aquí puede encontrar más fácil encontrar el camino http://stackoverflow.com/a/22511805/2106820 –

Respuesta

13

Si entiendo su pregunta correcta:

given: 
shape has corner (x1,y1), center (xc,yc) 
rotated shape has corner (x1',y1') after being rotated about center 

desired: 
how to map any point of the shape (x,y) -> (x',y') by that same rotation 

He aquí las ecuaciones relevantes:

(x'-xc) = Kc*(x-xc) - Ks*(y-yc) 
(y'-yc) = Ks*(x-xc) + Kc*(y-yc) 

donde Kc=cos(theta) y Ks=sin(theta) y theta es el ángulo de rotación en sentido antihorario. (para verificar: si theta = 0 esto deja las coordenadas sin cambios, de lo contrario si xc = yc = 0, asigna (1,0) a (cos (theta), sin (theta)) y (0,1) a (- sin (theta), cos (theta)). Advertencia: esto es para sistemas de coordenadas donde (x, y) = (1,1) está en el cuadrante superior derecho. Para el tuyo donde está en el cuadrante inferior derecho, theta sería el ángulo de rotación en el sentido de las agujas del reloj en lugar de la rotación en sentido contrario a las agujas del reloj.)

Si conoce las coordenadas de su rectángulo alineadas con los ejes xy, xc sería simplemente el promedio de las dos coordenadas x y y sería el promedio de la dos coordenadas y (en su caso, es xc = 75, yc = 85)

Si conoce theta, ahora tiene suficiente información para calcular las nuevas coordenadas. Si no conoces theta, puedes resolver Kc, Ks. He aquí los cálculos pertinentes para su ejemplo:

(62-75) = Kc*(50-75) - Ks*(50-85) 
(40-85) = Ks*(50-75) + Kc*(50-85) 

-13 = -25*Kc + 35*Ks = -25*Kc + 35*Ks 
-45 = -25*Ks - 35*Kc = -35*Kc - 25*Ks 

que es un system of linear equations que puede ser resuelto (ejercicio para el lector: en MATLAB es:

[-25 35;-35 -25]\[-13;-45] 

para producir, en este caso, Kc = 1,027 , Ks = 0.3622 que NO tiene sentido (K = Kc + Ks se supone que es igual a 1 para una rotación pura, en este caso es K = 1.089) así que no es una rotación pura del centro rectangular, que es lo que dibuja tu dibujo Ates. Tampoco parece ser una rotación pura sobre el origen. Para verificar, compare las distancias desde el centro de rotación antes y después de la rotación usando el teorema de Pitágoras, d = deltax + deltay . (para la rotación sobre xc = 75, yc = 85, la distancia anterior es 43.01, la distancia después es 46.84, la relación es K = 1.089; para la rotación sobre el origen, la distancia anterior es 70.71, la distancia es 73.78, la relación es 1.043. podría creer que las relaciones de 1.01 o menos surgirían del redondeo de coordenadas a enteros, pero esto es claramente más grande que un error de redondeo)

Aquí falta información. ¿Cómo obtuviste los números (62,40)?

Sin embargo, esa es la esencia básica de las rotaciones matemáticas detrás.

editar: aha, no me di cuenta de que eran estimaciones. (¡bastante cerca de ser realista, sin embargo!)

+0

Obtuve esos números agregando las coordenadas iniciales X e Y a OffsetX y OffsetY recuperada del Matriz de rotación. Por lo tanto, si OffsetX es 12, y X de la forma "no girada" es 50, la nueva X (después de la rotación) es 62. Lo mismo ocurre con la coordenada Y –

+0

Por cierto, para aclarar: Los puntos que puse en la imagen no puntos reales, y ni siquiera los desplazamientos son reales; Acabo de crearlos para la imagen –

+0

Creo que los valores son una estimación aproximada, mostró la ilustración como un ejemplo. – Drahcir

1

No estoy seguro , pero es esto lo que está buscando - rotación de un punto en el sistema de coordenadas cartesianas: link

+0

tendrá una mirada en ella. Gracias. –

1

Usted ca n use el método Transform.Transform() en su punto con las mismas transformaciones para obtener un nuevo punto al que se aplicaron estas transformaciones.

+0

Transform() acepta una variable de punto. ¿Cuál debería ser la xey de ese punto? –

+0

Izquierda y parte superior de su lienzo –

+0

En referencia a su pregunta actualizada, el método Transform() hará exactamente lo que necesita con cualquier punto (incluidas otras esquinas de su cuadrado). –

2

Mire el método GeneralTransform.TransformBounds().

6

que utiliza este método:

Point newPoint = rotateTransform.Transform(new Point(oldX, oldY)); 

donde RotateTransform es la instancia en la que yo trabajo y ajustar el ángulo ... etc.

Cuestiones relacionadas