Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 你是如何理解这一点的_Swift_Scenekit_Arkit - Fatal编程技术网

Swift 你是如何理解这一点的

Swift 你是如何理解这一点的,swift,scenekit,arkit,Swift,Scenekit,Arkit,在ARKit中,如果你触摸屏幕上的一个点,你能确定该点的位置吗?比如说,距离该点1米远 目前看来,要么你检测到一个生命点 if let hit = sceneView.hitTest(touchLocation, types:.featurePoint).first { … } 或者从屏幕中央变换: var translation = matrix_identity_float4x4 translation.columns.3.z = -1 let transform = simd_mul

在ARKit中,如果你触摸屏幕上的一个点,你能确定该点的位置吗?比如说,距离该点1米远

目前看来,要么你检测到一个生命点

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)
我要找的是距离触摸屏位置1米的距离

更新:我根据建议做了更改

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)
}
然后在触摸中,我改为:

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了!只是不是指的地方,而是指的很大的边距。

当你点击屏幕时,你基本上是在指定一个方向。在三维空间中,可以从两点获得方向。查看可能的解决方案

当你有方向时,你需要对它进行标准化(使它长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
}

当你点击屏幕时,你基本上是在指定一个方向。在三维空间中,可以从两点获得方向。查看可能的解决方案

有了方向后,需要将其规格化(使其长度为1m),并将其添加到当前相机位置

要规范化向量,可以使用以下扩展

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
提供了一个属性,该属性应能准确地提供您所需的内容



如果你想知道如何计算一个距离相机1米的点(不管那里是否有真实世界的表面),但是要与屏幕上的某个特定点对齐,而不是沿着相机的中心线。。。这是你可以开始调查的一条途径。另一种方法是使用命中测试找到一个曲面,然后将生成的向量缩放到1米长。

你是在问如何找到从相机到真实曲面的距离吗

在这种情况下,您需要一个命中测试,就像您问题中的第一个代码片段一样
ARHitTestResult
提供了一个属性,该属性应能准确地提供您所需的内容



如果你想知道如何计算一个距离相机1米的点(不管那里是否有真实世界的表面),但是要与屏幕上的某个特定点对齐,而不是沿着相机的中心线。。。这是你可以开始调查的一条途径。另一种方法是使用命中测试找到一个曲面,然后将生成的向量缩放到1m长。

谢谢,我使用了前面提到的view.unprojectPoint,但我没有在屏幕上看到任何东西。我更新了上面的代码。。。我做错了什么?
getDirection
retuns您正在查看的方向。你需要规格化这个向量,使它的长度为1米,然后将它添加到相机的位置,以获得相机前面1米的位置。好的,我得到相机的位置,添加到方向(我还不知道如何归一化…只是为了看到结果),但什么都没有发生。更新了相关代码。谢谢!这是一个好的开始-我现在可以看到节点。。。但是在错误的位置。我已经编辑了我的答案,谢谢,我使用了上面提到的view.unprojectPoint,但是我没有在屏幕上看到任何东西。我更新了上面的代码。。。我做错了什么?
getDirection
retuns您正在查看的方向。你需要规格化这个向量,使它的长度为1米,然后将它添加到相机的位置,以获得相机前面1米的位置。好的,我得到相机的位置,添加到方向(我还不知道如何归一化…只是为了看到结果),但什么都没有发生。更新了相关代码。谢谢!这是一个好的开始-我现在可以看到节点。。。但是在错误的位置。我已经编辑了我的答案,谢谢,我正在尝试使用@orangenkopf方法,但是我无法在屏幕上看到任何东西(代码更新)。第二种方法的问题是:如果我没有击中任何东西怎么办?我也在寻找同样的方法。就像我有两个点在3d世界测量应用程序。现在我想在2D点中转换它,需要在2D空间中绘制直线(如预览用户绘制的内容),我知道我可以使用
projectPoint
将其转换为2D点,但如何绘制直线并获得距离?距离是通过减去两个3D向量得到的。在将两个3D矢量投影到2D屏幕空间后,您可以使用任何2D绘图工具绘制线条。谢谢,我尝试使用@orangenkopf方法,但我无法在屏幕上获得任何内容(代码更新)。第二种方法的问题是:如果我没有击中任何东西怎么办?我也在寻找同样的方法。就像我有两个点在3d世界测量应用程序。现在我想在2D点中转换它,需要在2D空间中绘制直线(如预览用户绘制的内容),我知道我可以使用
projectPoint
将其转换为2D点,但如何绘制直线并获得距离?距离是通过减去两个3D向量得到的。将两个三维矢量投影到二维屏幕空间后,可以使用任何二维绘图工具绘制线。