klren0312 / daliy_knowledge

知识积累,正确使用方式是watch
21 stars 4 forks source link

cesium通过轨道六根数 绘制轨道和卫星 #827

Open klren0312 opened 4 months ago

klren0312 commented 4 months ago
<!DOCTYPE html>
<html>
<head>
  <script src="https://cesium.com/downloads/cesiumjs/releases/1.81/Build/Cesium/Cesium.js"></script>
  <link href="https://cesium.com/downloads/cesiumjs/releases/1.81/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
  <style>
    html,
    body {
      overflow: hidden;
      margin: 0px;
      padding: 0px;
      height: 100%;
      font-family: helvetica, arial, sans-serif;
    }
    #cesiumContainer {
      height: 100%;
    }
    #loading {
      width: 100%;
      height: 100%;
      background: #000;
      opacity: 0.8;
      position: fixed;
      top:0;
      left: 0;
      z-index: 1;
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: opacity 0.5s, visibility 0.5s;
      visibility: visible;
    }
    .disappear {
      opacity: 0!important;
      visibility: hidden!important;
    }
  </style>
</head>
<body>
    <div id="cesiumContainer"></div>

    <script>
        // 初始化Cesium viewer
        const viewer = new Cesium.Viewer('cesiumContainer', {
          imageryProvider: new Cesium.TileMapServiceImageryProvider({
            url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"),
          }),
          baseLayerPicker: false,
          geocoder: false,
          homeButton: false,
          infoBox: false,
          skyBox: false,
          navigationHelpButton: false,
          sceneModePicker: true
        });
        viewer.scene.globe.enableLighting = false;

        // 添加卫星轨道
        /**
         * 添加卫星轨道
         * @param {number} semiMajorAxis 轨道半长轴
         * @param {number} eccentricity 轨道离心率
         * @param {number} inclination 轨道倾角
         * @param {number} rightAscensionOfAscendingNode 右上升角
         * @param {number} argumentOfPeriapsis 近地点角距
         * @param {number} trueAnomaly 平近点角
         */
        function addSatelliteOrbit(semiMajorAxis, eccentricity, inclination, rightAscensionOfAscendingNode, argumentOfPeriapsis, trueAnomaly) {
          // 转换角度为弧度,因为Cesium使用的是弧度
          const inclinationRadians = Cesium.Math.toRadians(inclination); // 轨道倾角
          const rightAscensionRadians = Cesium.Math.toRadians(rightAscensionOfAscendingNode); // 右上升弧度
          const argumentOfPeriapsisRadians = Cesium.Math.toRadians(argumentOfPeriapsis); // 近地点角距
          const trueAnomalyRadians = Cesium.Math.toRadians(trueAnomaly); // 平近点角

          // 计算轨道位置
          const orbitPositions = [];
          for (let angle = 0; angle <= 360; angle++) {
            const angleRadians = Cesium.Math.toRadians(angle);
            // 使用开普勒方程计算卫星在轨道上的位置
            const position = calcPosition(semiMajorAxis, eccentricity, inclinationRadians, rightAscensionRadians, argumentOfPeriapsisRadians, angleRadians)
            orbitPositions.push(position);
          }

          // 添加实体以表示轨道
          viewer.entities.add({
            name: '轨道',
            polyline: {
              positions: orbitPositions,
              width: 1,
              material: Cesium.Color.BLUE, // 这里可以设置不同的颜色或材质
              loop: true // 闭合线条以创建完整轨道
            }
          })

          const satPosition = calcPosition(semiMajorAxis, eccentricity, inclinationRadians, rightAscensionRadians, argumentOfPeriapsisRadians, trueAnomalyRadians)
          // 添加卫星
          viewer.entities.add({
            position: satPosition,
            point: {
              color: Cesium.Color.BLUE,
              pixelSize: 10
            }
          })
        }

        // 使用典型的轨道参数调用函数
        addSatelliteOrbit(
          9191938.8176,
          0.240003257127,
          12.9991616499449228,
          306.07479915827,
          314.207519370549,
          0
        )

        addSatelliteOrbit(
          10201266.78664729,
          0.010042891779282947,
          0.9991369213719866,
          10.076989514269,
          11.62407046,
          0,
        )

        /**
         * 根据轨道六根数计算坐标
         * @param {number} semiMajorAxis 轨道半长轴
         * @param {number} eccentricity 轨道离心率
         * @param {number} inclination 轨道倾角
         * @param {number} rightAscensionOfAscendingNode 右上升角
         * @param {number} argumentOfPeriapsis 近地点角距
         * @param {number} trueAnomaly 平近点角
         */
        function calcPosition (semiMajorAxis, eccentricity, inclinationRadians, rightAscensionRadians, argumentOfPeriapsisRadians, trueAnomalyRadians) {
          const p = semiMajorAxis * (1 - eccentricity * eccentricity) // 焦点参数
          const r = p / (1 + eccentricity * Math.cos(trueAnomalyRadians)) // 根据真近点角计算卫星到中心体的距离
          const positionInOrbitalPlane = new Cesium.Cartesian3(
            r * Math.cos(trueAnomalyRadians),
            r * Math.sin(trueAnomalyRadians),
            0
          )

          let rotationMatrix = new Cesium.Matrix3()
          rotationMatrix = Cesium.Matrix3.multiply(Cesium.Matrix3.fromRotationZ(rightAscensionRadians), Cesium.Matrix3.fromRotationX(inclinationRadians), rotationMatrix)
          rotationMatrix = Cesium.Matrix3.multiply(rotationMatrix, Cesium.Matrix3.fromRotationZ(argumentOfPeriapsisRadians), rotationMatrix)
          const position = Cesium.Matrix3.multiplyByVector(rotationMatrix, positionInOrbitalPlane, new Cesium.Cartesian3())
          return position
        }
    </script>
</body>
</html>
klren0312 commented 1 month ago

image