Three经纬度转世界坐标算法

一、简介

用Three创建三维地球(sphere),将经纬度转换为笛卡尔坐标在球面进行展示。

二、流程

1、SphereGeometry 生成

SphereGeometry的构造函数如下

SphereGeometry(radius : Float, widthSegments : Integer, heightSegments : Integer, phiStart : Float, phiLength : Float, thetaStart : Float, thetaLength : Float)
radius — 球体半径,默认为1。
widthSegments — 水平分段数(沿着经线分段),最小值为3,默认值为8。
heightSegments — 垂直分段数(沿着纬线分段),最小值为2,默认值为6。
phiStart — 指定水平(经线)起始角度,默认值为0。。
phiLength — 指定水平(经线)扫描角度的大小,默认值为 Math.PI * 2。
thetaStart — 指定垂直(纬线)起始角度,默认值为0。
thetaLength — 指定垂直(纬线)扫描角度大小,默认值为 Math.PI。

主要看 phiStart 和 thetaStart,分别是球体横向的起点,与纵向的起点。其中横向的起点是X轴的负半轴,纵向的起点是Y轴正半轴,如图所示,也就是说如果对球体进行贴图,那么贴图的左半边是起点对应的X轴的负半轴,贴图的上边对应的是Y轴的正半轴,知道这一点后就可以对球面进行贴图了

2、球面贴图

贴图用的是墨卡托投影的世界地图

地图贴上去后展示左半边对应的是球体的x轴负半轴,如图所示,此处需要注意本初子午线(即墨卡托零度线)的位置

3、经纬度转世界坐标(笛卡尔坐标)

在计算之前,需要先理解经纬度的含义,如下图所示

经度以子午线为起点,向右转动A(50)度,到达东经50度,然后以赤道为期起点,向上转动B(40)度,到达北纬40度,理解经纬度如何计算之后,就可以开始推导公式了,设球体的半径为 R,R *  sin(B)便可以计算出点位的Y轴坐标。R * cos(B) 将点位投影到ZX轴构成的平面得到点位A1,A1 * COS(A)则可以得到Z轴坐标,A1 * sin(A)则可以得到X轴的坐标。代码如下

function getPosition(longitude, latitude, radius) {
    var lg = THREE.Math.degToRad(longitude);
    var lt = THREE.Math.degToRad(latitude);
    var temp = radius * Math.cos(lt);
    var x = temp * Math.sin(lg);
    var y = radius * Math.sin(lt);
    var z = temp * Math.cos(lg);
    return {
        x: x,
        y: y,
        z: z
    }
}

输入经纬度坐标(50,40),结果如图,可能会有人有疑问,点位实际效果与上面的示例图有着很大的差距,这个问题就需要回看上面的图中特地标出的本初子午线的位置了,算法计算的时候是以Z轴的正半轴为起点计算的,而实际上贴图之后的本初子午线是在X轴的正半轴,之间差了90度,所以在计算之前需要把经度加上90在进行计算。

输入(140,40),输出的结果如图,现在的点位就是正确的点位了

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Three.js 中,你可以使用球体的经纬度换为三维坐标。下面是一个示例代码片段,展示了如何将经纬度换为 Three.js 中的坐标: ```javascript // 创建一个场景 const scene = new THREE.Scene(); // 创建一个相机 const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; // 创建一个渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建一个球体 const geometry = new THREE.SphereGeometry(1, 32, 32); // 半径为1,分段数为32 const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const earth = new THREE.Mesh(geometry, material); scene.add(earth); // 将经纬度换为 Three.js 中的坐标 function latLonToVector3(lat, lon, radius) { const phi = (lat * Math.PI) / 180; const theta = ((lon - 180) * Math.PI) / 180; const x = -(radius * Math.cos(phi) * Math.cos(theta)); const y = radius * Math.sin(phi); const z = radius * Math.cos(phi) * Math.sin(theta); return new THREE.Vector3(x, y, z); } // 设置地球的位置 const lat = 40; // 纬度 const lon = -100; // 经度 const radius = 5; // 球体半径 earth.position.copy(latLonToVector3(lat, lon, radius)); // 动画循环 function animate() { requestAnimationFrame(animate); // 使地球旋 earth.rotation.y += 0.01; // 渲染场景 renderer.render(scene, camera); } // 开始动画循环 animate(); ``` 在这个代码中,我们创建了一个场景、相机和渲染器,并创建了一个球体表示地球。然后,我们定义了一个 `latLonToVector3` 函数,用于将经纬度换为 Three.js 中的坐标。通过调用这个函数并设置地球的位置,我们可以将地球放置在指定的经纬度位置上。在动画循环中,我们让地球旋,并使用渲染器来渲染场景。 你可以根据需要自定义代码,例如改变球体的材质、调整相机位置或调整地球的半径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值