在 Three.js 中将经度和纬度转换为 xyz(为了旋转相机)的问题

Posted

技术标签:

【中文标题】在 Three.js 中将经度和纬度转换为 xyz(为了旋转相机)的问题【英文标题】:Problems converting longitude and latitude to xyz (in order to rotate a camera) in Three.js 【发布时间】:2012-07-02 15:59:45 【问题描述】:

我正在开发一个 javascript 应用程序,可以在其中设计自己的壁橱。我希望可以平滑地旋转壁橱(不改变相机到壁橱的距离)。通常旋转对象本身是最容易的,但考虑到不同的网格具有不同的原点(它们的相对 (0,0) 点与全局 (0,0) 点不同),这不是一个选项。相反,我想我必须像在球体上一样围绕壁橱旋转相机。所以我想做的是根据任何经度和纬度(用户输入)计算相机需要的确切位置。结果,旋转真的很奇怪。当前状态的应用程序是here(重要:不适用于IE,但将来会有一个插件)。相关代码如下。注意:我在网上找到了这些公式。我自己做了几次数学运算,每次都能确认公式。我唯一可以确定的是到偏移点(xOffset,yOffset,zOffset)的距离(半径)是恒定的,但整个事情只是非常奇怪地旋转。我发现了另一个类似here 的问题。我尝试用他们的公式替换我的公式(即使它们没有意义,尽管它们似乎对他们有用)但这根本没有帮助(旋转仍然很奇怪,半径甚至不再看起来恒定)。

伪:

x = xOffset + radius * cos(longitude) * cos(latitude)
y = yOffset + radius * cos(longitude) * sin(latitude)
z = zOffset + radius * sin(longitude)
camera.lookAt(xOffset, yOffset, zOffset)

相关代码(注:度数转换为弧度):

var lon = 30;
var lat = -90;
var cameraRadius = 400;

function cameraReposition()    
var lon = dimensions.lon;
var lat = dimensions.lat;
camera.position.x = cameraX + cameraRadius * Math.cos(Math.PI * lon / 180) * Math.cos(Math.PI * lat / 180);
camera.position.y = cameraY + cameraRadius * Math.cos(Math.PI * lon / 180) * Math.sin(Math.PI * lat / 180);
camera.position.z = cameraZ + cameraRadius * Math.sin(Math.PI * lon / 180); 
camera.lookAt(new THREE.Vector3(cameraX, cameraY, cameraZ));



$('#visiblecanvas').mousemove(function(e)
    if(mousedown || rightMousedown) 
        var clickX = e.pageX - this.offsetLeft;    
        var clickY = e.pageY - this.offsetLeft;
        lon += (clickY - lastY) / 10;
        lat -= (clickX - lastX) / 10;
        lastY = clickY;
        lastX = clickX;
        if (lon > 360)
            lon -= 360;
        if (lon < -360)
            lon += 360;
        if (lat > 360)
            lat -= 180;
        if (lat < -360)
            lat += 360;
    
);

另一个注意事项:当 lon 和 lat 超过 360 度时改变的方式现在不是很相关,因为 lon 和 lat 目前都是通过 gui 控制的(用于调试目的)。

编辑:应用程序链接错误!固定。

【问题讨论】:

【参考方案1】:
    latLongToVector3: function(lat, lon, radius, heigth) 
      var phi = (lat)*Math.PI/180;
      var theta = (lon-180)*Math.PI/180;

      var x = -(radius+heigth) * Math.cos(phi) * Math.cos(theta);
      var y = (radius+heigth) * Math.sin(phi);
      var z = (radius+heigth) * Math.cos(phi) * Math.sin(theta);

      return new THREE.Vector3(x,y,z);
    

【讨论】:

请在答案中添加一些描述。 这个答案来自here。请注意拼写错误heigth 出现在两者中。【参考方案2】:

在我看来,摄像机的位置还可以,至少当纬度或经度发生变化时,它遵循正确的轨迹,而另一个保持不变。看起来奇怪的是相机的方向——lookAt 没有指定“向上”在哪里,所以它可以选择任何方向,例如你最终可能会看到正确的点,但颠倒了。

我自己没有尝试过 Three.js,但在文档中我没有看到将附加信息提供给相机的方法。您可能需要手动设置 projectionMatrix 及其逆矩阵。

【讨论】:

我只是添加了camera.rotation.z = 0;。这解决了你提到的问题,但我仍然很确定定位也坏了.. Woops.. 事实证明,在所有的实验之后,我没有正确的公式了,所以事实证明你的解决方案确实有效,只是我还不知道。谢谢!

以上是关于在 Three.js 中将经度和纬度转换为 xyz(为了旋转相机)的问题的主要内容,如果未能解决你的问题,请参考以下文章

在php中将地址转换为纬度和经度

如何在iPhone开发中将地址转换为纬度和经度[重复]

在R中将纬度/经度转换为高度

在java中将地址转换为纬度和经度以获得基于距离的建议

如何在 Java 中将纬度和经度转换为 x,y?

经纬度转换成XYZ坐标