【发布时间】:2009-10-01 14:23:46
【问题描述】:
是否可以从同时具有平移和缩放值的 CGAffineTransform 获得旋转角度?如果是,怎么做?
提前致谢!
【问题讨论】:
标签: iphone objective-c transform
是否可以从同时具有平移和缩放值的 CGAffineTransform 获得旋转角度?如果是,怎么做?
提前致谢!
【问题讨论】:
标签: iphone objective-c transform
atan2(rotationTransform.b, rotationTransform.d)
某人建议的 acos(b) 解决方案仅在 +/-0.5pi 范围内有效。这个解决方案在旋转、平移和缩放的组合下看起来很健壮,尽管几乎可以肯定不是剪切。我之前的回答 (atan2(rotationTransform.b, rotationTransform.a) 对扩展并不稳健。
【讨论】:
atan2(rotationTransform.b, rotationTransform.d)
取仿射成员 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。你可以看看the source for XAffineTransform here。 (该方法称为getRotation。)您可以read the API here。
这是方法的核心:
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];
【讨论】: