首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ARKit -如何知道3d对象是否位于屏幕的中心?

ARKit -如何知道3d对象是否位于屏幕的中心?
EN

Stack Overflow用户
提问于 2020-10-24 10:22:24
回答 3查看 219关注 0票数 1

我将3d对象放置在世界空间中。在那之后,我尝试随机移动相机。然后现在我需要知道在我通过isNode方法知道对象已经变成了锥体内部之后,对象是在相机视图的中心,顶部还是底部。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-10-27 04:26:20

我用另一种方法解决了问题:

代码语言:javascript
运行
复制
 let results = self.sceneView.hitTest(screenCenter!, options: [SCNHitTestOption.rootNode: parentnode])

其中parentnode是目标节点的父节点,因为我有多个节点。

票数 0
EN

Stack Overflow用户

发布于 2020-10-24 16:22:11

解决方案

要做到这一点,你需要使用一个技巧。创建新的SCNCamera,使其成为pointOfView default camera的子项,并将其FoV设置为大约10度。

然后在renderer(_:updateAtTime:)实例方法中使用isNode(:insideFrustumOf:)方法。

以下是工作代码:

代码语言:javascript
运行
复制
import ARKit

class ViewController: UIViewController,
                      ARSCNViewDelegate,
                      SCNSceneRendererDelegate {

    @IBOutlet var sceneView: ARSCNView!
    @IBOutlet var label: UILabel!
    let cameraNode = SCNNode()
    let sphereNode = SCNNode()
    let config = ARWorldTrackingConfiguration()
    
    public func renderer(_ renderer: SCNSceneRenderer,
                  updateAtTime time: TimeInterval) {
        
        DispatchQueue.main.async {
            if self.sceneView.isNode(self.sphereNode,
                                     insideFrustumOf: self.cameraNode) {
                self.label.text = "In the center..."
            } else {
                self.label.text = "Out OF CENTER"
            }
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        sceneView.delegate = self
        sceneView.allowsCameraControl = true
        let scene = SCNScene()
        sceneView.scene = scene
        
        cameraNode.camera = SCNCamera()
        cameraNode.camera?.fieldOfView = 10
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            self.sceneView.pointOfView!.addChildNode(self.cameraNode)
        }
        
        sphereNode.geometry = SCNSphere(radius: 0.05)
        sphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.red
        sphereNode.position.z = -1.0
        sceneView.scene.rootNode.addChildNode(sphereNode)
        sceneView.session.run(config)
    }
}

此外,在此解决方案中,您可以为子摄影机启用orthographic projection,而不是perspective one。当模型远离相机时,它会有所帮助。

代码语言:javascript
运行
复制
cameraNode.camera?.usesOrthographicProjection = true

下面是你的屏幕可能的样子:

下一步

同样,您可以附加两个额外的SCNCameras,将它们放在中心SCNCamera的上方和下方,并使用两个额外的isNode(:insideFrustumOf:)实例方法测试您的对象。

票数 1
EN

Stack Overflow用户

发布于 2020-10-26 17:38:41

对于不是黑客攻击的解决方案,您可以使用projectPoint:应用编程接口。使用像素坐标可能更好,因为此方法使用实际相机的设置来确定对象在屏幕上的位置。

代码语言:javascript
运行
复制
let projectedPoint = sceneView.projectPoint(self.sphereNode.worldPosition)
let xOffset = projectedPoint.x - screenCenter.x; 
let yOffset = projectedPoint.y - screenCenter.y; 
if xOffset * xOffset + yOffset * yOffset < R_squared {
    // inside a disc of radius 'R' at the center of the screen
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64509350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档