views:

604

answers:

3

Hi,

Is it possible to get just the angle of rotation from a CGAffineTransform that also has translation and scaling values? If yes, how?

Thanks in advance!

A: 

You can try using the acos() and asin() functions to reverse what CGAffineTransformMakeRotation does. However, since you've got the Scale transform matrix multiplied in there, it might be a bit difficult to do that.

Dave DeLong
+2  A: 

Take the asin() or acos() of the affine member b or c.

struct CGAffineTransform {
   CGFloat a;
   CGFloat b;
   CGFloat c;
   CGFloat d;
   CGFloat tx;
   CGFloat ty;
};
zaph
The math behind this is explained in the "Math Behind the Matrices" subsection of the Quartz 2D Programming Guide: http://developer.apple.com/mac/library/DOCUMENTATION/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_affine/dq_affine.html#//apple_ref/doc/uid/TP30001066-CH204-CJBECIAD
Brad Larson
A: 

I have in the past used the XAffineTransform class from the GeoTools toolkit to extract the rotation from an affine matrix. It works even when scaling and shearing has been applied.

It's a Java library, but you should be able to easily convert it to (Objective-)C. You can look at the source for XAffineTransform here. (The method is called getRotation.) And you can read the API here.

This is the heart of the method:

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

You'd need to also implement the getScale/getShear methods. Not hard at all. (For the most part you can just copy the Java code as is.)

Felixyz