【问题标题】:Swift 3D rotation of UIImageView (CGAffineTransform or CATransform3D)UIImageView 的 Swift 3D 旋转(CGAffineTransform 或 CATransform3D)
【发布时间】:2019-06-25 12:04:40
【问题描述】:

我想根据 iPhone 的滚动/俯仰/偏航以 3D 形式围绕其中心点旋转图像。

哪个是首选解决方案:CGAffineTransform 还是 CATransform3D?

有什么我可以效仿的例子吗?有许多帖子暗示了解决方案。

为简单起见,图像是一个矩形。

非常感谢。

【问题讨论】:

    标签: swift cgaffinetransform catransform3d


    【解决方案1】:

    CoreMotion 给出设备当前的姿态(偏航、俯仰、滚动、欧拉模式或四元数旋转)。这是表达同一事物的三种不同方式。 您需要做的是正确应用转换以反映设备当前的态度。 考虑这个示例。

    import UIKit
    import CoreMotion
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var rect1: UIView! // Add background color to be ale to see it
        @IBOutlet weak var rect2: UIView!
    
        @IBOutlet weak var xLabel: UILabel!
        @IBOutlet weak var yLabel: UILabel!
        @IBOutlet weak var zLabel: UILabel!
    
    
        let motionManager = CMMotionManager() // The one and only for the app
    
        override func viewDidLoad() {
            super.viewDidLoad()
            //The device motion object provides the device orientation in several equivalent forms: Euler angles, a rotation matrix, and a quaternion. Since we already use matrices to represent rotations in our Metal code, they are they best fit for incorporating Core Motion’s data into our app.
            let motionHandler: CMDeviceMotionHandler = { [weak self] (motion, error)  in
                if let err = error { print(err) }
                if let m = motion {
                    self?.xLabel.text = "Yaw: \(m.attitude.yaw)"
                    self?.yLabel.text = "Pitch: \(m.attitude.pitch)"
                    self?.zLabel.text = "Roll: \(m.attitude.roll)"
    
                    var transform: CATransform3D
    
                    transform = CATransform3DMakeRotation(CGFloat(m.attitude.pitch), 1, 0, 0) // X rotation
                    transform = CATransform3DRotate(transform, CGFloat(m.attitude.roll), 0, 1, 0) // Y rotation
                    transform = CATransform3DRotate(transform, CGFloat(m.attitude.yaw), 0, 0, 1) // Z rotation
                    print(transform)
    
                    self?.rect1.layer.transform = transform
                    // Mind coordinate space is most intuitive. The following transform differs.
                    // If you can tell why - please do.
                    let rm = m.attitude.rotationMatrix
    
                    transform = CATransform3D(m11: CGFloat(rm.m11), m12: CGFloat(rm.m12), m13: CGFloat(rm.m13), m14: 0,
                                              m21: CGFloat(rm.m21), m22: CGFloat(rm.m22), m23: CGFloat(rm.m23), m24: 0,
                                              m31: CGFloat(rm.m31), m32: CGFloat(rm.m32), m33: CGFloat(rm.m33), m34: 0,
                                              m41: 0,               m42: 0,               m43: 0,               m44: 1)
                    print(transform)
    
    
                    self?.rect2.layer.transform = transform
                    //self?.compass.layer.sublayerTransform = transform
                    //[myImage setNeedsDisplay];
                }
            }
            motionManager.deviceMotionUpdateInterval = 0.1
    
            if let current = OperationQueue.current {
                motionManager.startDeviceMotionUpdates(using: .xArbitraryCorrectedZVertical/*.xTrueNorthZVertical*/, to: current, withHandler: motionHandler)
            }
    
        }
    }
    

    要重现,必须在 Storyboard 中创建 UIView(rect1rect2),并将它们连接到 viewController。当您旋转设备时,这些视图将相应地转换。你可以试试 CMQuaternion (m.attitude.quaternion) 做类似的工作。

    【讨论】:

      猜你喜欢
      • 2010-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-01
      • 1970-01-01
      相关资源
      最近更新 更多