2017-02-21 11 views
0

В настоящее время я смущен с точки зрения создания функциональности 3D-компаса. С SceneKit, я загружен объект стрелки, а затем неправдоподобные данные датчика, как показано ниже кода (Эффект this video)Как реализовать 3D-компас с помощью SceneKit

let motionManager = CMMotionManager() 
motionManager.deviceMotionUpdateInterval = 1.0/60.0 
if motionManager.isDeviceMotionAvailable { 
    motionManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: { (devMotion, error) -> Void in 
     arrow.orientation = SCNQuaternion(-CGFloat((motionManager.deviceMotion?.attitude.quaternion.x)!), -CGFloat((motionManager.deviceMotion?.attitude.quaternion.y)!), -CGFloat((motionManager.deviceMotion?.attitude.quaternion.z)!), CGFloat((motionManager.deviceMotion?.attitude.quaternion.w)!)) 

     })} 

После того, как это сделали, если пользователь повернуть устройство в любой оси, стрелка может вращаться, как Что ж. Поскольку это 3D-компас, мне нужно, чтобы стрелка указывала направление. Поэтому я получил данные заголовка через CLLocationManager, а затем проблема наступает.

let gq1: GLKQuaternion = GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(heading), 0, 0, 1) 
arrow.orientation = SCNVector4(gq1.x,gq1.y,gq1.z,gq1.w) 

Приведенный выше код отлично работает в 2D, как рисунок ниже, он правильно указывает направление на восток. Но я хочу его в 3D-среде, так что я сделал, как показано ниже

motionManager.deviceMotionUpdateInterval = 1.0/60.0 
    if motionManager.isDeviceMotionAvailable { 
     motionManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: { (devMotion, error) -> Void in 
      arrow.orientation = orient(q: (motionManager.deviceMotion?.attitude.quaternion)!, angle: heading) 
    } 
func orient(q:CMQuaternion,angle:Float) -> SCNQuaternion{ 
    GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(-angle), 0, 0, 1) 
    let gq1: GLKQuaternion = GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(-angle), 0, 0, 1) 
    // add a rotation in z axis 
    let gq2: GLKQuaternion = GLKQuaternionMake(Float(q.x), Float(q.y), Float(q.z), Float(q.w)) 
    // the current orientation 
    let qp: GLKQuaternion = GLKQuaternionMultiply(gq1, gq2) 
    // get the "new" orientation 
    var rq = CMQuaternion() 
    rq.x = Double(qp.x) 
    rq.y = Double(qp.y) 
    rq.z = Double(qp.z) 
    rq.w = Double(qp.w) 
    return SCNVector4(-Float(rq.x), -Float(rq.y), -Float(rq.z), Float(rq.w)) 
} 

Существует ошибка (this video шоу), если повернуть устройство вокруг оси г, стрелка по-прежнему вращается вокруг оси у. Я сделал что-то неправильно?

enter image description here

ответ

0

Если я повернуть устройство вокруг оси г с помощью этого метода, данные направления выходит непрерывно. В результате я не могу использовать CLLocationManager для достижения своей цели. Это thread - это то, что я хочу.

 Смежные вопросы

  • Нет связанных вопросов^_^