在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了!只是没有手指指向的位置,大幅度偏离。
答案 0 :(得分:4)
当您点击屏幕时,您基本上是指定方向。在3D空间中,您可以从两个点获得方向。查看this question以获取可能的解决方案。
当你有方向时需要将其标准化(使其长度为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
}
答案 1 :(得分:0)
您是否在询问如何找到从相机到真实世界表面的距离?
在这种情况下,您需要一个匹配测试,就像您问题中的第一个代码段一样。 ARHitTestResult
提供distance
属性,可以为您提供您正在寻找的内容。
如果您正在询问如何计算距离相机正好1米的点(无论是否存在真实世界表面),而是与屏幕上的特定点对齐,而不是沿着相机的中心线... { {3}}是您可以开始调查的一条途径。另一种方法是使用命中测试来找到一个表面,然后将得到的矢量缩放到1米长。