2d与2.5d坐标转换_Three.js 地理坐标和三维空间坐标的转换
奇技指南
本文作者高峰,360奇舞團(tuán)前端工程師,W3C性能工作組/WOT工作組成員
本文轉(zhuǎn)載自奇舞周刊
引言
在實(shí)現(xiàn)3D地球時(shí),球面是通過(guò)地理貼圖渲染的。所以我們所說(shuō)的地理坐標(biāo)和三維空間坐標(biāo)的轉(zhuǎn)換,是指將地理貼圖上的坐標(biāo),轉(zhuǎn)換為球面坐標(biāo)(https://en.wikipedia.org/wiki/Spherical_coordinate_system),即three.js中的三維坐標(biāo)。
在介紹他們之間如何轉(zhuǎn)換之前,我們先來(lái)了解下這兩種坐標(biāo)。
地理坐標(biāo)(貼圖坐標(biāo))
一個(gè)完整的地理貼圖坐標(biāo) (https://zh.wikipedia.org/wiki/%E5%9C%B0%E7%90%86%E5%9D%90%E6%A0%87%E7%B3%BB)如下,其中第一張為簡(jiǎn)圖,能夠幫我們快速理解經(jīng)緯度與地理坐標(biāo),第二張為詳細(xì)經(jīng)緯度分布圖。
可以看出貼圖橫向表示經(jīng)度,范圍[-180(西經(jīng)),180(東經(jīng))],豎向表示緯度[-90(南緯), 90(北緯)],因此坐標(biāo)轉(zhuǎn)化就成了經(jīng)緯度到球面坐標(biāo)的轉(zhuǎn)化。
球面坐標(biāo)
在three.js中,創(chuàng)建球體時(shí)有以下幾個(gè)重要參數(shù):
- 半徑(radius)以及分段數(shù)
- 水平方向起始角度(phiStart)
- 水平方向角度大小(phiLength)
- 垂直方向起始角(thetaStart)
- 垂直方向角度大小(thetaLength)
其中phiStart的默認(rèn)值0,起始點(diǎn)為x軸負(fù)方向。thetaStart的默認(rèn)值也為0,起始點(diǎn)為z軸正方向。如下圖所示:
如上圖,其中phi的值為0-Math.PI*2,對(duì)應(yīng)的經(jīng)度范圍為-180到180,所以與經(jīng)度對(duì)應(yīng)的phi應(yīng)為180+lng(lng為經(jīng)度longitude)。theta的值為0-Math.PI,對(duì)應(yīng)的緯度為90到-90,所以與緯度對(duì)應(yīng)的theta值應(yīng)為90-lat(lat為緯度latitude)。
坐標(biāo)轉(zhuǎn)換
三角函數(shù)計(jì)算法
基于上述得出的經(jīng)緯度和球體創(chuàng)建時(shí)角度的對(duì)應(yīng)關(guān)系,結(jié)合三角函數(shù),我們應(yīng)該可以很方便地算出對(duì)應(yīng)的三維坐標(biāo),如下:
x = - r * sin(theta) * cos(phi)y = r * cos(theta)z = r * sin(theta) * sin(phi)如下轉(zhuǎn)換為JS代碼:
function lglt2xyz(lng, lat, radius) { 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自帶方法
除了上述直接用三角函數(shù)來(lái)算以外,我們也可以通過(guò)Three.js中的提供的方式來(lái)計(jì)算。主要涉及THREE.Spherical和THREE.Vector3
THREE.Spherical
THREE.Spherical是three.js中的球面坐標(biāo)類,用法如下:
var spherical = new THREE.Spherical(radius,phi,theta)
其中的三個(gè)參數(shù)含義分別如下:
- radius:半徑,默認(rèn)為1
- phi: 以y軸正方向?yàn)槠瘘c(diǎn)的垂直方向弧度值,默認(rèn)0
- theta: 以z軸正方向?yàn)槠瘘c(diǎn)的水平方向弧度值,默認(rèn)0
可以看出,這里的球面坐標(biāo)類與我們?cè)诙x球時(shí)所用的球面坐標(biāo)中的角是有區(qū)別的。phi和theta與上面恰恰相反。對(duì)應(yīng)關(guān)系分別為(加’的為此處的角度):
- phi’ = theta = 90 - lat
- theta’ = phi - 90 = 90 + lng
THREE.Vector3
THREE.Vector3用于表示三維向量,它有一個(gè)setFromSpherical的方法,顧名思義,表示可以從球面坐標(biāo)得到三維向量坐標(biāo)。其實(shí),three.js中可以可以實(shí)現(xiàn)球面坐標(biāo)和三維坐標(biāo)的相互轉(zhuǎn)換,THREE.Spherical也存在類似的setFromVector3方法。
綜上,通過(guò)three.js自帶的方法來(lái)轉(zhuǎn)換經(jīng)緯度時(shí)可以用以下方法:
lglt2xyz(lng, lat, radius) { 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))},總結(jié)
以上是生活随笔為你收集整理的2d与2.5d坐标转换_Three.js 地理坐标和三维空间坐标的转换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python中如何调用类_python如
- 下一篇: 进程用户态 上下文切换需要保存哪些_漫话