在 Three.js 中将经度和纬度转换为 xyz(以便旋转相机)时出现问题

Problems converting longitude and latitude to xyz (in order to rotate a camera) in Three.js

本文关键字:相机 旋转 问题 xyz js Three 经度 转换 纬度      更新时间:2023-09-26

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

伪:

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 控制的(用于调试目的)。

编辑:指向应用程序的错误链接! 已修复。

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

相机定位对我来说看起来不错,至少当纬度或经度变化时,它会遵循正确的轨迹,而另一个保持不变。看起来奇怪的是相机的方向 - lookAt没有指定"向上"的位置,因此它可以选择任何方向,例如,您可能最终看向正确的点,但颠倒。

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