ARKit оценилВертикальный тест на удар самолета, чтобы получить вращение самолета - PullRequest
0 голосов
/ 25 апреля 2018

Я использую 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, но для оцененного VerticalPlane он равен нулю.( ARKit 1.5, как получить вращение вертикальной плоскости ).

Также, когда я делаю: po hitTestResult.worldTransform на отладчике, он печатает вращение для worldTransform на 91 градус и т. Д., Но я не могуполучить его из преобразования.

1 Ответ

0 голосов
/ 12 мая 2018

Мне, наконец, удалось получить углы Эйлера из преобразования с помощью следующего преобразования, но мне все равно нужно проверить правильность результатов:

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