¿Es posible obtener solo el ángulo de rotación de un CGAffineTransform que también tiene valores de conversión y escalado? Si es así, ¿cómo?Obtener solo la rotación de un CGAffineTransform
¡Gracias de antemano!
¿Es posible obtener solo el ángulo de rotación de un CGAffineTransform que también tiene valores de conversión y escalado? Si es así, ¿cómo?Obtener solo la rotación de un CGAffineTransform
¡Gracias de antemano!
Tome el asin() o acos() del miembro afín byc.
struct CGAffineTransform {
CGFloat a;
CGFloat b;
CGFloat c;
CGFloat d;
CGFloat tx;
CGFloat ty;
};
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.
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.)
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.
Creo que debería ser 'atan2 (rotationTransform.b, rotationTransform.d)' –
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. –
usando transform.b, transform.d ¡salvó el día! ¡Gracias! – srik
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];
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 –
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