Distance and direction of two points on a sphere

Hello, I’m struggling, mathematically-speaking, with the correct way to approach this problem. I have two points on a sphere, A and B, where B is the player. When B moves so far from A I need to rotate the camera to match. It seems that I can use Vector3.Angle(a,b) and that will give me the distance between those two points, but this is a float. What I am trying to understand is, I need to essentially rotate the camera sphere to the north 25* and west 30* for example if the player has walked 25* towards the north pole and west 30*. I also tried just getting the angle of each vector separately but I still can’t quite get it. Any pointer at what I can look at? Thanks!

There’s loads of ways to do that kind of thing (spherical co-ordinates etc…) but maybe a simple way would just be to convert your 2 points on the sphere into latitude/longitude values (like on a globe).

 public Vector2 ToLatLong(Vector3 position, float sphereRadius)
{
     float lat = (float)Mathf.Acos(position.y / sphereRadius); //theta
     float lon = (float)Mathf.Atan(position.x / position.z);
     return new Vector2(lat, lon);
}

You can then just find the difference in longitude/latitude between the 2 points and rotate your camera around to match (i.e. rotate 30 degrees on longitude and 20 degrees on latitude)

Thanks for the thoughts on this. My sphere has a scale of 4, so my call looked something like:

var pv = ToLatLong(transform.position, 4.0f);

When I walked the player along the planet I got a value of 1.1 to 2, north pole to south and south back to north went 2 back to 1.1. From east to west until the visible horizon I got 1.6 to - 1.6. and vice versa on the opposite site. Does this seem right?

It seems like this should be simple but I’m finding it anything but. I’ve been Googling and trying different things off and on over the past few days.

Probably worth making sure that your point is relative to the centre of your sphere (e.g. transform.position - mySphereTransform.position). I think the latitude/longitude is probably returned in radians so you could multiply by Mathf.Rad2Deg to get the result in degrees for ease of use.

You could also think of the point on the sphere as a direction vector (from the centre of your sphere pointing outwards). With that vector you could convert it to a set of euler angles (xyz) using this method: Ray.direction as Euler angle - Questions & Answers - Unity Discussions

Your euler angles might make more sense as they would be between 0-360 degrees

Have you considered maybe trying another approach?
This all seems excessive.

I would have a pool of “interest objects” that is kept by the camera.
Camera always looks at the center of your sphere, hovering at whatever distance you need, above the point of center mass (averages of all the position vectors of the interest objects).

So for 2 objects, the camera will hover in between them, half way, unless you add some “weight” consideration to an entry of your interest objects, making one pull more than others.

When certain conditions are met, like A is too far from B, remove A from interest object list, and the camera should center on B.

No need for complicated calculations, or coordinate systems, only 3 points:
A - Average of interest objects’ positions.
B - Center of sphere.
C - Camera position.

C = B + camHeight * (AB).normalized;

1 Like