Search code examples
unity-game-enginegeometrylatitude-longitude

Vector3 to Latitude Longitude


I am trying to raycast a point on a sphere, and then convert that point to its appropriate latitude and longitude. I came across this question that relates to what I am doing almost exactly on stack exchange

3D coordinates on a sphere to Latitude and Longitude

which uses this function

public static LatLon FromVector3(Vector3 position, float sphereRadius)
    {
        float lat = (float)Math.Acos(position.Y / sphereRadius); //theta
        float lon = (float)Math.Atan(position.X / position.Z); //phi
        return new LatLon(lat, lon);
    }

however, the function is always returning a value somewhere in the range of 0 to 3 for lat and -1 to 1 for longitude.

The program I am using is Unity, does anyone know why I may be getting these incorrect values? I am passing the raycast hit world vector and sphere radius as my parameters and the sphere is centered at world 0,0,0.

Updated Code

public static Vector2 GetLatLonFromVector3 (Vector3 position, float sphereRadius){
        float lat = (float)Mathf.Acos(position.y / sphereRadius); //theta
        float lon = (float)Mathf.Atan2(position.x, position.z); //phi
        lat *= Mathf.Rad2Deg;
        lon *= Mathf.Rad2Deg;
        return new Vector2(lat, lon);
    }

The issue I am now running in to is the values are not being correctly reflected by the quadrant that they are in.


Solution

  • Acos and atan return values in radians, so from -π (-3.1...) to π (3.1...). In order to convert to degrees, divide by π and multiply by 180. Unity even has a useful constant, Mathf.Rad2Deg to make it easy.

    public static LatLon FromVector3(Vector3 position, float sphereRadius)
    {
        float lat = (float)Math.Acos(position.Y / sphereRadius); //theta
        float lon = (float)Math.Atan(position.X / position.Z); //phi
        return new LatLon(lat * Mathf.Rad2Deg, lon * Mathf.Rad2Deg);
    }