【问题标题】:How to determine if an ScnNode is left or right of the view direction of a camera node in SceneKit如何判断一个ScnNode是在SceneKit中相机节点的视图方向的左边还是右边
【发布时间】:2017-05-25 14:05:58
【问题描述】:

我在 SceneKit 场景的中心位置 (0,0,0) 有一个摄像头 我正在围绕 y 轴旋转相机以显示场景的不同部分。

我想在屏幕的左侧/右侧显示箭头,以显示用户必须向哪个方向移动才能查看目标对象。

如何计算 ScnNode 是否位于视图方向的左侧?

我知道:

  • 相机节点的位置和旋转
  • 目标节点的位置

【问题讨论】:

标签: ios swift scenekit skscene


【解决方案1】:
  1. 计算节点相对于相机的向量。通过从节点位置中减去相机位置来计算向量
  2. 使用atan2 将矢量转换为角度。 Apple 文档的解释有点薄。 raywenderlich.com有教程。

例如

let v = CGPoint(x: nodePosition.x - cameraPosition.x, y: nodePosition.y - cameraPosition.y);
let a = atan2(v.y, v.x) // Note: order of arguments

角度以弧度为单位,范围在 -π 和 π(-180 到 180 度)之间。如果值为负,则节点在相机矢量的左侧,正值表示节点在右侧,零表示节点在正前方。

如果你愿意,你可以很方便地使用这个角度来实际执行旋转。只需将相机角度增加到节点角度的一部分即可。

例如

cameraRotation += a * 0.1

注意事项:

  • “向前”或“向上”不一定与您的内部坐标系相同。通常 0 位于右侧,因此如果您想显示箭头或其他 UI,您可能需要从角度添加或减去一个量(通常为 -(π/2) 以旋转四分之一圈)。
  • 角度始终只在 -π 和 +π 之间。如果节点恰好落在相机的正后方(正好 180 度),您将得到 -π 或 +π,并且当节点越过此不连续性时,您可能会看到这两个极端之间的角度跳跃。你有时会在游戏中看到这种副作用,导航箭头会指向一个目标,然后突然弹到屏幕的另一侧。有多种方法可以处理这个问题。一种简单的方法是对角度使用低通滤波器(即随着时间的推移累积多个样本)。

【讨论】:

【解决方案2】:

使用 projectPoint 函数有一种更简单的方法,可以在视图中将图像显示为 2d 元素,并根据它的位置定位用户应该查看的位置

func getIfHeIsLookingNew(sceneWidth: CGFloat, nodePosition: SCNVector3){
    if(nodePosition.z < 1){
        if(nodePosition.x > (Float(sceneWidth))){
            print("Look Right")
        }else if(nodePosition.x < 0){
            print("Look Left")
        }else{
            print("Correct")
            return
        }
    }else if(nodePosition.x < 0){
        print("Look Right")
    }else{
        print("Look Left")
    }
}

然后像下面这样使用它

let sceneWidth:CGFloat = self.sceneView.frame.width

getIfHeIsLookingNew(sceneWidth: sceneWidth, nodePosition: self.sceneView.projectPoint(targetNode.position))

【讨论】:

  • 它总是向我显示一个静态方向例如,一旦显示正确,它总是显示正确,如果离开则总是离开。我的实现有问题吗?希望你能帮我回答这个问题stackoverflow.com/questions/59501725/…
猜你喜欢
  • 1970-01-01
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-15
相关资源
最近更新 更多