計算a點和b點的角度(偏行角:逆時針) function courseAngle(lng_a, lat_a, lng_b, lat_b) { //以a點為原點建立局部坐標系(東方向為x軸,北方向為y軸,垂直於地面為z軸),得到一個局部坐標到世界坐標轉換的變換矩陣 var localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(lng_a, lat_a)); //求世界坐標到局部坐標的變換矩陣 var worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4()); //a點在局部坐標的位置,其實就是局部坐標原點 var localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, new Cesium.Cartesian3.fromDegrees(lng_a, lat_a), new Cesium.Cartesian3()); //B點在以A點為原點的局部的坐標位置 var localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, new Cesium.Cartesian3.fromDegrees(lng_b, lat_b), new Cesium.Cartesian3()); //弧度 var angle = Math.atan2((localPosition_B.y-localPosition_A.y), (localPosition_B.x-localPosition_A.x)) //角度 var theta = angle*(180/Math.PI); if (theta < 0) { theta = theta + 360; } return theta; } 計算a點和b點的角度(俯仰角:逆時針) function coursePitchAngle(lng_a, lat_a, alt_a, lng_b, lat_b, alt_b) { //以a點為原點建立局部坐標系(東方向為x軸,北方向為y軸,垂直於地面為z軸),得到一個局部坐標到世界坐標轉換的變換矩陣 var localToWorld_Matrix = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(lng_a, lat_a, alt_a)); //求世界坐標到局部坐標的變換矩陣 var worldToLocal_Matrix = Cesium.Matrix4.inverse(localToWorld_Matrix, new Cesium.Matrix4()); //a點在局部坐標的位置,其實就是局部坐標原點 var localPosition_A = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, new Cesium.Cartesian3.fromDegrees(lng_a, lat_a, alt_a), new Cesium.Cartesian3()); //B點在以A點為原點的局部的坐標位置 var localPosition_B = Cesium.Matrix4.multiplyByPoint(worldToLocal_Matrix, new Cesium.Cartesian3.fromDegrees(lng_b, lat_b, alt_b), new Cesium.Cartesian3()); //弧度 var angle = Math.atan2((localPosition_B.z-localPosition_A.z), (localPosition_B.x-localPosition_A.x)) //角度 var theta = angle*(180/Math.PI); if (theta < 0) { theta = theta + 360; } return theta; } 實例:根據實時目標運行坐標點計算目標的位置及方位(pathPosition:自定義參數,記錄目標實時運行的坐標點集合) function updateOrientation(targetEntity){ var pathPosition = targetEntity.pathPosition; // 前一個坐標點 var preIndex = 0; if(pathPosition.length > 1){ preIndex = pathPosition.length-2; } var prevPosition = Cesium.Cartesian3.fromDegrees(pathPosition[preIndex][0], pathPosition[preIndex][1], pathPosition[preIndex][2]); // 當前坐標點 var currentIndex = pathPosition.length-1; var currentPosition = Cesium.Cartesian3.fromDegrees(pathPosition[currentIndex][0], pathPosition[currentIndex][1], pathPosition[currentIndex][2]); // 計算a點和b點的角度(偏行角) var angle = courseAngle(pathPosition[preIndex][0], pathPosition[preIndex][1],pathPosition[currentIndex][0], pathPosition[currentIndex][1]); angle = 360 - Number(angle.toFixed(0)); // 計算a點和b點的角度(俯仰角) var pitchAngle = coursePitchAngle(pathPosition[currentIndex][0], pathPosition[currentIndex][1], pathPosition[currentIndex][2], pathPosition[preIndex][0], pathPosition[preIndex][1], pathPosition[preIndex][2]); pitchAngle = Number(pitchAngle.toFixed(0)); if(pitchAngle > 180){ pitchAngle = 360 - pitchAngle; }else{ pitchAngle = 180 + pitchAngle; } // 根據“俯仰角、偏行角、滾轉角”得到目標方位 var gheading = Cesium.Math.toRadians(angle); var gpitch = Cesium.Math.toRadians(pitchAngle); var groll = Cesium.Math.toRadians(0); var hpr = new Cesium.HeadingPitchRoll(gheading, gpitch, groll); var orientation = Cesium.Transforms.headingPitchRollQuaternion(prevPosition, hpr); targetEntity.orientation = orientation; } 根據實體方位計算角度 // 計算四元數 var _angle = targetEntity.orientation.getValue(viewer.clock.currentTime); // 計算旋轉角(弧度) var hpr = Cesium.HeadingPitchRoll.fromQuaternion(_angle); // 得到角度 var heading = Cesium.Math.toDegrees(hpr.heading); var pitch = Cesium.Math.toDegrees(hpr.pitch); var roll = Cesium.Math.toDegrees(hpr.roll); console.log('heading : ' + heading, 'pitch : ' + pitch, 'roll : ' + roll); pitch是圍繞X軸旋轉,也叫做俯仰角 heading(yaw)是圍繞Y軸旋轉,也叫偏航角,(平行於z軸,就是水平旋轉的,其他同理) roll是圍繞Z軸旋轉,也叫翻滾角