iosswiftaccelerometergyroscopecmmotionmanager

Obtain absolute rotation using CMDeviceMotion?


I'm building a simple game with Sprite Kit, the screen doesn't rotate but I want to know the angle the user is holding the phone for a game mechanic.

The values I want to get can be easily retrieved with the accelerometer (x, y) but I have found this to be unreliable so I'm trying to archive better results with CMDeviceMotion. I could obtain the equivalent to data.acceleration.y but I can't figure out how to get the equivalent of data.acceleration.x.

if let data = motionManager.accelerometerData? {
    let y = CGFloat(data.acceleration.y)
    let x = CGFloat(data.acceleration.x)
}

// Device Motion
if let attitude = motionManager.deviceMotion?.attitude? {
    let y = CGFloat(-attitude.pitch * 2 / M_PI) // This matches closely with data.acceleration.y
    let x = ??????????
}

How do I calculate the equivalent to data.acceleration.x using CMDeviceMotion?


Solution

  • This is what I'm trying now. I got to it through experimentation so I cannot tell if it's correct, probably there is a better solution.

                if let attitude = motionManager.deviceMotion?.attitude? {
                     // Convert pitch and roll to [-1, 1] range
                    let pitch = CGFloat(-attitude.pitch * 2 / M_PI)
                    let roll = CGFloat(abs(attitude.roll) > M_PI / 2 ? (2 - abs(attitude.roll) * 2 / M_PI) * (attitude.roll > 0 ? 1 : -1) : attitude.roll * 2 / M_PI)
    
                    // Calculate x and y
                    let y = pitch
                    let x = roll*(1.0-abs(pitch))
                }