2009-10-01 21 views

Respuesta

5

Tome el asin() o acos() del miembro afín byc.

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

La matemática detrás de esto se explica en la "matemática detrás de las matrices" subsección de la Guía de programación 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 y acos no es correcto cuando hay escala. la fórmula correcta es: CGFloat radianes = atan2f (self.view.transform.b, self.view.transform.a); CGFloat degrees = radianes * (180/M_PI); – lbsweek

0

Puede intentar usar las funciones acos() y asin() para invertir lo que hace CGAffineTransformMakeRotation. Sin embargo, dado que tienes la matriz de transformación Scale multiplicada allí, puede ser un poco difícil hacerlo.

0

I tienen en el pasado utiliza la clase XAffineTransform de la caja de herramientas GeoTools para extraer la rotación de una matriz afín. Funciona incluso cuando se ha aplicado escala y cizallamiento.

Es una biblioteca de Java, pero debería ser capaz de convertirla fácilmente en (Objective-) C. Puede mirar the source for XAffineTransform here. (El método se llama getRotation). Y puede read the API here.

Este es el corazón del método:

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

Se necesitaría implementar también los/getShear métodos getScale. No es difícil en absoluto. (En su mayor parte se puede simplemente copiar el código Java como es.)

5
atan2(rotationTransform.b, rotationTransform.d) 

El (b) Solución acos sugerido por alguien sólo es válida en el rango de +/- 0.5pi. Esta solución parece robusta bajo combinaciones de rotación, traslación y escalado, aunque casi con toda seguridad no es cortante. Mi respuesta anterior (atan2(rotationTransform.b, rotationTransform.a) no era sólida para escalar.

This duplicate was the basis for my original answer.

+2

Creo que debería ser 'atan2 (rotationTransform.b, rotationTransform.d)' –

+0

Luiz - Ambos son iguales y correctos en las combinaciones de traducción y rotación, pero el tuyo también parece seguir siendo correcto cuando se agrega escala, así que voy para actualizarlo Gracias. –

+0

usando transform.b, transform.d ¡salvó el día! ¡Gracias! – srik

0

asin y acos no es correcto cuando hay escala.

la fórmula correcta es:

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]; 
Cuestiones relacionadas