ARKit估计垂直平面击中测试获得平面旋转(ARKit estimatedVerticalPlane hit test get plane rotation)

编程入门 行业动态 更新时间:2024-10-21 17:24:22
ARKit估计垂直平面击中测试获得平面旋转(ARKit estimatedVerticalPlane hit test get plane rotation)

我正在使用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) } } }

更多推荐

本文发布于:2023-04-29 10:09:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1335921.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:平面   测试   estimatedVerticalPlane   ARKit   plane

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!