简体   繁体   中英

Objects in a 3d sphere coordinates to 2d

I'm making a 3d compass that tracks camera movements in three.js. Here's an image of the compass

In the image, the pie slice is the FOV of the camera and the small, pink circles are the objects in the scene. The scene is a sphere, and the objects are all along the edges of the sphere. Given the x, y, and z positions of the objects, how do I get the relative positions in a 2d circle? I tried getting the angle: yAngle = Math.atan(xpos / zpos) and then getting the x and y positions on the circle by doing: x = radius * Math.cos(yAngle), y = radius * Math.sin(yAngle) , but that isn't getting the correct positions. I think I can do something with three.js projections?

I would really appreciate some help :)

Consider you have several objects in space, including your camera. If you view the scene from the top-down perspective of your camera, and you're ignoring whether objects are above/below your camera's horizon, then you can consider the object's positions in terms of X/Z (remember your look direction is along the camera's Y axis).

Getting Object Positions In Camera Space

It's relatively simple to get the 3D position of an object relative to another. In this case, you want the position of an object relative to your camera.

// keep this somewhere accessible to your function scope
var tempObjectLocation = new THREE.Vector3();

// later in your code...

tempObjectLocation.copy(yourObject.position);

// only need to do this if your object isn't already in world coordinates
yourObject.parent.localToWorld(tempObjectLocation); 

// put the vector in camera space
camera.worldToLocal(tempObjectLocation);

// tempObjectLocation now contains the object's position in camera space

Getting The Position On The Compass

Now that you have the object's position in camera space, you can either eliminate the Y component, or use it to detect if the object is above/below the camera horizon. In your case:

tempObjectLocation.y = 0;

You now have a vector in X/Z. Let's say its value is {x: 15, y: 0, z: 8} . Let's also say your compass uses a radius of 5 to place the object indicators around the outside edge. Simply set the length of the vector.

tempObjectLocation.setLength(5);
// tempObjectLocation is now {x: 4.411764705882353, y: 0, z: 2.3529411764705883}

The X and Z values now represent the indicator position on your compass, where {x: 0, y: 0, z: 0} is the center of you compass. (You may need to map X/Z => X/Y, or apply other transformations, depending on how you draw your compass.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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