Is there a way to figure out, how many degrees an

2019-01-11 08:47发布

问题:

I am applying an rotation transform animation in an animation block with this transform:

CATransform3D rotatedTransform = self.layer.transform;
rotatedTransform = CATransform3DRotate(rotatedTransform, 90 * M_PI / 180.0, 0.0f, 0.0f, 1.0f);
self.layer.transform = rotatedTransform;

The animation begins, and the user kicks in another event that would have to push the rotation towards a new target. To calculate realistic looking behavior, I need to know what's the current degrees of the rotation, so that the next rotation degrees can be added up appropriately.

回答1:

This is an old question but I came across this answer while trying to find the current rotation angle during a key frame animation:-

CALayer* layer = [self.layer presentationLayer];
float currentAngle = [[layer valueForKeyPath:@"transform.rotation.z"] floatValue];

Seems to work for me. Also, nice and concise.



回答2:

You can retrieve the current state of an animating layer by grabbing its presentationLayer. Assuming that you have not applied any other transformations to the layer, you can extract the current angle of the rotating layer using code like the following:

CATransform3D rotationTransform = [(CALayer *)[self.layer presentationLayer] transform];
float angle;
if (rotationTransform.m11 < 0.0f)
    angle = 180.0f - (asin(rotationTransform.m12) * 180.0f / M_PI);
else
    angle = asin(rotationTransform.m12) * 180.0f / M_PI;

In an otherwise unmodified transform, the m11 and m12 values are coordinates that lie on the unit circle, so you can use trigonometry to determine the angle they describe.

EDIT (5/18/2009): Added a typecast to CALayer to overcome compiler warnings and fixed the naming of the transform in the trigonometry operations.



回答3:

You can also calculate it using matrices and trigonometry. Refer to my answer for this question



回答4:

Try this:

CGFloat setAngle = 75.0;
CATransform3D t = CATransform3DIdentity;
t.m34 = 0.004;
t = CATransform3DRotate(t, -M_PI/180*setAngle, 0, 1, 0);
self.testView.layer.transform = t;

CGFloat getAngle = 0;
if (t.m11 < 0.0f) {
    getAngle = 180.0f - (asin(t.m13) * 180.0f / M_PI);
} else {
    getAngle = asin(t.m13) * 180.0f / M_PI;
}
NSLog(@"setAngle=%@ getAngle=%@", @(setAngle), @(getAngle));