ARKit 估计VerticalPlane hit test 得到平面旋转 [英] ARKit estimatedVerticalPlane hit test get plane rotation

查看:23
本文介绍了ARKit 估计VerticalPlane hit test 得到平面旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ARKit 在运行时检测墙壁,当触摸屏幕的某个点时,我使用 .estimatedVerticalPlane 类型的命中测试.我正在尝试将 Y 旋转应用于与检测到的平面方向相对应的节点.

I am using ARKit to detect walls at runtime, I use a hit test of type .estimatedVerticalPlane when some point of the screen is touched. I am trying to apply Y rotation to node corresponding to the detected plane orientation.

我想计算旋转:

private func computeYRotationForHitLocation(hitTestResult: ARHitTestResult) -> Float {
    guard hitTestResult.type == .estimatedVerticalPlane else { return 0.0 }
//        guard let planeAnchor = hitTestResult.anchor as? ARPlaneAnchor else { return 0.0 }
//        guard let anchoredNode = sceneView.node(for: planeAnchor) else { return 0.0 }

    let worldTransform = hitTestResult.worldTransform
    let anchorNodeOrientation = ???

    return .pi * anchorNodeOrientation.y
}

如何在给定墙壁方向的情况下推断出要应用的 anchorNodeOrientation,这篇文章很好地解释了提供 ARAnchor 的命中测试类型,但对于estimatedVerticalPlane,它为零.(ARKit 1.5 如何获得旋转垂直平面).

How to deduce the anchorNodeOrientation to apply given the wall orientation, this post explains it well for a hit test type that provide an ARAnchor but for estimatedVerticalPlane it is nil. (ARKit 1.5 how to get the rotation of a vertical plane).

此外,当我这样做时:在调试器上 po hitTestResult.worldTransform 它会打印 worldTransform 91 度等的旋转,但我无法从变换中检索它.

Also when I do : po hitTestResult.worldTransform on the debugger it prints a rotation for worldTransform 91 degrees etc but I cannot retrieve it from the transform.

推荐答案

我终于通过下面的变换从变换中得到了欧拉角,还得检查结果的正确性:

I finally managed to get the Euler Angles from the transform through the following transformation, still have to check the results correctness :

import SceneKit
import ARKit

public extension matrix_float4x4 {

/// Retrieve translation from a quaternion matrix
public var translation: SCNVector3 {
    get {
        return SCNVector3Make(columns.3.x, columns.3.y, columns.3.z)
    }
}

/// Retrieve euler angles from a quaternion matrix
public var eulerAngles: SCNVector3 {
    get {
        //first we get the quaternion from m00...m22
        //see http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
        let qw = sqrt(1 + self.columns.0.x + self.columns.1.y + self.columns.2.z) / 2.0
        let qx = (self.columns.2.y - self.columns.1.z) / (qw * 4.0)
        let qy = (self.columns.0.z - self.columns.2.x) / (qw * 4.0)
        let qz = (self.columns.1.x - self.columns.0.y) / (qw * 4.0)

        //then we deduce euler angles with some cosines
        //see https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
        // roll (x-axis rotation)
        let sinr = +2.0 * (qw * qx + qy * qz)
        let cosr = +1.0 - 2.0 * (qx * qx + qy * qy)
        let roll = atan2(sinr, cosr)

        // pitch (y-axis rotation)
        let sinp = +2.0 * (qw * qy - qz * qx)
        var pitch: Float
        if fabs(sinp) >= 1 {
            pitch = copysign(Float.pi / 2, sinp)
        } else {
            pitch = asin(sinp)
        }

        // yaw (z-axis rotation)
        let siny = +2.0 * (qw * qz + qx * qy)
        let cosy = +1.0 - 2.0 * (qy * qy + qz * qz)
        let yaw = atan2(siny, cosy)

        return SCNVector3(roll, pitch, yaw)
    }
}
}

这篇关于ARKit 估计VerticalPlane hit test 得到平面旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆