iOS ARKit-计算设备在所有三个方向上的旋转度

iOS ARKit-计算设备在所有三个方向上的旋转度,ios,swift,arkit,euler-angles,arscnview,Ios,Swift,Arkit,Euler Angles,Arscnview,我想得到所有三个轴的旋转度。我试图实现与景观模式。 当将设备从左向右旋转(Y旋转)时,我希望在用户设置左端并向右旋转后覆盖度。所以当它到达起点时,我们需要360度。因此,对于y旋转,使用以下计算,这是很好的 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)) ) 参考: 类似地,想

我想得到所有三个轴的旋转度。我试图实现与景观模式。 当将设备从左向右旋转(Y旋转)时,我希望在用户设置左端并向右旋转后覆盖度。所以当它到达起点时,我们需要360度。因此,对于y旋转,使用以下计算,这是很好的

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)) )
参考:

类似地,想要Z旋转,对于Z旋转,不需要360度旋转。但旋转90度时需要精确的值 如果我们使用

var zRotation = sceneView.pointOfView.eulerAngles.z
但这是错误的。如果我们将设备从左向右(Y方向)旋转一定程度,然后检查Z旋转,我们将得到接近180度的Z旋转值,而不是接近0

所以尝试了一种糟糕的方法来获得Z旋转,如:

var zRotation = sceneView.pointOfView.eulerAngles.z
if abs(sceneView.pointOfVieweulerAngles.z.toDegree) > 90 {
    zRotation = (abs(cameraNode.eulerAngles.z.toDegree) - 180).toRadian
}
但这并不准确,我们可以在减去180时看到Z轴旋转值的巨大变化

你能建议一个合适的方法吗

X旋转值与Z旋转值类似,在从左向右旋转(Y旋转)一定程度后进行检查时,值接近180

谢谢

编辑:2109年9月3日 对于x和y,现在我使用

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

如果禁用横向方向(左和右),您将获得相当好的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")
            }

如果我的问题需要更多的澄清或细节,请发表意见。您所面临的是一个称为Gimble Lock()的问题,这是您正在使用的Euler Angles()固有的基本问题。正是因为这个原因,3D图形中引擎盖下的所有东西都使用四元数()表示旋转角度。具体的用例是什么?--也许我可以建议另一种解决方案。我正在尝试拍摄全景视频。从左到右和从下到上的方向。进行左右(Y)旋转时,我想知道准确的Z旋转和X旋转角度,以便根据AR对象验证和定心框架。您是否计划捕获多个水平条带?或者只是一个水平带(从左到右),您只想检查上/下枢轴以确保手机保持水平?是的,我想捕捉多个水平和垂直脚部。并确保有多少偏差。在左右画面中,我想知道每帧的X和Z旋转值。对于上下镜头,我想知道每帧的Y和Z旋转值。我只使用横向模式初始化AR(并且需要横向模式下的旋转度),因此上述解决方案不适合我的情况。