2009-05-21 4 views

risposta

8

Supponendo, che la trasformata SOLO contiene una rotazione è facile: prendi semplicemente gli aco dell'elemento m11.

Funziona ancora se la trasformazione contiene una traduzione, ma se contiene taglio o ridimensionamento non sei fortunato. Questi possono essere ricostruiti scomponendo la matrice in una matrice di taglio, scala e rotazione, ma i risultati ottenuti non sono molto probabilmente quelli che stai cercando.

+0

+1 per la precisione tecnica. Viene in mente anche la decomposizione SVD della parte di non traduzione (composizione della rotazione, ridimensionamento anisotropico lungo assi x-y e rotazione)) –

8

Il modo più generale, più semplice è di trasformare (0,0) e (1,0), quindi utilizzare le funzioni trigonometriche (arctan) per ottenere l'angolo di

+0

Questo è il modo giusto per farlo. grazie – sharvey

4

Transformation Matrix è un'implementazione utilizzata per la grafica 3D. Semplifica la matematica per accelerare gli orientamenti posizionali/rotazionali di punti/oggetti. È davvero molto difficile tirare fuori l'orientamento dalla Trasformazione a causa del modo in cui accumula le traduzioni/rotazioni/scale successive.

Ecco un suggerimento. Prendi un vettore che punti in una direzione semplice come (1,0,0), quindi applica la Trasformazione su di esso. Il tuo vettore risultante sarà tradotto e ruotato per darti qualcosa del genere: (27.8, 19.2, 77.4). Applica la trasformazione a (0,0,0), per ottenere qualcosa come (26,1, 19,4, 50,8). È possibile utilizzare questi due punti per calcolare le rotazioni che sono state applicate in base alla conoscenza dei loro punti di partenza di (1,0,0).

Questo aiuto?

+1

QTransform esegue trasformazioni 2D usando matrici 3x3. Le trasformazioni 3D con matrici 4x4 sono molto simili, ma la matematica nel caso 2D è un po 'più semplice. Detto questo, tutti tranne Nils sembrano aver dimenticato le trasformazioni di taglio come [[1,1,0], [0,1,0], [0,0,1]], nel qual caso basta premere due punti per non restituire un risultato sufficientemente descrittivo. – ephemient

2

Generalmente è necessaria una funzione trigonometrica inversa, ma è necessario fare attenzione alle ambiguità del quadrante, e questo è ciò che si dovrebbe usare atan2 (talvolta compitato arctan2). Quindi, ruotare un vettore unitario [0, 1] in [x, y] e quindi usare atan2 (y, x), o se la matrice sta solo implementando una rotazione, puoi usare atan2 (m12, m11). (Queste sono simili alle risposte di Javier e Nils, eccetto che non usano atan2)

1

Stavo usando QGraphicsItem con solo setRotate e non avevo alcun tipo di problema, fino a quando non aggiungo una funzionalità di gruppo ruotata. Il problema è che quando viene chiamato destroyItemGroup, applica la rotazione come una trasformazione agli elementi e non come una rotazione. Per questo motivo ho dovuto recuperare la rotazione da questo oggetto QTransform.

La mia difficoltà è stato quello di aggiungere le seguenti righe al metodo itemChange (credito per la risposta di 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'altra soluzione con acos e m11() non ha funzionato. Si blocca per determinati valori, come spiegato da tom10.