【发布时间】:2019-06-25 12:04:40
【问题描述】:
我想根据 iPhone 的滚动/俯仰/偏航以 3D 形式围绕其中心点旋转图像。
哪个是首选解决方案:CGAffineTransform 还是 CATransform3D?
有什么我可以效仿的例子吗?有许多帖子暗示了解决方案。
为简单起见,图像是一个矩形。
非常感谢。
【问题讨论】:
标签: swift cgaffinetransform catransform3d
我想根据 iPhone 的滚动/俯仰/偏航以 3D 形式围绕其中心点旋转图像。
哪个是首选解决方案:CGAffineTransform 还是 CATransform3D?
有什么我可以效仿的例子吗?有许多帖子暗示了解决方案。
为简单起见,图像是一个矩形。
非常感谢。
【问题讨论】:
标签: swift cgaffinetransform catransform3d
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(rect1、rect2),并将它们连接到 viewController。当您旋转设备时,这些视图将相应地转换。你可以试试 CMQuaternion (m.attitude.quaternion) 做类似的工作。
【讨论】: