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

我只是一个虾纸丫 提交于 2020-01-13 12:56:13

问题


I have a camera in the center of SceneKit scene at position(0,0,0) I'm rotation the camera around the y-axis to show different parts of the scene.

I want to show arrows at the left/right side of my screen to show in which direction the user has to move to view a target object.

How can I calculate if a ScnNode is positioned at the left of right side of my view direction?

I know:

  • position and rotation of the camera node
  • position of the target node

回答1:


  1. Calculate the vector to the node relative to the camera. Calculate the vector by subtracting the camera position from the node position
  2. Use atan2 to convert the vector into an angle. The Apple docs are bit thin on explanation. There's a tutorial on raywenderlich.com.

E.g.

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

The angle is in radians, and will range between -π and π (-180 to 180 degrees). If the value is negative the node is to the left of the camera vector, positive values mean the node is to the right, and zero means the node is straight ahead.

Conveniently, you can use this angle as-is to actually perform the rotation if you want. Just increment the camera angle by some fraction of the angle to the node.

E.g.

cameraRotation += a * 0.1

Caveats:

  • "Forward" or "Up" is not necessarily going to be the same as your internal coordinate system. Usually 0 is to the right, so if you want to show an arrow or other UI you may need to add or subtract an amount from the angle (usually -(π/2) to rotate a quarter turn).
  • The angle will always only be between -π and +π. If the node happens to fall directly behind the camera (exactly 180 degrees) you will get either -π or +π, and you might see the angle jump between these two extremes as the node cross over this discontinuity. You sometimes see the side effects of this in games where a nav arrow will point to a target then suddenly flick to the opposite side of the screen. There are various ways to handle this. One easy way is to use a low pass filter on the angle (ie accumulate multiple samples over time).



回答2:


There is an easier way with projectPoint funcion witch show the image as 2d element in your view and based on where it is you can locate where the user should look

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

And use it like below

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

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


来源:https://stackoverflow.com/questions/41579755/how-to-determine-if-an-scnnode-is-left-or-right-of-the-view-direction-of-a-camer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!