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

音乐小憩