Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Distance and direction of two points on a sphere

Discussion in 'Scripting' started by mquickel, Aug 13, 2017.

  1. mquickel

    mquickel

    Joined:
    Jun 21, 2013
    Posts:
    11
    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!
     
  2. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    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).

    Code (CSharp):
    1.  public Vector2 ToLatLong(Vector3 position, float sphereRadius)
    2. {
    3.      float lat = (float)Mathf.Acos(position.y / sphereRadius); //theta
    4.      float lon = (float)Mathf.Atan(position.x / position.z);
    5.      return new Vector2(lat, lon);
    6. }
    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)
     
  3. mquickel

    mquickel

    Joined:
    Jun 21, 2013
    Posts:
    11
    Thanks for the thoughts on this. My sphere has a scale of 4, so my call looked something like:

    Code (CSharp):
    1. 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.
     
  4. tonemcbride

    tonemcbride

    Joined:
    Sep 7, 2010
    Posts:
    1,077
    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: http://answers.unity3d.com/questions/432068/raydirection-as-euler-angle.html

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

    maxizrin

    Joined:
    Apr 13, 2015
    Posts:
    17
    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;
     
    Kiwasi likes this.