【问题标题】:Get just the rotation from a CGAffineTransform仅从 CGAffineTransform 获取旋转
【发布时间】:2009-10-01 14:23:46
【问题描述】:

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

提前致谢!

【问题讨论】:

    标签: iphone objective-c transform


    【解决方案1】:
    atan2(rotationTransform.b, rotationTransform.d)
    

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

    This duplicate was the basis for my original answer.

    【讨论】:

    • 我觉得应该是atan2(rotationTransform.b, rotationTransform.d)
    • Luiz - 在平移和旋转的组合下它们都是相同且正确的,但在添加缩放时您的似乎也保持正确,因此我将对其进行更新。谢谢。
    • 使用 transform.b,transform.d 拯救了一天!谢谢!
    • 节省了我的半天时间 :)
    【解决方案2】:

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

    struct CGAffineTransform {
       CGFloat a;
       CGFloat b;
       CGFloat c;
       CGFloat d;
       CGFloat tx;
       CGFloat ty;
    };
    

    【讨论】:

    • Quartz 2D 编程指南的“矩阵背后的数学”小节解释了这背后的数学:developer.apple.com/mac/library/DOCUMENTATION/GraphicsImaging/…
    • asin 和 acos 在有刻度时不正确。正确的公式是:CGFloat 弧度 = atan2f(self.view.transform.b, self.view.transform.a); CGFloat 度数 = 弧度 * (180 / M_PI);
    【解决方案3】:

    您可以尝试使用 acos() 和 asin() 函数来反转 CGAffineTransformMakeRotation 所做的事情。但是,由于您已经在其中乘以 Scale 变换矩阵,所以这样做可能有点困难。

    【讨论】:

      【解决方案4】:

      我过去曾使用 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 代码。)

      【讨论】:

        【解决方案5】:

        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];
        

        【讨论】:

          猜你喜欢
          • 2014-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-27
          相关资源
          最近更新 更多