2009-02-24 12 views
13

En référence à this programming game Je construis actuellement.WPF: Obtenir de nouvelles coordonnées après une rotation

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

Pour traduire une toile en WPF, j'utilise deux formes: TranslateTransform (pour le déplacer) et RotateTransform (pour le faire pivoter) [enfants du mêmeTransformationGroup]

Je peux facilement obtenir les coordonnées x et y en haut à gauche d'une toile quand elle n'est pas tournée (ou pivotée à 90deg, puisque ce sera la même chose), mais le problème auquel je fais face est le haut gauche (et les 3 autres points) coordonnées.

En effet, lorsqu'un RotateTransform est appliqué, les propriétés de X et YTranslateTransform ne sont pas modifiés (et donc indiquent encore que la partie supérieure gauche de la place est comme le carré en pointillé (de l'image)

la toile est en rotation de son centre, de sorte que est son origine.

alors comment puis-je le « nouveau » coordonnées x et y des 4 points après une rotation?

[UPDATE]

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

Je l'ai trouvé un moyen de trouver le supérieur gauche coordonnées après une rotation (comme vous pouvez le voir dans la nouvelle image) en ajoutant la OffsetX et OffsetY de la rotation aux coordonnées X et Y de départ.

Mais j'ai maintenant du mal à trouver le reste des coordonnées (les 3 autres).

Avec cette forme pivotée, comment puis-je déterminer les coordonnées x et y des 3 coins restants?

[EDIT]

Les points de la 2ème image de NE SONT PAS DES POINTS ET EXACT PRÉCIS. J'ai fait les points avec des estimations dans ma tête.

[UPDATE] Solution:

Tout d'abord, je voudrais remercier Jason S pour ce poste long et très instructif dans lequel il décrit les mathématiques derrière le processus; J'ai certainement beaucoup appris en lisant votre article et en essayant les valeurs.

Mais j'ai trouvé un extrait de code (grâce à la mention de EugeneZ de TransformBounds) qui fait exactement ce que je veux:

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

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

+0

Ici vous pouvez trouver plus facile trouver moyen http://stackoverflow.com/a/22511805/2106820 –

Répondre

13

Si je comprends bien votre question:

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 

Voici les équations pertinentes:

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

Kc=cos(theta) et Ks=sin(theta) et theta est l'angle de rotation anti-horaire. (À vérifier: si theta = 0 Cela laisse les coordonnées inchangé, sinon, si xc = yc = 0, il fait correspondre (1,0) à (cos (thêta), sin (thêta)) et (0,1) à (- . sin (thêta), cos (thêta)) caveat:. c'est pour les systèmes de coordonnées où (x, y) = (1,1) est dans le quadrant supérieur droit pour le vôtre où il est dans le quadrant inférieur droit, thêta serait Si vous connaissez les coordonnées de votre rectangle alignées avec les axes xy, xc serait simplement la moyenne des deux coordonnées x et yc serait simplement la moyenne des valeurs de l'axe XY. deux coordonnées y. (Dans votre situation, il est xc = 75, 85 = YC.)

Si vous connaissez thêta, vous avez maintenant suffisamment d'informations pour calculer les nouvelles coordonnées. Si vous ne connaissez pas thêta, vous pouvez résoudre pour Kc, Ks. Voici les calculs pertinents pour votre exemple:

(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 

qui est un system of linear equations qui peut être résolu (exercice pour le lecteur: dans Matlab il est:

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

Céder, dans ce cas, Kc = 1,027 , Ks = 0,3622 ce qui n'a pas de sens (K = Kc + Ks est supposé être égal à 1 pour une rotation pure, dans ce cas c'est K = 1,089) donc ce n'est pas une rotation pure sur le centre de rectangle, qui est ce que votre dessin indique ates. Il ne semble pas non plus être une rotation pure sur l'origine. Pour vérifier, comparer les distances du centre de rotation avant et après la rotation en utilisant le théorème de Pythagore, d = deltax + deltay . (Pour une rotation autour d'xc = 75, J = 85, la distance avant est 43,01, la distance après est-46,84, le rapport est de K = 1,089; pour une rotation autour de l'origine, la distance avant est 70,71, la distance après est-73,78, le ratio est de 1,043 I. pourrait croire que des rapports de 1,01 ou moins pourraient résulter de l'arrondi des coordonnées aux entiers, mais cela est nettement plus grand qu'une erreur d'arrondi)

Il manque donc quelques informations ici. Comment avez-vous obtenu les chiffres (62,40)?Cependant, c'est l'essentiel de la mathématique des rotations.

edit: aha, je ne savais pas qu'ils étaient des estimations. (assez proche d'être réaliste, cependant!)

+0

J'ai obtenu ces nombres en ajoutant les coordonnées X et Y de départ au OffsetX et au OffsetY récupérés du Matrice de rotation. Ainsi, si le OffsetX est 12, et que X est 50, le nouveau X (après rotation) est 62. Idem pour la coordonnée Y –

+0

Btw, juste pour clarifier: Les points que je mets dans l'image ne sont pas des points réels, et même les décalages ne sont pas réels; Je les ai juste fait pour l'image –

+0

Je pense que les valeurs sont une estimation approximative, il a montré l'illustration comme un exemple. – Drahcir

1

Je ne suis pas sûr , mais est ce que vous cherchez - rotation d'un point dans le système de coordonnées cartésiennes: link

+0

aura un coup d'oeil. Merci. –

1

Vous pouvez n utiliser la méthode Transform.Transform() sur votre point avec les mêmes transformations pour obtenir un nouveau point auquel ces transformations ont été appliquées.

+0

Transform() accepte une variable Point. Quels devraient être les x et y de ce point? –

+0

Gauche et haut de votre toile –

+0

En référence à votre question mise à jour, la méthode Transform() fera exactement ce dont vous avez besoin avec n'importe quel point (y compris les autres coins de votre carré). –

2

Regardez la méthode GeneralTransform.TransformBounds().

6

J'utilise cette méthode:

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

où RotateTransform est l'instance sur laquelle je travaille et mettre l'angle ... etc.