繁体   English   中英

从CGAffineTransform获取旋转

[英]Get just the rotation from a CGAffineTransform

是否可以从具有平移和缩放值的CGAffineTransform获得旋转角度? 如果有,怎么样?

提前致谢!

取仿射成员b或c的asin()或acos()。

struct CGAffineTransform {
   CGFloat a;
   CGFloat b;
   CGFloat c;
   CGFloat d;
   CGFloat tx;
   CGFloat ty;
};
atan2(rotationTransform.b, rotationTransform.d)

某人建议的acos(b)解决方案仅在+/- 0.5pi范围内有效。 这种解决方案在旋转,平移和缩放的组合下似乎很稳健,尽管几乎肯定不会剪切。 我之前的回答( atan2(rotationTransform.b, rotationTransform.a )对缩放不稳健。

这个副本是我原来答案的基础

您可以尝试使用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];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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