Cesium方位角测量(仿火星科技)接着之前的通用工具介绍来讲,今天主要介绍方位角测量。仿照火星科技的例子实现,可以连续测量。先上图:
原理首先明白什么是方位角,百度百科介绍:
方位角,又称地平经度(Azimuth angle,缩写为Az),是在平面上量度物体之间的角度差的方法之一。是从某点的指北方向线起,依顺时针方向到目标方向线之间的水平夹角。
从定义中得到几个关键信息:
两个点, 起点和目标点
两点间顺时针的水平夹角
根据上面的信息,想到的方法就是,根据起点建立一个 x东方向,y为北方向的局部坐标系(或者y为东,x为北),计算出目标点在这个坐标系的局部坐标值,然后利用三角函数 arctan计算出夹角(图中角A的值)。
Cesium 中提供了建立局部坐标系的方法
以x为北,y东的局部坐标系
以y为北,x东的局部坐标系
实现核心代码如下:
/** * 计算两个点的方位角度 * @param lng_a * @param lat_a * @param lng_b * @param lat_b * @return {number} */courseAngle(lng_a, lat_a, lng_b, lat_b) { //以a点为原点建立局部坐标系(东方向为y轴,北方向为x轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵 // const localToWorld_Matrix = Cesium.Transforms.northEastDownToFixedFrame( // new Cesium.Cartesian3.fromDegrees(lng_a, lat_a) // ); //以a点为原点建立局部坐标系(东方向为x轴,北方向为y轴,垂直于地面为z轴),得到一个局部坐标到世界坐标转换的变换矩阵 const localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame( new Cesium.Cartesian3.fromDegrees(lng_a, lat_a) ); //求世界坐标到局部坐标的变换矩阵 const worldToLocal_Matrix = Cesium.Matrix4.inverse( localToWorld_Matrix, new Cesium.Matrix4() ); //a点在局部坐标的位置,其实就是局部坐标原点 const localPosition_A = Cesium.Matrix4.multiplyByPoint( worldToLocal_Matrix, new Cesium.Cartesian3.fromDegrees(lng_a, lat_a), new Cesium.Cartesian3() ); //B点在以A点为原点的局部的坐标位置 const localPosition_B = Cesium.Matrix4.multiplyByPoint( worldToLocal_Matrix, new Cesium.Cartesian3.fromDegrees(lng_b, lat_b), new Cesium.Cartesian3() ); //弧度 // const angle = Math.atan2( // localPosition_B.y - localPosition_A.y, // localPosition_B.x - localPosition_A.x // ); //弧度 const angle = Math.atan2( localPosition_B.x - localPosition_A.x, localPosition_B.y - localPosition_A.y ); //角度 let theta = angle * (180 / Math.PI); if (theta < 0) { theta = theta + 360; } return theta;}
我是按照以x轴为东方向,y为北方向为局部坐标系建立的(另一种方向的计算也写了出来,请自行查看)。主要就是弧度计算的时候,是以 △y 为对边 还是以 △x 为对边求来结果。
天不生我李淳罡,剑道万古如长夜
代码 完整代码都放到 github 上,需要的移步Cesium-demo-view
音乐小憩