我正在使用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的命中测试类型,但对于estimateVerticalPlane它是零。 ( ARKit 1.5如何获得垂直平面的旋转 )。
此外,当我这样做:在调试器上po hitTestResult.worldTransform它打印一个旋转为worldTransform 91度等但我无法从转换中检索它。
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.
I want to compute the rotation in :
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 }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).
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.
最满意答案
我终于通过以下转换设法从变换中获得了Euler Angles,仍然要检查结果的正确性:
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) } } }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) } } }更多推荐
发布评论