繁体   English   中英

核心动力:如何分辨“向上”?

[英]Core Motion: how to tell which way is “up”?

我正在尝试复制Compass应用程序中的功能-并被困在一个特定的位上:如何确定界面中的“向上”是哪种方式?

我在屏幕上有一个标签,并且我有以下代码可以使该标签在设备移动时保持水平:

self.motionManager = CMMotionManager()
self.motionManager?.gyroUpdateInterval = 1/100
self.motionManager?.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: { (deviceMotion, error) -> Void in
  let roll = -deviceMotion.attitude.roll
  self.tiltLabel?.transform = CGAffineTransformRotate(CGAffineTransformIdentity, CGFloat(roll))
})

这种效果是相当不错的,但是在某些情况下它是错误的-例如,当指向iPhone的闪电连接器时,标签会不规则地翻转。

如何使用CoreMotion始终确定哪个方向向上?

更新:显然,滚动/俯仰/偏航是受到万向节锁定影响的欧拉角 -因此,我认为正确的解决方案可能涉及使用四元数 ,而四元数不会受到此问题的困扰,或者CMAttitude上的rotationMatrix可能会有所帮助: https: //developer.apple.com/library/ios/documentation/CoreMotion/Reference/CMAttitude_Class/index.html

对于2D情况,它并不需要那么复杂。 “上”表示“相反的重力”,因此:

motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue()) { (motion, error) in
    // Gravity as a counterclockwise angle from the horizontal.
    let gravityAngle = atan2(Double(motion.gravity.y), Double(motion.gravity.x))

    // Negate and subtract π/2, because we want -π/2 ↦ 0 (home button down) and 0 ↦ -π/2 (home button left).
    self.tiltLabel.transform = CGAffineTransformMakeRotation(CGFloat(-gravityAngle - M_PI_2))
}

但是,如果您尝试在所有三个维度上执行此操作,则“相反重力”的意义就更小:重力方向不会告诉您有关手机围绕重力矢量的角度的任何信息(如果您的手机是面朝上的,则此方向是偏航角)。 要在三个维度上进行校正,我们可以改用滚动,俯仰和偏航测量:

// Add some perspective so the label looks (roughly) the same,
// no matter what angle the device is held at.
var t = self.view.layer.sublayerTransform
t.m34 = 1/300
self.view.layer.sublayerTransform = t

motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.mainQueue()) { (motion, error) in
    let a = motion.attitude
    self.tiltLabel.layer.transform =
        CATransform3DRotate(
            CATransform3DRotate(
                CATransform3DRotate(
                    CATransform3DMakeRotation(CGFloat(a.roll), 0, -1, 0),
                    CGFloat(a.pitch), 1, 0, 0),
                CGFloat(a.yaw), 0, 0, 1),
            CGFloat(-M_PI_2), 1, 0, 0) // Extra pitch to make the label point "up" away from gravity
}

暂无
暂无

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

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