Cesium坐标转换:根据两个坐标点(坐标点a、坐标点b)的经纬度,计算a点和b点的角度

  • 计算a点和b点的角度(偏行角:逆时针) 

/**
 * 计算a点和b点的角度(偏行角)
 * @param lng_a a点经度
 * @param lat_a a点维度
 * @param lng_b b点经度
 * @param lat_b b点维度
 * @returns 角度
 */
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点的角度(俯仰角:逆时针) 

/**
 * 计算a点和b点的角度(俯仰角)
 * @param lng_a a点经度
 * @param lat_a a点维度
 * @param lng_b b点经度
 * @param lat_b b点维度
 * @returns 角度
 */
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;
}

/**
 * 计算a点和b点的角度(俯仰角)
 * @param lng_a a点经度
 * @param lat_a a点维度
 * @param lng_b b点经度
 * @param lat_b b点维度
 * @returns 角度
 */
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));
	//求世界坐标到局部坐标的变换矩阵
	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());

    let distance = Math.sqrt(Math.pow((localPosition_B.x-localPosition_A.x),2)+ Math.pow((localPosition_B.y-localPosition_A.y),2))
	let dz = alt_b - alt_a;
	var angle = 0;
	if(distance != 0){
		angle = Math.tanh(dz/distance);
	}
	var theta = angle*(180/Math.PI);
    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轴旋转,也叫翻滚角

 

 

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值