我爱模板网 > 建站教程 > 地图,GIS教程 >  Cesium中笛卡尔坐标系详解正文

Cesium中笛卡尔坐标系详解

使用Cesium开发三维GIS应用离不开笛卡尔坐标系,在CesiumJS中定义类型是Cartesian3,这是Cesium的基础数据类型,所有坐标最后均转换成这个类型参与三维渲染,包括屏幕坐标,地理坐标系坐标。那么问题来了,这个笛卡尔坐标系到底是什么?常用的WGS84怎么转换成这个坐标系的?让我们来看看cesium源码一探究竟。

Cartesian3.js里面有个函数fromRadians ,将经纬度转换成Cartesian3,其中经纬度是wgs84转换成弧度的经纬度。
01Cartesian3.fromRadians = function(longitude, latitude, height, ellipsoid, result) {
02    //>>includeStart('debug', pragmas.debug);
03    Check.typeOf.number('longitude', longitude);
04    Check.typeOf.number('latitude', latitude);
05    //>>includeEnd('debug');
06 
07    height = defaultValue(height, 0.0);
08    var radiiSquared = defined(ellipsoid) ? ellipsoid.radiiSquared : wgs84RadiiSquared;
09 
10    var cosLatitude = Math.cos(latitude);
11    scratchN.x = cosLatitude * Math.cos(longitude);
12    scratchN.y = cosLatitude * Math.sin(longitude);
13    scratchN.z = Math.sin(latitude);
14    scratchN = Cartesian3.normalize(scratchN, scratchN);
15 
16    Cartesian3.multiplyComponents(radiiSquared, scratchN, scratchK);
17    var gamma = Math.sqrt(Cartesian3.dot(scratchN, scratchK));
18    scratchK = Cartesian3.divideByScalar(scratchK, gamma, scratchK);
19    scratchN = Cartesian3.multiplyByScalar(scratchN, height, scratchN);
20 
21    if (!defined(result)) {
22        result = new Cartesian3();
23    }
24    return Cartesian3.add(scratchK, scratchN, result);
25};
1、检验经纬度是否符合标准;
1Check.typeOf.number('longitude', longitude);
2Check.typeOf.number('latitude', latitude);
2、如果高度为空赋值默认为0;
1height = defaultValue(height, 0.0);
3、如果坐标系为空默认赋值WGS84坐标系;
1var radiiSquared = defined(ellipsoid) ? ellipsoid.radiiSquared : wgs84RadiiSquared;
4、赋值地球球体半径(假设为1)在xy平面上的投影长度;
cesium假设wgs84坐标系构成地球球体是xy平面的正圆,z轴稍微小一点扁椭球:



如上图所示:x轴垂直纸面向上,wgs84坐标系定义的x,y平面圆是正圆,半径是6378137,xz或者yz的圆是椭圆,z轴的半径是:6356752.3142451793,定义如下:
1var wgs84RadiiSquared = new Cartesian3(6378137.0 * 6378137.0, 6378137.0 * 6378137.0, 6356752.3142451793 * 6356752.3142451793);
2 
3var cosLatitude = Math.cos(latitude);
所以这句话的意思是假设球半径为1,这个半径投影到xy平面上的长度(当然由于这不是标准球,所以球半径不是固定的,但是在这里假设是一个标准球,直到下面第9步骤)。

5、求出对应x轴坐标(假设球半径为1),用上一步求得的投影长度乘以经度的余弦,直接求得对应x轴坐标;



1scratchN.x = cosLatitude * Math.cos(longitude);
6、求出对应y轴坐标(假设球半径为1);
1scratchN.y = cosLatitude * Math.sin(longitude);
7、求出对应z轴坐标(假设球半径为1),以上三步骤构成scratchN向量;
1scratchN.z = Math.sin(latitude);
8、求出scratchN的单位模向量赋值给scratchN本身,这样做的目的是把这个xyz轴数值同比例缩小到一个单位球,便于后面等比例变化;
单位模的含义:
对向量A=[X,Y,Z]求模:


1scratchN = Cartesian3.normalize(scratchN, scratchN);
9、ScratchN同比例放大一定倍数;
x轴放大6378137.0 * 6378137.0倍数, Y轴放大6378137.0 * 6378137.0倍数, Z轴放大6356752.3142451793 * 6356752.3142451793倍数,结果放到scratchK中,scratchN保持不变
1Cartesian3.multiplyComponents(radiiSquared, scratchN, scratchK)
10、求经纬度坐标对应的xyz坐标;


1var gamma = Math.sqrt(Cartesian3.dot(scratchN, scratchK))
该语句执行结果:

1scratchK = Cartesian3.divideByScalar(scratchK, gamma, scratchK);
该语句执行结果:

1var gamma = Math.sqrt(Cartesian3.dot(scratchN, scratchK));
2scratchK = Cartesian3.divideByScalar(scratchK, gamma, scratchK);
回头看到这里的步骤,其实cesium做了两次取模运算,第一次目的是算出经纬度对应的标准球体上面xyz比例,第二次是算出在wgs84坐标系下面进行椭球体拉伸后的xyz比例,最后再用这个拉伸后的比例乘以实际值(以米为单位)算出实际xyz坐标。

11、求高程对应的xyz坐标增量写入scratchN;
1scratchN = Cartesian3.multiplyByScalar(scratchN, height, scratchN)


12、将第十步骤和第十一步骤对应的坐标相加得到最终xyz值。
1return Cartesian3.add(scratchK, scratchN, result)
总结推论:
1)笛卡尔坐标系是米单位;
2)笛卡尔坐标系原点是地球几何中心;
3)xz平面是中央经线和180度经线组成的平面,其中x轴正方向指向的是中央经线,x轴负方向指向180度经线;
4)y轴正方向指向东经90度经线,负方向指向西经90度经线。


部分素材资源来源网站,本站提供免费下载,如有侵权请联系站长马上删除!
上一篇:Cesium修改3dtiles的经纬度和高度偏移量 下一篇:通用的Cesium自动调整倾斜模型高度贴合地形的方法
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
选择头像:
最新评论

猜你喜欢