【问题标题】:ARKit estimatedVerticalPlane hit test get plane rotationARKit 估计垂直平面命中测试获取平面旋转
【发布时间】:2018-10-06 08:18:50
【问题描述】:

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

我想计算旋转:

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,它是nil。 (ARKit 1.5 how to get the rotation of a vertical plane)。

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

【问题讨论】:

    标签: arkit hittest


    【解决方案1】:

    我终于通过以下变换从变换中得到了欧拉角,仍然需要检查结果的正确性:

    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)
        }
    }
    }
    

    【讨论】:

    • 最后的向量不应该是roll, pitch, yaw吗?
    • 大概,我们应该模仿一下在eulerAngles中设置的顺序,我现在没时间检查,您能确认一下,所以我更新返回值?
    • 我去看看。我快速浏览了一下,给出的旋转与锚点匹配,但顺序不正确,除非我做错了什么:)
    • 好吧,我认为它看起来不错:)
    • 这是一段很棒的代码 :) 正如你所铺设的那样,你只需要在最后仔细检查向量的结构 :)
    猜你喜欢
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 2020-06-14
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多