我有以下信息:
存在一个原点(0,0,0)和半径R的球体。 在进行射线球体交叉后,我知道球体上的3D空间中的点(XYZ)(3D空间中线穿过球体的确切位置)。
对于我的程序,我想计算球体上XYZ点的纬度和经度,但我无法想象(或谷歌)这样做的方法。
简而言之,我正在尝试编写的函数是:
public static LatLon FromVector3(Vector3 position, float sphereRadius)
{
return Latitude and Longitude
}
有人知道怎么做吗?作为参考,这个Wiki SVG文件可能会有所帮助:
更新:
感谢所有有用的答案,所以最后我使用了这段代码:
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);
}
现在我必须考虑哪个答案对我有最大的帮助:P。
答案 0 :(得分:31)
我想从x,y,z(三维坐标系)中找到球面极坐标应该不难。
r
如果在表面上总是不变的。
(90 - θ)您的纬度(负数表示它位于底部)为从顶部测量。
φ 是您的经度。 (但不太确定经度系统)
同时从wikipedia检查此图表。
答案 1 :(得分:9)
lat=atan2(z,sqrt(x*x+y*y))
lng=atan2(y,x)
使用atan2()
的公式更方便。
您不必添加/减去pi / 2或关注不同象限中的符号问题或除以零。
lat
在北半球将> 0
lat
在南半球将<0}
东半球的lng
将> 0
lng
在西半球将<0;
答案 2 :(得分:7)
这有助于使用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;
答案 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
你可能不得不修补一些迹象
答案 4 :(得分:0)
这是背后的工作,但是:
Lat = arctan(z/(sqrt(x^2+y^2)))
Long = arccos(sqrt(x^2+y^2)/x)
答案 5 :(得分:0)
编辑 - 重新阅读您的问题我的答案不一定适用,但我会留下以供参考。
这取决于你想要使用结果的目的是多么准确。没有单一的纬度和逻辑系统,例如WGS84(美国GPS)或ETRS89(欧洲GPS)略有不同,随着大西洋的扩大而发散。
最后,这应该直接解决你的问题。
或
http://www.ordnancesurvey.co.uk/oswebsite/gps/docs/convertingcoordinates3D.pdf
答案 6 :(得分:0)
在努力获得使用lat / lng在球体上放置对象的简单解决方案之后,我想出了一个简单的类,让你可以使用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);
}