奇技指南 本文做者高峰,360奇舞团前端工程师,W3C性能工做组/WOT工做组成员 本文转载自奇舞周刊前端
在实现3D地球时,球面是经过地理贴图渲染的。因此咱们所说的地理坐标和三维空间坐标的转换,是指将地理贴图上的坐标,转换为球面坐标(https://en.wikipedia.org/wiki/Spherical_coordinate_system),即three.js中的三维坐标。git
在介绍他们之间如何转换以前,咱们先来了解下这两种坐标。算法
一个完整的地理贴图坐标 (https://zh.wikipedia.org/wiki/%E5%9C%B0%E7%90%86%E5%9D%90%E6%A0%87%E7%B3%BB)以下,其中第一张为简图,可以帮咱们快速理解经纬度与地理坐标,第二张为详细经纬度分布图。微信
能够看出贴图横向表示经度,范围[-180(西经),180(东经)],竖向表示纬度[-90(南纬), 90(北纬)],所以坐标转化就成了经纬度到球面坐标的转化。前端工程师
在three.js中,建立球体时有如下几个重要参数:函数
其中phiStart的默认值0,起始点为x轴负方向。thetaStart的默认值也为0,起始点为z轴正方向。以下图所示:性能
如上图,其中phi的值为0-Math.PI*2,对应的经度范围为-180到180,因此与经度对应的phi应为180+lng(lng为经度longitude)。theta的值为0-Math.PI,对应的纬度为90到-90,因此与纬度对应的theta值应为90-lat(lat为纬度latitude)。code
基于上述得出的经纬度和球体建立时角度的对应关系,结合三角函数,咱们应该能够很方便地算出对应的三维坐标,以下:blog
y = r * cos(theta) z = r * sin(theta) * sin(phi)
以下转换为JS代码:three
const phi = (180 + lng) * (Math.PI / 180) const theta = (90 - lat) * (Math.PI / 180) return { x: -radius * Math.sin(theta) * Math.cos(phi), y: radius * Math.cos(theta), z: radius * Math.sin(theta) * Math.sin(phi), } }
除了上述直接用三角函数来算之外,咱们也能够经过Three.js
中的提供的方式来计算。主要涉及THREE.Spherical
和THREE.Vector3
THREE.Spherical是three.js中的球面坐标类,用法以下:
能够看出,这里的球面坐标类与咱们在定义球时所用的球面坐标中的角是有区别的。phi和theta与上面偏偏相反。对应关系分别为(加’的为此处的角度):
THREE.Vector3
用于表示三维向量,它有一个setFromSpherical
的方法,顾名思义,表示能够从球面坐标获得三维向量坐标。其实,three.js
中能够能够实现球面坐标和三维坐标的相互转换,THREE.Spherical
也存在相似的setFromVector3
方法。 综上,经过three.js自带的方法来转换经纬度时能够用如下方法:
const theta = (90 + lng) * (Math.PI / 180) const phi = (90 - lat) * (Math.PI / 180) return (new THREE.Vector3()).setFromSpherical(new THREE.Spherical(radius, phi, theta)) },
关于360技术 360技术是360技术团队打造的技术分享公众号,天天推送技术干货内容 更多技术信息欢迎关注“360技术”微信公众号