是否可以从也具有平移和缩放值的 CGAffineTransform 获得旋转角度?如果是,如何?
提前致谢!
atan2(rotationTransform.b, rotationTransform.d)
某人建议的 acos(b) 解决方案仅在 +/-0.5pi 范围内有效。这个解决方案在旋转、平移和缩放的组合下看起来很健壮,尽管几乎可以肯定不是剪切。我之前的答案 ( atan2(rotationTransform.b, rotationTransform.a
) 对缩放并不稳健。
取仿射成员 b 或 c 的 asin() 或 acos()。
struct CGAffineTransform {
CGFloat a;
CGFloat b;
CGFloat c;
CGFloat d;
CGFloat tx;
CGFloat ty;
};
您可以尝试使用 acos() 和 asin() 函数来反转CGAffineTransformMakeRotation的作用。但是,由于您已经在其中乘以 Scale 变换矩阵,因此这样做可能有点困难。
我过去曾使用 GeoTools 工具包中的 XAffineTransform 类从仿射矩阵中提取旋转。即使应用了缩放和剪切,它也可以工作。
它是一个 Java 库,但您应该能够轻松地将其转换为 (Objective-)C。您可以在此处查看 XAffineTransform 的源代码。(该方法称为 getRotation。)您可以在此处阅读 API。
这是该方法的核心:
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);
您还需要实现 getScale/getShear 方法。一点都不难。(在大多数情况下,您可以直接复制 Java 代码。)
当有规模时,asin 和 acos 是不正确的。
正确的公式是:
CGFloat radians = atan2f(self.view.transform.b, self.view.transform.a);
CGFloat degrees = radians * (180 / M_PI);
或者:
CGFloat angle = [(NSNumber *)[view valueForKeyPath:@"layer.transform.rotation.z"] floatValue];