2009-02-24 3 views
13

Con riferimento a this programming game Attualmente sto costruendo.WPF: ottenere nuove coordinate dopo una rotazione

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

Per tradurre una tela di canapa in WPF, io sto usando due forme: TranslateTransform (per spostarlo) e RotateTransform (per ruotarlo) [figli dello stessoTransformationGroup]

Posso facilmente ottenere le coordinate x, y in alto a sinistra di una tela quando non è ruotata (o ruotata a 90 gradi, poiché sarà la stessa), ma il problema che sto affrontando è quello in alto a sinistra (e gli altri 3 punti) coordinate.

Questo perché quando una RotateTransform viene applicata, s' X e Y proprietà TranslateTransform non vengono modificati (e quindi ancora indicano che in alto a sinistra del quadrato è come il tratteggiata-square (dall'immagine)

la tela è in rotazione dal suo centro, in modo che sia la sua origine.

così come posso ottenere il "nuovo" coordinate xey dei 4 punti dopo una rotazione?

[UPDATE]

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

ho trovato un modo per trovare la in alto a sinistra coordinate dopo una rotazione (come si può vedere dalla nuova immagine) con l'aggiunta del OffsetX e Sfalsamento dalla rotazione alle coordinate iniziali X e Y.

Ma ora sto avendo problemi a capire il resto delle coordinate (gli altri 3).

Con questa forma ruotata, , come è possibile calcolare le coordinate x e y dei restanti 3 angoli?

[EDIT]

I punti nel 2 ° immagine non sono punti accurato e ESATTE. Ho fatto i punti con le stime nella mia testa.

[UPDATE] Soluzione:

Prima di tutto, vorrei ringraziare Jason S per quel post lungo e molto istruttiva in cui descrive la matematica dietro l'intero processo; Ho sicuramente imparato molto leggendo il tuo post e provando i valori.

Ma ora ho trovato un frammento di codice (grazie a EugeneZ s' menzione di TransformBounds) che fa esattamente quello che voglio:

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)); 
} 

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

+0

Qui potete trovare più facile trovare modo http://stackoverflow.com/a/22511805/2106820 –

risposta

13

Se ho capito la tua domanda giusta:

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 

Ecco le equazioni rilevanti:

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

dove Kc=cos(theta) e Ks=sin(theta) e theta è l'angolo di rotazione in senso antiorario. (per verificare: se theta = 0 lascia le coordinate invariate, altrimenti se xc = yc = 0, esegue il mapping (1,0) a (cos (theta), sin (theta)) e (0,1) a (- sin (theta), cos (theta)). Caveat: questo è per i sistemi di coordinate dove (x, y) = (1,1) si trova nel quadrante in alto a destra.Per il tuo dove è nel quadrante in basso a destra, theta sarebbe l'angolo di rotazione in senso orario anziché in senso antiorario.)

Se si conoscono le coordinate del rettangolo allineate con gli assi xy, xc sarebbe solo la media delle due coordinate x e yc sarebbe solo la media del due coordinate y. (nella tua situazione, è xc = 75, yc = 85.)

Se conosci theta, ora hai abbastanza informazioni per calcolare le nuove coordinate. Se non conosci theta, puoi risolvere Kc, Ks. Ecco i calcoli rilevanti per il tuo esempio:

(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 

che è un system of linear equations che può essere risolto (esercizio per il lettore: in MATLAB è:

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

a cedere, in questo caso, Kc = 1.027 , Ks = 0,3622 che NON ha senso (K = Kc + Ks si suppone uguale 1 per una rotazione pura, in questo caso è K = 1.089) quindi non è una rotazione pura sul centro del rettangolo, che è ciò che il tuo disegno indica Ates. Né sembra essere una rotazione pura sull'origine. Per verificare, confrontare le distanze dal centro di rotazione prima e dopo la rotazione utilizzando il teorema di Pitagora, d = deltax + deltay . (per rotazione su xc = 75, yc = 85, la distanza prima è 43.01, la distanza dopo è 46.84, il rapporto è K = 1.089, per la rotazione sull'origine, la distanza prima è 70.71, la distanza dopo è 73.78, il rapporto è 1.043. potrebbe credere che rapporti da 1,01 o meno emergano dall'arrotondamento delle coordinate agli interi, ma questo è chiaramente maggiore di un errore di arrotondamento)

Quindi ci sono alcune informazioni mancanti qui. Come hai ottenuto i numeri (62,40)?

Questo è l'essenza di base della matematica dietro le rotazioni, tuttavia.

modifica: aha, non avevo capito che erano stime. (abbastanza vicino ad essere realistico, però!)

+0

Ho ottenuto quei numeri aggiungendo le coordinate X e Y iniziali a OffsetX e OffsetY recuperate dal Matrice di rotazione. Quindi, se OffsetX è 12, e X della forma "non ruotata" è 50, la nuova X (dopo la rotazione) è 62. Lo stesso vale per la coordinata Y –

+0

Btw, giusto per chiarire: I punti che ho inserito nell'immagine non sono punti reali, e nemmeno gli offset sono reali; Li ho appena inventati per l'immagine –

+0

Penso che i valori siano una stima approssimativa, ha mostrato l'illustrazione come esempio. – Drahcir

1

non sono sicuro , ma questo è quello che stai cercando - rotazione di un punto nel sistema di coordinate cartesiane: link

+0

avrà un aspetto a questo. Grazie. –

1

Si ca n usa il metodo Transform.Transform() sul tuo Punto con le stesse trasformazioni per ottenere un nuovo punto a cui sono state applicate queste trasformazioni.

+0

Transform() accetta una variabile Punto. Quale dovrebbe essere la xey di quel punto? –

+0

Sinistra e parte superiore della tela –

+0

In riferimento alla domanda aggiornata, il metodo Transform() farà esattamente ciò che è necessario con qualsiasi punto (compresi gli altri angoli del quadrato). –

2

Guarda il metodo GeneralTransform.TransformBounds().

6

Io uso questo metodo:

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

dove RotateTransform è l'istanza in cui io lavoro e impostare l'angolo ... ecc.