Cesium座標轉換:根據兩個座標點(座標點a、座標點b)的經緯度,計算a點和b點的角度

  • 計算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);

注:

  1. pitch是圍繞X軸旋轉,也叫做俯仰角
  2. heading(yaw)是圍繞Y軸旋轉,也叫偏航角,(平行於z軸,就是水平旋轉的,其他同理)
  3. roll是圍繞Z軸旋轉,也叫翻滾角

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章