已知世界坐标系中的两个点p1、p2,求p1和p2的角度。原理是以p1为原点,建立一个enu坐标系,求出在这个相对坐标系中p1到p2的向量,归一化得到单位向量localVector,再通过Math.atan2计算出这个localVector和x轴的夹角,即是p1到p2的夹角。

方法一:先求出p1、p2在相对坐标系中的坐标local1、local2,相减得到向量localVector,归一化得到单位向量。

let localToWorldMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(p1);
let worldToLocalMatrix = Cesium.Matrix4.inverse(localToWorldMatrix, new Cesium.Matrix4());

// 计算 localVector
let local1 = Cesium.Matrix4.multiplyByPoint(
    worldToLocalMatrix,
    p1,
    new Cesium.Cartesian3()
);
let local2 = Cesium.Matrix4.multiplyByPoint(
    worldToLocalMatrix,
    p2,
    new Cesium.Cartesian3()
);
let localVector = Cesium.Cartesian3.subtract(local2, local1, new Cesium.Cartesian3());

// localVector 向量归一化
let direction = Cesium.Cartesian3.normalize(localVector, new Cesium.Cartesian3());
let angleToX = Math.atan2(direction.y, direction.x);
let heading = Cesium.Math.toDegrees(angleToX);

方法二:先用p1、p2在世界坐标系中相减得到世界坐标下的向量worldVector,再用以p1为原点得到的矩阵的逆矩阵,计算出worldVector在相对坐标系下的向量值,归一化得到单位向量。

let localToWorldMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(p1);
let worldToLocalMatrix = Cesium.Matrix4.inverse(localToWorldMatrix, new Cesium.Matrix4());

// 计算 localVector
let worldVector = Cesium.Cartesian3.subtract(p2, p1, new Cesium.Cartesian3());
let localVector = Cesium.Matrix4.multiplyByPointAsVector(worldToLocalMatrix, worldVector, new Cesium.Cartesian3());

// localVector 向量归一化
let direction = Cesium.Cartesian3.normalize(localVector, new Cesium.Cartesian3());
let angleToX = Math.atan2(direction.y, direction.x);
let heading = Cesium.Math.toDegrees(angleToX);

可以看出,两种方法就是计算localVector的方式不同,结果是一致的。

1、红线为以1为原点建立的相对坐标系的x轴正方向。

2、Math.atan2是内置方法

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐