Swift 你是如何理解这一点的
在ARKit中,如果你触摸屏幕上的一个点,你能确定该点的位置吗?比如说,距离该点1米远 目前看来,要么你检测到一个生命点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
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向量得到的。将两个三维矢量投影到二维屏幕空间后,可以使用任何二维绘图工具绘制线。