2009-10-01 12 views

risposta

5

Prendere l'asin() o acos() del membro affine be c.

struct CGAffineTransform { 
    CGFloat a; 
    CGFloat b; 
    CGFloat c; 
    CGFloat d; 
    CGFloat tx; 
    CGFloat ty; 
}; 
+4

La matematica dietro questo è spiegato nella "matematica dietro le matrici" Sottosezione della Guida alla programmazione Quartz 2D: http: // developer.apple.com/mac/library/DOCUMENTATION/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_affine/dq_affine.html#//apple_ref/doc/uid/TP30001066-CH204-CJBECIAD –

+2

asin e acos non è corretto quando c'è scala. la formula corretta è: CGFloat radians = atan2f (self.view.transform.b, self.view.transform.a); gradi CGFloat = radianti * (180/M_PI); – lbsweek

0

È possibile provare a utilizzare le funzioni acos() e asin() per invertire ciò che fa CGAffineTransformMakeRotation. Tuttavia, dal momento che la matrice di trasformazione Scala si moltiplica, potrebbe essere un po 'difficile farlo.

0

Ho in passato utilizzata la classe XAffineTransform dal GeoTools toolkit per estrarre la rotazione da una matrice affine. Funziona anche quando è stato applicato ridimensionamento e tosatura.

È una libreria Java, ma dovresti essere in grado di convertirlo facilmente in (Objective-) C. Puoi guardare the source for XAffineTransform here. (Il metodo è chiamato getRotation.) E puoi read the API here.

questo è il cuore del metodo:

final double scaleX = getScaleX0(tr); 
final double scaleY = getScaleY0(tr) * flip; 
return Math.atan2(tr.getShearY()/scaleY - tr.getShearX()/scaleX, 
        tr.getScaleY()/scaleY + tr.getScaleX()/scaleX); 

Avresti bisogno di implementare anche le/getShear metodi getScale. Non è affatto difficile. (Per la maggior parte si può solo copiare il codice Java come è.)

5
atan2(rotationTransform.b, rotationTransform.d) 

Il (b) soluzione acos suggerita da qualcuno è valido solo nel range +/- 0.5pi. Questa soluzione sembra robusta in combinazioni di rotazione, traslazione e ridimensionamento, anche se quasi certamente non si tagliano. La mia risposta precedente (atan2(rotationTransform.b, rotationTransform.a) non era valida per il ridimensionamento.

This duplicate was the basis for my original answer.

+2

Penso che dovrebbe essere 'atan2 (rotationTransform.b, rotationTransform.d)' –

+0

Luiz - Sono entrambi uguali e corretti sotto combinazioni di traslazione e rotazione ma anche il tuo sembra rimanere corretto quando viene aggiunto il ridimensionamento, quindi vado per aggiornarlo. Grazie. –

+0

utilizzando transform.b, transform.d ha salvato il giorno! Grazie! – srik

0

asin e acos non è corretto quando c'è scala.

la formula corretta è:

CGFloat radians = atan2f(self.view.transform.b, self.view.transform.a); 
CGFloat degrees = radians * (180/M_PI); 

o:

CGFloat angle = [(NSNumber *)[view valueForKeyPath:@"layer.transform.rotation.z"] floatValue]; 
Problemi correlati