[英]cesium.js The cone changes with the heading, pitch, and roll of the satellite model, and the vertex position of the cone remains unchanged
我想用一个圆锥体来表示卫星模型的正射影像。圆锥体随着卫星模型的航向、俯仰和滚转而变化,圆锥体的顶点位置保持不变。 效果类似于http://cesium.marsgis.cn/cesium-example/editor.html#27_space_satellite 。
这是我根据自己的需要写的一种求锥矩阵的方法。 当我只改变pitch值时,可以正确绘制圆锥体,当同时改变pitch和roll时,圆锥体顶点会发生变化。 我知道它需要通过偏移量计算,但我不知道如何计算任何滚动值的正确偏移量?
computedModelMatrix(position,attitude,length){
//position Represents the latitude, longitude and altitude of the satellite, attitude represents
//the heading of the satellite, pitch, roll, length represents the length of the cone
let oldZ = length/2;
let oldLongitude=position.longitude;
let oldLatitude=position.latitude;
let roll=attitude.roll;
let pitch=attitude.pitch;
let headingRadians=Cesium.Math.toRadians(roll);
let rollRadians=Cesium.Math.toRadians(roll);
let pitchRadians=Cesium.Math.toRadians(pitch);
let newLongitude:number,newLatitude:number,newAltitude: number;
let L=oldZ/Math.cos(rollRadians)/Math.cos(pitchRadians);
let deg=Math.acos(oldZ/L);
let distance =oldZ*Math.tan(deg);
let x=(oldZ*Math.tan(pitch));
let y=(oldZ*Math.tan(roll));
let angle;
if (roll>=0&&pitch>=0){
//夹角在0-90度
if (pitch==0&&roll==0){
angle=0;
} else if (pitch==0){
angle=0
} else if (roll==0){
angle=90;
}else{
angle =Math.atan(x/y);
}
}
else if (pitch>0&&roll<0) {
angle =Math.atan(y/x)+90;
}
else if (pitch<0&&roll<0){
angle=Math.atan(x/y)+180;
}
else{
angle=Math.atan(y/x)+270;
}
newAltitude=oldZ;
//Find the longitude and latitude of another point by angle and distance
let resultPisiotion =GetPosition.computerThatLonLat(oldLongitude,oldLatitude,angle,distance);
newLongitude=resultPisiotion.lon;
newLatitude=resultPisiotion.lat;
let centerOnEllipsoid = Cesium.Cartesian3.fromDegrees(newLongitude, newLatitude, newAltitude);
let hpr = new Cesium.HeadingPitchRoll(headingRadians,pitchRadians, rollRadians);
let result ={
modelMatrix:Cesium.Transforms.headingPitchRollToFixedFrame(centerOnEllipsoid, hpr),
length:2*L
};
return result;
}
computedModelMatrix(Cartesian3: any, attitude: any, length: any) {
//锥体距离卫星的高度
let oldLength = length / 2;
let centerCartesian3 = new Cesium.Cartesian3(Cartesian3.x, Cartesian3.y, Cartesian3.z);
let oldX = 0, oldY = 0, oldZ = -oldLength, newX = 0, newY = 0, newZ = 0;
let heading = attitude.heading;
//规定顺时针为正旋转,正东方向为0度
if (heading < 0) {
heading = heading + 360;
}
let roll = attitude.roll;
let pitch = attitude.pitch;
let headingRadians = Cesium.Math.toRadians(heading);
let pitchRadians = Cesium.Math.toRadians(pitch);
let rollRadians = Cesium.Math.toRadians(roll);
let hpr = new Cesium.HeadingPitchRoll(headingRadians, pitchRadians, rollRadians);
let orientation = Cesium.Transforms.headingPitchRollQuaternion(centerCartesian3, hpr);
//旋转roll
newY = oldY + oldLength * Math.sin(rollRadians);
newZ = oldZ + oldLength - oldLength * Math.cos(rollRadians);
let pitchTouying = oldLength * Math.cos(rollRadians);//进行pitch变化时在Y轴和Z轴组成的平面的投影
//旋转pitch
newX = oldX + pitchTouying * Math.sin(pitchRadians);
newZ = newZ + (pitchTouying - pitchTouying * Math.cos(pitchRadians));
if (heading != 0) {
let headingTouying = Math.sqrt(Math.pow(Math.abs(newX), 2) + Math.pow(Math.abs(newY), 2));//进行heading变化时在Y轴和X轴组成的平面的投影
//旋转heading
let Xdeg = Cesium.Math.toDegrees(Math.acos(Math.abs(newX) / Math.abs(headingTouying)));//现有投影线与X轴的夹角
let newXdeg = 0;//旋转heading后与X轴的夹角
let newXRadians = 0;//旋转heading后与X轴的夹角弧度
if (newX >= 0 && newY >= 0) {
newXdeg = heading - Xdeg;
} else if (newX > 0 && newY < 0) {
newXdeg = heading + Xdeg;
} else if (newX < 0 && newY > 0) {
newXdeg = heading + (180 + Xdeg);
} else {
newXdeg = heading + (180 - Xdeg)
}
if (newXdeg >= 360) {
newXdeg = 360 - newXdeg;
}
if (newXdeg >= 0 && newXdeg <= 90) {
newXRadians = Cesium.Math.toRadians(newXdeg);
newY = -headingTouying * Math.sin(newXRadians);
newX = headingTouying * Math.cos(newXRadians);
} else if (newXdeg > 90 && newXdeg <= 180) {
newXRadians = Cesium.Math.toRadians(180 - newXdeg);
newY = -headingTouying * Math.sin(newXRadians);
newX = -headingTouying * Math.cos(newXRadians)
} else if (newXdeg > 180 && newXdeg <= 270) {
newXRadians = Cesium.Math.toRadians(newXdeg - 180);
newY = headingTouying * Math.sin(newXRadians);
newX = -(headingTouying * Math.cos(newXRadians))
} else {
newXRadians = Cesium.Math.toRadians(360 - newXdeg);
newY = headingTouying * Math.sin(newXRadians);
newX = headingTouying * Math.cos(newXRadians)
}
}
let offset = new Cesium.Cartesian3(newX, newY, newZ);
let newPosition = this.computeOffset(centerCartesian3, offset);
return Cesium.Matrix4.fromTranslationQuaternionRotationScale(newPosition, orientation, new Cesium.Cartesian3(1, 1, 1))
}
computeOffset(Cartesian3: any, offset: any) {
let enuTransform = Cesium.Transforms.eastNorthUpToFixedFrame(Cartesian3);
Cesium.Matrix4.multiplyByPointAsVector(enuTransform, offset, offset);
return Cesium.Cartesian3.add(Cartesian3, offset, new Cesium.Cartesian3());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.