首页 > 解决方案 > iOS ARKit - Calculate the degree of rotation of device in all three direction

问题描述

I want to get the degree of Rotation of all three axis. I am trying to achieve with landscape mode. When rotate device from left to right (Y-rotation), I want the degree covered once user set a left end and rotatae to right. So we need the degree 360 when it reached the starting point. So for the y-rotation, using the following calculation and it is fine.

let q = sceneView.pointOfView.orientation
let yRotation = Float.pi - atan2f( (2*q.y*q.w)-(2*q.x*q.z), 1-(2*pow(q.y,2))-(2*pow(q.z,2)) )

Ref: Getting the rotation of device around the world origin's y axis in ARKit

Similarly, want the Z-rotation, for Z-rotation , no need for 360 degree rotation. But need accurate value when rotate about upto 90 degree This is fine if we use the

var zRotation = sceneView.pointOfView.eulerAngles.z

But this will be wrong* if we rotate the device on left to right (Y-direction ) some degree and then check the Z rotation, we will get the Z-rotation values as near to 180 degree rather than near to 0

So tried a bad way to get the Z rotation like:

var zRotation = sceneView.pointOfView.eulerAngles.z
if abs(sceneView.pointOfVieweulerAngles.z.toDegree) > 90 {
    zRotation = (abs(cameraNode.eulerAngles.z.toDegree) - 180).toRadian
}

But this is not accurate, we can see a jumb the Z-rotation value when subtracting 180.

Could you suggest a proper method..

X-rotation value is simialr to Z-rotation, getting values near to 180 when check after rotate left to right (Y-rotation) some degree.

Thanks

Edited: Sep 3, 2109 For x and y, Now I am using

let xRotation = sceneView!.session.currentFrame!.camera.eulerAngles.x
let zRotation = sceneView!.session.currentFrame!.camera.eulerAngles.z

标签: iosswiftarkiteuler-anglesarscnview

解决方案


如果您禁用横向(左和右),您将获得很好的 x、y 和 z 旋转数据。

if let q = self?.sceneView.pointOfView?.orientation {

            let heading = atan2f( (2 * q.y * q.w) - (2 * q.x * q.z), 1 - (2 * pow(q.y,2)) - (2 * pow(q.z,2)) )
            let attitude = asinf( (2 * q.x * q.y) + (2 * q.z * q.w) )
            let bank = atan2f( (2 * q.x * q.w) - (2 * q.y * q.z), 1 - (2 * pow(q.x,2)) - (2 * pow(q.z,2)) )

            print("X: \(attitude * (180.0 / .pi)) Y: \(heading * (180.0 / .pi)) Z: \(bank * (180.0 / .pi))")

    }

如果您允许横向方向,那么您将获得不同的值。一旦设备从纵向变为横向,您将获得旋转数据,就好像整个坐标空间已经旋转了 pi/2 弧度。然后您必须调整数据(添加或减去 pi/2)以获得正确的值。 有没有办法在更改为横向方向后转换坐标系?

因此,如果您不希望设备窗口随方向旋转,请取消选择横向模式。虽然您可以获得所有方向信息来执行任何 UI 更改:

if UIDevice.current.orientation == UIDeviceOrientation.faceUp {
                print("faceUp")
            } else if UIDevice.current.orientation == UIDeviceOrientation.landscapeRight {
                print("landscapeRight")
            } else if UIDevice.current.orientation == UIDeviceOrientation.portrait {
                print("portrait")
            } else if UIDevice.current.orientation == UIDeviceOrientation.portraitUpsideDown {
                print("portraitUpsideDown")
            }

推荐阅读