Coordonnées 3D sur une sphère à la Latitude et la Longitude
J'ai les informations suivantes:
Il existe une sphère avec l'origine (0,0,0) et le rayon R. Après avoir fait une intersection rayon-sphère, je connais un point (XYZ) dans L'espace 3D qui se trouve sur la sphère (la position exacte dans L'espace 3D où la ligne perce la coque de la sphère).
Pour mon programme, je voudrais calculer la Latitude et la Longitude du point XYZ sur la sphère, mais je ne peux pas penser (ou Google) un moyen de le faire facilement.
Donc, en bref, la fonction que j'essaie de écrire est ceci:
public static LatLon FromVector3(Vector3 position, float sphereRadius)
{
return Latitude and Longitude
}
Quelqu'un sait comment faire cela? Comme référence, ce fichier WIKI SVG peut être utile:
Mise à jour:
Merci pour toutes les réponses utiles, donc à la fin je suis allé avec ce 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);
}
Maintenant, je dois penser à quelle réponse m'a le plus aidé à accepter: P.
7 réponses
Je suppose qu'il ne devrait pas être difficile de trouver les coordonnées polaires sphériques de x,y,z (système de coordonnées 3d).
-
r
est toujours constante si elle est sur la surface. -
(90 - θ) votre latitude (négatif signifie qu'il est sur le bas) comme c'est mesurée à partir du haut.
-
φ est votre longitude. (mais pas tout à fait sûr de la longitude système)
Vérifiez également ce diagramme de wikipedia.
lat=atan2(z,sqrt(x*x+y*y))
lng=atan2(y,x)
L'utilisation de formules avec atan2()
est plus pratique.
Vous n'avez pas à ajouter/soustraire pi/2 ou à vous soucier des problèmes de signes dans différents quadrants ou division par zéro.
lat
sera >0 dans l'hémisphère nordlat
sera lng
sera >0 dans l'hémisphère orientallng
sera
Cela a aidé à utiliser 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;
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
Vous pourriez avoir à bricoler avec les signes un peu
Edit - après avoir relu votre question, ma réponse n'est pas nécessairement applicable, mais je vais la laisser pour référence.
Cela dépend de la précision avec laquelle vous voulez être un objectif pour lequel vous allez utiliser le résultat. Il n'y a pas de système de latitude et de logitude unique, par exemple WGS84 (USA GPS) ou ETRS89 (European GPS) diffèrent légèrement et divergent comme L'Océan Atlantique élargir.
Enfin, cela devrait répondre à votre question directement.
Ou
Http://www.ordnancesurvey.co.uk/oswebsite/gps/docs/convertingcoordinates3D.pdf
Après avoir travaillé sur une solution simple pour placer des objets sur une sphère en utilisant lat/lng, j'ai trouvé une classe simple pour vous permettre de le faire en utilisant trois.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);
}
C'est un travail de retour d'enveloppe mais:
Lat = arctan(z/(sqrt(x^2+y^2)))
Long = arccos(sqrt(x^2+y^2)/x)