繁体   English   中英

cesium.js 锥体随着卫星模型的航向、俯仰和滚转而变化,锥体的顶点位置保持不变

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM