2009-05-21 5 views

Antwort

8

Unter der Annahme zu erhalten, dass die Transformation NUR eine Drehung enthält es einfach: Nimm einfach die Acos des Elements m11.

Es funktioniert immer noch, wenn die Transformation eine Übersetzung enthält, aber wenn es Scheren oder Skalierung enthält, haben Sie kein Glück. Diese können rekonstruiert werden, indem die Matrix in eine Scher-, Skalen- und Rotationsmatrix zerlegt wird, aber die Ergebnisse, die Sie erhalten, sind nicht sehr wahrscheinlich, wonach Sie suchen.

+0

+1 für technische genauigkeit. Man denke auch an die SVD-Zerlegung des Nicht-Übersetzungsteils (Zusammensetzung der Drehung, anisotrope Skalierung entlang x-y-Achsen und Rotation)) –

8

Die einfachste allgemeine Art und Weise ist (0,0) und (1,0) zu transformieren, dann trigonometrische Funktionen (arctan) den Winkel

+0

Dies ist der richtige Weg, es zu tun. danke – sharvey

4

Die Transformationsmatrix ist eine Implementierung für 3D-Grafiken. Es vereinfacht die Mathematik, um die 3D-Positions-/Rotationsorientierungen von Punkten/Objekten zu beschleunigen. Es ist in der Tat sehr schwierig, die Orientierung aus der Transformation herauszuziehen, weil sie aufeinanderfolgende Translationen/Rotationen/Skalen anhäuft.

Hier ist ein Vorschlag. Nehmen Sie einen Vektor, der in eine einfache Richtung wie (1,0,0) zeigt, und wenden Sie dann die Transformation darauf an. Ihr resultierender Vektor wird übersetzt und rotiert, um Ihnen etwas Ähnliches zu geben: (27.8, 19.2, 77.4). Wenden Sie die Transformation auf (0,0,0) an, um etwas wie (26.1, 19.4, 50.8) zu bekommen. Sie können diese zwei Punkte verwenden, um die Rotationen zu berechnen, die basierend auf der Kenntnis ihrer Anfangspunkte von (1,0,0) angewendet wurden.

Hilft das?

+1

QTransform führt 2D-Transformationen unter Verwendung von 3x3-Matrizen durch. 3D-Transformationen mit 4x4-Matrizen sind sehr ähnlich, aber die Mathematik im 2D-Fall ist etwas einfacher. Abgesehen davon scheint jeder außer Nils vergessen zu haben, dass sich die Scherumform wie [[1,1,0], [0,1,0], [0,0,1]] verändert, in welchem ​​Fall nur zwei Punkte nicht durchgeschoben werden ein ausreichend beschreibendes Ergebnis liefern. – ephemient

2

Im Allgemeinen benötigen Sie eine inverse Trig-Funktion, aber Sie müssen auf Quadranten-Ambiguitäten achten, und das ist, was Sie atan2 (manchmal buchstabiert arctan2) verwenden sollten. Drehen Sie entweder einen Einheitsvektor [0, 1] zu [x, y] und verwenden Sie dann atan2 (y, x), oder wenn die Matrix nur eine Rotation implementiert, können Sie atan2 (m12, m11) verwenden. (Diese sind Javier und Nils Antworten ähnlich, außer dass sie atan2 nicht verwenden.)

1

Ich verwendete QGraphicsItem mit nur setRotate und hatte keine Art von Problem, bis ich eine Rotationsgruppenfunktionalität hinzufüge. Das Problem besteht darin, dass beim Aufruf von destroyItemGroup die Rotation als Transformation auf die Elemente und nicht als Rotation angewendet wird. Daher musste ich die Rotation von diesem QTransform-Objekt wiederherstellen.

war meine fix die folgenden Zeilen in der itemChange Methode (Kredit tom10 Antwort) hinzuzufügen:

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 .: Die andere Lösung mit acos und m11() funktionierte nicht. Es stürzt bei bestimmten Werten ab, wie von tom10 erklärt.