如何在ThreeJS中点击球体获取地理经纬度坐标?
在ThreeJS球体上获取地理坐标的实现方法
可以实现,核心是将点击得到的3D空间点转换为地理经纬度坐标,以下是具体实现步骤和代码修改:
关键原理
ThreeJS中SphereGeometry的默认坐标系为Y轴向上,需将点击点的世界坐标转换为地球模型的局部坐标,再通过三角函数计算经纬度:
- 经度(Longitude):对应绕Y轴的旋转角度,由点的X、Z坐标计算
- 纬度(Latitude):对应点与Y轴的夹角,由点的Y坐标和地球半径计算
代码修改
修改Earth类中的onClick方法,加入经纬度转换逻辑:
onClick(event) { event.preventDefault(); let canvas = this.renderer.domElement; let vector = new THREE.Vector3( ((event.offsetX) / canvas.width) * 2 - 1, -((event.offsetY) / canvas.height) * 2 + 1, 0.5 ); vector.unproject(this.camera); this.raycaster.set(this.camera.position, vector.sub(this.camera.position).normalize()); // 仅检测地球模型的子物体,避免误判其他场景对象 let intersects = this.raycaster.intersectObjects(this.obj.children); if (intersects.length > 0) { const worldPoint = intersects[0].point; // 将世界坐标转换为地球局部坐标(消除地球旋转的影响) const localPoint = this.obj.worldToLocal(worldPoint.clone()); const radius = this.radius; // 计算经度:atan2(x, z) 得到弧度,转换为度数,调整0度对应本初子午线 let longitude = THREE.Math.radToDeg(Math.atan2(localPoint.x, localPoint.z)); // 可选:将经度范围转为-180到180度 if (longitude < 0) longitude += 360; // 计算纬度:asin(y / radius) 得到弧度,转换为度数 let latitude = THREE.Math.radToDeg(Math.asin(localPoint.y / radius)); console.log(`经度: ${longitude.toFixed(2)}°`); console.log(`纬度: ${latitude.toFixed(2)}°`); } }
额外优化建议
- 移除重复的ThreeJS引入:HTML中同时引入了
three.min.js和three.js,保留其中一个即可(建议选压缩版three.min.js) - 优化渲染循环:将
setPixelRatio和setSize移到窗口resize事件中,避免重复执行:
function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); } window.addEventListener('resize', onWindowResize);
- 旋转状态下的坐标准确性:如果开启
earthRotate,worldToLocal方法会自动处理旋转后的坐标转换,无需额外调整
内容的提问来源于stack exchange,提问作者Kiwi
相关产品推荐
相关产品推荐

