你如何获得 ARKit 中的点

How do you get the point in ARKit

在 ARKit 中,如果你触摸屏幕上的一个点,你能确定这个点的位置吗?说是离这个点 1m 远?

目前看来要么你检测到生命值

if let hit = sceneView.hitTest(touchLocation, types:.featurePoint).first {
  …
}

或者你从屏幕中央变换:

var translation = matrix_identity_float4x4
translation.columns.3.z = -1
let transform = simd_mul(currentFrame.camera.transform, translation)

我要找的是距离触摸位置1m处。

更新:我根据建议进行了更改。

func getDirection(for point: CGPoint, in view: SCNView) -> SCNVector3 {
    let farPoint  = view.unprojectPoint(SCNVector3(Float(point.x), Float(point.y), 1))
    let nearPoint = view.unprojectPoint(SCNVector3(Float(point.x), Float(point.y), 0))

    return SCNVector3(farPoint.x - nearPoint.x, farPoint.y - nearPoint.y, farPoint.z - nearPoint.z)
}

func getCameraPosition() -> SCNVector3 {
    let transform = sceneView.session.currentFrame?.camera.transform
    let pos = MDLTransform(matrix:transform!)
    return SCNVector3(pos.translation.x, pos.translation.y, pos.translation.z)
}

然后在touches中我改为:

if let touchLocation = touches.first?.location(in:sceneView) {
  …
  let node = SCNNode(geometry: geometry)
  let pos = getCameraPosition()
  let dir = getDirection(for: touchLocation, in: sceneView).normalized
  node.position = SCNVector3(pos.x + dir.x, pos.y + dir.y, pos.z + dir.z)
}

基于评论中的规范化扩展名。我现在可以看到 SCNNode 了!只是不是手指所指的地方,差了一大截。

当您点击屏幕时,您基本上是在指定一个方向。在 3D space 中,您可以从两个点获得方向。查看 以获得可能的解决方案。

有了方向后,您需要对其进行归一化(使其长度为 1 米)并将其添加到当前相机位置。

要标准化向量,您可以使用这些扩展

extension SCNVector3 {
    /// Returns the length of the vector
    var length: Float {
        return sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
    }
    var normalized: SCNVector3 {
        let length = self.length
        return SCNVector3(self.x/length, self.y/length, self.z/length)
    }
}

编辑:

这对我来说很好用:

func getCameraPosition(in view: ARSCNView) -> SCNVector3? {
    guard let lastFrame = view.session.currentFrame else {
        return nil
    }

    let position = lastFrame.camera.transform * float4(x: 0, y: 0, z: 0, w: 1)
    let camera: SCNVector3 = SCNVector3(position.x, position.y, position.z)

    return camera
}

你是问如何找到从相机到真实世界表面的距离?

在这种情况下,您需要进行命中测试,就像您问题中的第一个代码片段一样。 ARHitTestResult 提供了 distance 属性 应该可以准确地满足您的需求。


如果您询问如何计算距离相机正好 1 米的点(无论那里是否有真实世界的表面),但与屏幕上的特定点一致,而不是沿着相机的中心线.. . 是您可以开始调查的一种途径。另一种方法是使用命中测试找到一个表面,然后将所得矢量的长度缩放到 1 米。