2009-10-01 7 views

Répondre

5

Prenez l'asin() ou l'acos() du membre affine b ou c.

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

Les mathématiques derrière cela est expliqué dans le "Math derrière les matrices" sous-section du Guide de programmation 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 et acos ne sont pas corrects lorsqu'il y a de l'échelle. la formule correcte est: CGFloat radians = atan2f (self.view.transform.b, self.view.transform.a); CGFloat degrés = radians * (180/M_PI); – lbsweek

0

Vous pouvez essayer d'utiliser les fonctions acos() et asin() pour inverser ce que fait CGAffineTransformMakeRotation. Cependant, puisque vous avez multiplié la matrice de transformation Scale, il pourrait être un peu difficile de le faire.

0

I ont utilisé dans le passé, la classe XAffineTransform de la boîte à outils GeoTools pour extraire la rotation à partir d'une matrice affine. Cela fonctionne même lorsque l'échelle et le cisaillement ont été appliqués.

Il s'agit d'une bibliothèque Java, mais vous devriez pouvoir la convertir facilement en (Objective-) C. Vous pouvez regarder the source for XAffineTransform here. (La méthode s'appelle getRotation.) Et vous pouvez read the API here.

C'est le cœur de la méthode:

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

Vous auriez besoin de mettre en œuvre également les méthodes getScale/getShear. Pas dur du tout. (Pour la plupart, vous pouvez simplement copier le code Java est.)

5
atan2(rotationTransform.b, rotationTransform.d) 

Le ACOS (b) solution proposée par quelqu'un est valable uniquement dans la plage +/- 0.5pi. Cette solution semble robuste sous des combinaisons de rotation, de translation et de mise à l'échelle bien que presque certainement pas de cisaillement. Ma réponse précédente (atan2(rotationTransform.b, rotationTransform.a) n'était pas robuste à la mise à l'échelle.

This duplicate was the basis for my original answer.

+2

Je pense qu'il devrait être 'atan2 (rotationTransform.b, rotationTransform.d)' –

+0

Luiz - Ils sont à la fois les mêmes et corrects sous les combinaisons de translation et de rotation, mais le tien semble aussi rester correct lorsque la mise à l'échelle est ajoutée alors je vais pour le mettre à jour. Je vous remercie. –

+0

en utilisant transform.b, transform.d sauvé le jour! Merci! – srik

0

asin et acos n'est pas correct lorsqu'il y a de l'échelle.

la formule correcte est:

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

ou:

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