繁体   English   中英

如何确定 ScnNode 是在 SceneKit 中相机节点的视图方向的左侧还是右侧

[英]How to determine if an ScnNode is left or right of the view direction of a camera node in SceneKit

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

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

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

在此处输入图片说明

我知道:

  • 相机节点的位置和旋转
  • 目标节点的位置
  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 度),您将得到 -π 或 +π,并且当节点越过此不连续点时,您可能会看到这两个极端之间的角度跳跃。 您有时会在导航箭头指向目标然后突然轻弹到屏幕的另一侧的游戏中看到这种副作用。 有多种方法可以处理这个问题。 一种简单的方法是在角度上使用低通滤波器(即随时间累积多个样本)。

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))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM