2009-05-21 7 views

Répondre

8

En supposant que la transformation SEULEMENT simple façon générale est de transformer (0,0) et (1,0), puis utilisez les fonctions trigonométriques (de arctan) contient une rotation, il est facile: il suffit de prendre l'acos de l'élément m11.

Cela fonctionne toujours si la transformation contient une traduction, mais si elle contient du cisaillement ou de la mise à l'échelle, vous n'avez pas de chance. Ceux-ci peuvent être reconstruits en décomposant la matrice en une matrice de cisaillement, d'échelle et de rotation, mais les résultats que vous obtenez ne sont probablement pas ce que vous recherchez.

+0

+1 pour l'exactitude technique. La décomposition SVD de la partie de non-traduction vient également à l'esprit (composition de la rotation, mise à l'échelle anisotrope le long des axes x-y et rotation)) –

8

Le pour obtenir l'angle

+0

C'est la bonne façon de le faire. merci – sharvey

4

La matrice de transformation est une implémentation utilisée pour les graphiques 3D. Il simplifie les calculs afin d'accélérer les orientations 3D de position/rotation des points/objets. Il est en effet très difficile de sortir l'orientation de la Transformation à cause de la manière dont elle accumule les translations/rotations/échelles successives.

Voici une suggestion. Prenez un vecteur qui pointe dans une direction simple comme (1,0,0), puis appliquez-lui la transformation. Votre vecteur résultant sera traduit et tourné pour vous donner quelque chose comme ceci: (27.8, 19.2, 77.4). Appliquez la transformation à (0,0,0), pour obtenir quelque chose comme (26.1, 19.4, 50.8). Vous pouvez utiliser ces deux points pour calculer les rotations qui ont été appliquées en fonction de leur point de départ de (1,0,0).

Est-ce que cela aide?

+1

QTransform effectue des transformations 2D en utilisant des matrices 3x3. Les transformations 3D avec des matrices 4x4 sont très similaires, mais les maths dans le cas 2D sont un peu plus simples. Cela étant dit, tout le monde sauf Nils semble avoir oublié les transformations de cisaillement comme [[1,1,0], [0,1,0], [0,0,1]], auquel cas il suffit de pousser deux points pour ne pas renvoie un résultat suffisamment descriptif. – ephemient

2

Généralement vous avez besoin d'une fonction de trig inverse, mais vous devez faire attention aux ambiguïtés des quadrants, et c'est ce que vous devriez utiliser atan2 (parfois orthographié arctan2). Donc, soit faire tourner un vecteur unitaire [0, 1] vers [x, y], puis utiliser atan2 (y, x), ou si la matrice ne fait que mettre en œuvre une rotation, vous pouvez utiliser atan2 (m12, m11). (Ils sont similaires aux réponses de Javier et Nils, sauf qu'ils n'utilisent pas atan2.)

1

J'utilisais QGraphicsItem avec juste setRotate et je n'avais aucun problème, jusqu'à ce que j'ajoute une fonctionnalité de groupe de rotation. Le problème est que lorsque destroyItemGroup est appelé, il applique la rotation comme une transformation aux éléments, et non comme une rotation. À cause de cela j'ai dû récupérer la rotation de cet objet QTransform.

Mon solution était d'ajouter les lignes suivantes à la méthode itemChange (crédit à la réponse de tom10):

QVariant MyGraphicItem::itemChange(GraphicsItemChange change, const QVariant &value) 
{ 
    if(change == ItemTransformChange) 
    { 
     auto transform = value.value<QTransform>(); 
     setRotation(rotation() + qRadiansToDegrees(qAtan2(transform.m12(), transform.m11()))); 
     return QVariant(); 
    } 
    ... 
} 

PS .: L'autre solution avec ACOS et M11() ne fonctionnait pas. Il se bloque pour certaines valeurs, comme expliqué par tom10.