ARKit – 有没有办法知道对象在与 ARCamera 相关的空间中的位置? [英] ARKit – Is there a way to know where the object is located in space related to ARCamera?

查看:14
本文介绍了ARKit – 有没有办法知道对象在与 ARCamera 相关的空间中的位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 ARKit 的屏幕上有一个对象,我想知道它与相机方向之间的水平角度,或者至少该对象位于屏幕的左侧、中间或右侧?

I have an object in ARKit's screen and I want to know the horizontal angle between it and the camera direction, or at least is the object on the left, center or right of the screen?

推荐答案

绝对(很好)

首先,我们需要了解 ARKit.

First, we need to understand ARKit.

  1. ARKit 对象不在 实际 空间中,而是基于相机看到的内容.

  1. ARKit objects are not in actual space and are based off of what the camera sees.

相机并不完美;您会注意到 静止" 物体由于光线、周围环境等原因四处移动.

The camera is not perfect; You will notice "stationary" objects moving around either due to lighting, surroundings, etc.

没有人的手是稳稳的;不仅物体会移动,手机也会做一些小的调整.

No one's hand is steady; not only will the object be moving, but the phone will be doing small adjustments as well.

现在,提供这些信息,我们可以使用我们知道的变量来计算 3 个已知位置之间的角度(当然是在 3D 空间中!).

Now, provided this information, we can use the variables we know to calculate the angle between 3 known positions (in 3D Space of course!).

使用这个答案,我们可以看到通过很多数学我们可以从 3 个 3D 点获得一个角度

Using this answer, we can see that through lots of math we can get to an angle from 3 3D points

现在,进入它的代码.

让我们得到我们的变量

  1. 您可以使用 SCNSceneRendererDelegate
  2. 提供的函数获取您的 phone 位置

func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
    guard let pointOfView = sceneView.pointOfView else { return }
    let transform = pointOfView.transform
    let orientation = SCNVector3(-transform.m31, -transform.m32, transform.m33)
    let location = SCNVector3(transform.m41, transform.m42, transform.m43)
    let currentPositionOfCamera = orientation + location
    print(currentPositionOfCamera)
}

func +(lhv:SCNVector3, rhv:SCNVector3) -> SCNVector3 {
     return SCNVector3(lhv.x + rhv.x, lhv.y + rhv.y, lhv.z + rhv.z)
}

  1. 你可以通过这样做获得你的object

let anObject = SCNNode()
let pos = anObject.position

  1. 你可以用一种有点创意的方式获得你的 userViewDirection —— 我能想到的最好方法是创建一个新的 SCNNode 并将它放在前面一段距离你的.我们可以通过使用这个链接来做到这一点
  1. You can get your userViewDirection in a slightly creative way -- the best way I can come up with is to create a new SCNNode and place it some distance in front of you. We can do this by using this link

func updatePositionAndOrientationOf(_ node: SCNNode, withPosition position: SCNVector3, relativeTo referenceNode: SCNNode) {
    let referenceNodeTransform = matrix_float4x4(referenceNode.transform)

    // Setup a translation matrix with the desired position
    var translationMatrix = matrix_identity_float4x4
    translationMatrix.columns.3.x = position.x
    translationMatrix.columns.3.y = position.y
    translationMatrix.columns.3.z = position.z

    // Combine the configured translation matrix with the referenceNode's transform to get the desired position AND orientation
    let updatedTransform = matrix_multiply(referenceNodeTransform, translationMatrix)
    node.transform = SCNMatrix4(updatedTransform)
}

//Create a global node 
let lookingNode:SCNNode = SCNNode()

//Now update node say `2` away in the Z (looking direction)
let position = SCNVector3(x: 0, y: 0, z: -2)
updatePositionAndOrientationOf(lookingNode, withPosition: position, relativeTo: cameraNode)

现在我们有了 3 个变量.

Now we have our 3 variables.

我们可以简单地对它们进行数学运算:)

We can san simply do math on them :)

//Vertex is pos1
func calculateAngleBetween3Positions(pos1:SCNVector3, pos2:SCNVector3, pos3:SCNVector3) -> Float {
    let v1 = SCNVector3(x: pos2.x-pos1.x, y: pos2.y-pos1.y, z: pos2.z-pos1.z)
    let v2 = SCNVector3(x: pos3.x-pos1.x, y: pos3.y-pos1.y, z: pos3.z-pos1.z)

    let v1Magnitude = sqrt(v1.x * v1.x + v1.y * v1.y + v1.z * v1.z)
    let v1Normal = SCNVector3(x: v1.x/v1Magnitude, y: v1.y/v1Magnitude, v1.z/v1Magnitude)
  
    let v2Magnitude = sqrt(v2.x * v2.x + v2.y * v2.y + v2.z * v2.z)
    let v2Normal = SCNVector3(x: v2.x/v2Magnitude, y: v2.y/v2Magnitude, v2.z/v2Magnitude)

    let result = v1Normal.x * v2Normal.x + v1Normal.y * v2Normal.y + v1Normal.z * v2Normal.z
    let angle = acos(result)

    return angle
}

这篇关于ARKit – 有没有办法知道对象在与 ARCamera 相关的空间中的位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆