简体   繁体   中英

Get just the rotation from a CGAffineTransform

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!

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;
};
atan2(rotationTransform.b, rotationTransform.d)

The acos(b) solution suggested by someone is only valid in the range +/-0.5pi. This solution seems robust under combinations of rotation, translation and scaling although almost certainly not shear. My earlier answer ( atan2(rotationTransform.b, rotationTransform.a ) was not robust to scaling.

This duplicate was the basis for my original answer .

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.

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

asin and acos is not correct when there is scale.

the correct formula is:

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

or:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM