В настоящее время я смущен с точки зрения создания функциональности 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 шоу), если повернуть устройство вокруг оси г, стрелка по-прежнему вращается вокруг оси у. Я сделал что-то неправильно?