45

I've got the following information:

There exists a sphere with origin (0,0,0) and radius R. After doing a ray-sphere intersection I know a point (XYZ) in 3D space that is on the sphere (the exact position in 3D space where the line pierces the sphere hull).

For my program I'd like to calculate the Latitude and Longitude of the XYZ point on the sphere, but I can't think (or Google) up a way to do this easily.

So in short, the function that I'm trying to write is this:

public static LatLon FromVector3(Vector3 position, float sphereRadius)
{
    return Latitude and Longitude
}

Does anybody know how to do this? As a reference this Wiki SVG file might be helpful:

Geographic coordinates

Update:

Thanks for all the helpful answers, so in the end I went with this code:

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

Now I've got to think of which answer helped me the most to accept :P.

PKCLsoft
  • 1,359
  • 2
  • 26
  • 35
Roy T.
  • 9,429
  • 2
  • 48
  • 70
  • what coordinates are you using?? use spherical polar coordinates than x,y,z – S L Apr 15 '11 at 08:27
  • The XYZ coordinates I mentioned, are just plain 3D coordinates and have no relation to spherical coordinates whatsoever: http://ecommprojects.com/seo/Ahmed-Zewails-4d-Telescope/xyz-coordinates.png – Roy T. Apr 15 '11 at 08:29
  • 2
    I found that to get the lat/long to have the correct sign using SceneKit, I needed: float latitude = -((float)acosf(result.localCoordinates.y / sphereRadius) - M_PI_2); //theta float longitude = M_PI - ((float)atan2f(result.localCoordinates.z, result.localCoordinates.x));/ //phi if (longitude > M_PI) { longitude = longitude - (2.0 * M_PI); } – PKCLsoft Aug 01 '16 at 14:11

7 Answers7

38

I guess it should not be difficult to find the spherical polar coordinates from x,y,z (3d-coordinate system).

  1. r is always constant if it's on surface.

    enter image description here

  2. (90 - θ) your latitude (negative means it's on the bottom) as it's measured from top.

    enter image description here

  3. φ is your longitude. (but not quite sure about longitude system)

    enter image description here

Also check this diagram from wikipedia.

enter image description here

Community
  • 1
  • 1
S L
  • 14,262
  • 17
  • 77
  • 116
  • Wow, thanks for the neatly layouted answer, I'll test this right now. And if everything works out I'll accept it in a bit :). – Roy T. Apr 15 '11 at 08:37
  • 1
    I'm getting very strange results with these formula, so I'm afraid this doesn't seem to be the solution. – Roy T. Apr 15 '11 at 09:05
  • 1
    nvm, you are correct. I didnt look at your picture, you use Z = up, I used Y = up. Also you swapped lat and lon. – Roy T. Apr 15 '11 at 10:16
13
lat=atan2(z,sqrt(x*x+y*y))
lng=atan2(y,x)

Using formulas with atan2() is more convenient. You don't have to add/subtract pi/2 or care about sign issues in different quadrants or division by zero.

lat will be >0 in the northern hemisphere
lat will be <0 in the southern hemisphere
lng will be >0 in the eastern hemisphere
lng will be <0 in the western hemisphere

Curd
  • 12,169
  • 3
  • 35
  • 49
  • Your latitude seems to work, but your longitude is very erratic – Roy T. Apr 15 '11 at 09:23
  • @Roy T.: probably depends on the definition which one of the two axis is x- and -y. Try it with x- and y-axis exchanged (You didn't specify the coordinate system exactly). – Curd Apr 19 '11 at 15:59
11

This helped using Javascript/THREE.js:

var lat = 90 - (Math.acos(y / RADIUS_SPHERE)) * 180 / Math.PI;
var lon = ((270 + (Math.atan2(x , z)) * 180 / Math.PI) % 360) -180;
Torsten Becker
  • 4,330
  • 2
  • 21
  • 22
0

After working on getting a straightforward solution to placing objects on a sphere using lat/lng, I came up with a simple class to let you do it using three.js.

var earth = new THREE.GeoSpatialMap(geometry, material);
earth.setTexturesEdgeLongitude(-180.806168);

for (i = 0; i < continentData.length; i += step) {

    var lat = continentData[i];
    var lng = continentData[i + 1];

    var light = new THREE.PointLight(0x0099ff);
    var plant = new org.good.ecology.Plant();
    plant.scale.x = plant.scale.y = plant.scale.z = Math.random() * 3;

    console.log("Adding symbol at: " + lat + " : " + lng);
    earth.addGeoSymbol(
        new THREE.GeoSpatialMap.GeoSymbol(plant, {
            phi: lat,
            lambda: lng
        })
    );


    plant.lookAt(earth.position);

}

https://github.com/scottbyrns/Three.js-Geospatial-Mapping

Brad Koch
  • 19,267
  • 19
  • 110
  • 137
user1976945
  • 41
  • 1
  • 3
0
r=sqrt(x^2+y^2+z^2)  
phi = arccos(sqrt(x^2+y^2)/r)*sign(y)  
lambda = arccos(x/sqrt(x^2+y^2))  
latitude = 180/pi * phi  
longitude = 180/pi * lambda 

you might have to tinker with the signs a little

titus
  • 5,512
  • 7
  • 25
  • 39
0

This is back-of-envelope work but:

Lat = arctan(z/(sqrt(x^2+y^2)))

Long = arccos(sqrt(x^2+y^2)/x)
Brad Koch
  • 19,267
  • 19
  • 110
  • 137
shieldfoss
  • 886
  • 2
  • 12
  • 22
0

Edit - having reread you question my answer isn't necessarily applicable, but I'll leave it up for reference.

It depends how accurate you wan to be an dwhat purpose you are going to use the result for. There is no single latitude and logitude system, eg WGS84 (USA GPS) or ETRS89 (European GPS) differ slightly and are diverging as the Atlantic Ocean widens.

http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/guide5.html

http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/guide6.html

Finally this should address your question directly.

http://www.ordnancesurvey.co.uk/oswebsite/gps/information/coordinatesystemsinfo/guidecontents/guideb.html

or

http://www.ordnancesurvey.co.uk/oswebsite/gps/docs/convertingcoordinates3D.pdf

Jaydee
  • 4,138
  • 1
  • 19
  • 20
  • 1
    I'm using this a spherical coordinates for a perfect sphere (in a game) so I don't have to use real-world complexities :) – Roy T. Apr 15 '11 at 09:10
  • I realised that after posting, I really should read the question properly sounding off. I've done a fair bit of this in the past so I see lat/long and start pontificating. – Jaydee Apr 15 '11 at 09:16