我需要快速使用陀螺仪的帮助

时间:2019-10-12 17:08:41

标签: swift xcode

我现在对此深有感触,所以当我翻转手机时,它会在文本中添加一个,但它会一直添加直到完成翻转。我有办法做到这一点,所以每次翻转都会增加一个。

更改y>代码

func startGyro() {
    motionManager.gyroUpdateInterval = 0.2
    motionManager.startGyroUpdates(to: OperationQueue.current!) { (data, Error) in
        if let myData = data {
            if myData.rotationRate.y > 3 {
                tiltOut = tiltOut + 1
                self.labelText = "\(tiltOut)"
            }
        }
    }
}

我希望它每次翻转记录一次。

1 个答案:

答案 0 :(得分:0)

将此代码视为代码示例,而不是复制粘贴示例,因为与陀螺仪相关的代码很难测试,但此处的核心思想是跟踪经过的时间和旋转速率,以确定与代码的距离。设备已旋转。

var prevTime = DispatchTime.now()
var totalRotation: CGFloat = 0
var delta: CGFloat = 10

func startGyro() {
    motionManager.gyroUpdateInterval = 0.2
    motionManager.startGyroUpdates(to: OperationQueue.current!) { (data, Error) in
        if let myData = data {
            let currTime = DispatchTime.now()
            let dt = 0
            let interval = prevTime.distance(to: currTime)
            if case .nanoseconds(let value) = interval {
                dt = value
            }
            prevTime = currTime
            // assuming rotationRate is in degrees/millisecond.
            let dTheta: CGFloat = CGFloat(myData.rotationRate.y) * CGFloat(dt)
            // If not milliseconds, convert dt to correct time unit
            // If rotationRate is in radians, convert to degrees or make future comparison check for 2*pi instead of 360 degrees
            totalRotation += dTheta
            if totalRotation > 360 - delta && totalRotation < 360 + delta {
                tiltOut = tiltOut + 1
                self.labelText = "\(tiltOut)"
                totalRotation -= 360
            }
        }
    }
}

存在增量是因为startGyroUpdates不会在设备每次旋转1度时被调用,因此您必须提供一个缓冲区来确定“大约360度”可以做什么。在这里,我给出了一个范围,如果它已经旋转了350-370度,则应该将标签加1。当然,这使用的是离散的时间块,但是假设startGyroUpdates调用与该时间段中rotationRate的变化之间的时间间隔相对较小,则应该不会出现太多错误。该代码还假设电话在startGyroUpdates次通话之间不会旋转超过360度,这是一个公平的假设。

如果您知道旋转速度会相当恒定,则也可以使用旋转速度的平均值并将其乘以经过的时间。

编辑:在dTheta之前忘记了let,并添加了将DispatchTimeInterval转换为可用Int的代码。您可以添加秒,毫秒等的大小写,并将dt转换为rotationRate的时间单位。有关将prevTime.distance(to: currTime)的结果转换为可以进行数学运算的Int的更多信息,请参见this SO link。确保进行单位转换时不会损失精度。

编辑2 :指定dTheta类型为CGFloat

编辑3 :将myData.rotationRate.ydt投射到CGFloat