Compare commits
	
		
			No commits in common. "2c0b750b87eeada0fee0cf6a8a91ea5bf5760e7a" and "e5dc139a6b3938b1628c7bce36bf7c489826d9c8" have entirely different histories.
		
	
	
		
			2c0b750b87
			...
			e5dc139a6b
		
	
		
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 756 KiB  | 
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@ -2,15 +2,6 @@ export default class ExplosionEffect {
 | 
				
			|||||||
  constructor(viewer, obj) {
 | 
					  constructor(viewer, obj) {
 | 
				
			||||||
    this.viewer = viewer
 | 
					    this.viewer = viewer
 | 
				
			||||||
    this.viewModel = {
 | 
					    this.viewModel = {
 | 
				
			||||||
      // emissionRate: 5,
 | 
					 | 
				
			||||||
      // gravity: 0.0, //设置重力参数
 | 
					 | 
				
			||||||
      // minimumParticleLife: 1,
 | 
					 | 
				
			||||||
      // maximumParticleLife: 6,
 | 
					 | 
				
			||||||
      // minimumSpeed: 1.0, //粒子发射的最小速度
 | 
					 | 
				
			||||||
      // maximumSpeed: 4.0, //粒子发射的最大速度
 | 
					 | 
				
			||||||
      // startScale: 0.0,
 | 
					 | 
				
			||||||
      // endScale: 8.0,
 | 
					 | 
				
			||||||
      // particleSize: 25.0,
 | 
					 | 
				
			||||||
      emissionRate: 5,
 | 
					      emissionRate: 5,
 | 
				
			||||||
      gravity: 0.0, //设置重力参数
 | 
					      gravity: 0.0, //设置重力参数
 | 
				
			||||||
      minimumParticleLife: 1,
 | 
					      minimumParticleLife: 1,
 | 
				
			||||||
@ -19,7 +10,7 @@ export default class ExplosionEffect {
 | 
				
			|||||||
      maximumSpeed: 4.0, //粒子发射的最大速度
 | 
					      maximumSpeed: 4.0, //粒子发射的最大速度
 | 
				
			||||||
      startScale: 0.0,
 | 
					      startScale: 0.0,
 | 
				
			||||||
      endScale: 8.0,
 | 
					      endScale: 8.0,
 | 
				
			||||||
      particleSize: 10.0,
 | 
					      particleSize: 25.0,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.emitterModelMatrix = new Cesium.Matrix4()
 | 
					    this.emitterModelMatrix = new Cesium.Matrix4()
 | 
				
			||||||
    this.translation = new Cesium.Cartesian3()
 | 
					    this.translation = new Cesium.Cartesian3()
 | 
				
			||||||
@ -42,8 +33,7 @@ export default class ExplosionEffect {
 | 
				
			|||||||
    // this.viewer.trackedEntity = this.entity;
 | 
					    // this.viewer.trackedEntity = this.entity;
 | 
				
			||||||
    let particleSystem = this.scene.primitives.add(
 | 
					    let particleSystem = this.scene.primitives.add(
 | 
				
			||||||
      new Cesium.ParticleSystem({
 | 
					      new Cesium.ParticleSystem({
 | 
				
			||||||
        // image: './images/explosion.png', //生成所需粒子的图片路径
 | 
					        image: './images/explosion.png', //生成所需粒子的图片路径
 | 
				
			||||||
        image: './images/fire.png', //生成所需粒子的图片路径
 | 
					 | 
				
			||||||
        //粒子在生命周期开始时的颜色
 | 
					        //粒子在生命周期开始时的颜色
 | 
				
			||||||
        startColor: Cesium.Color.RED.withAlpha(0.7),
 | 
					        startColor: Cesium.Color.RED.withAlpha(0.7),
 | 
				
			||||||
        //粒子在生命周期结束时的颜色
 | 
					        //粒子在生命周期结束时的颜色
 | 
				
			||||||
@ -71,33 +61,14 @@ export default class ExplosionEffect {
 | 
				
			|||||||
        lifetime: 16.0,
 | 
					        lifetime: 16.0,
 | 
				
			||||||
        //设置粒子的大小是否以米或像素为单位
 | 
					        //设置粒子的大小是否以米或像素为单位
 | 
				
			||||||
        sizeInMeters: false,
 | 
					        sizeInMeters: false,
 | 
				
			||||||
        // sizeInMeters: true,
 | 
					 | 
				
			||||||
        //系统的粒子发射器
 | 
					        //系统的粒子发射器
 | 
				
			||||||
        // emitter: new Cesium.CircleEmitter(5.0), //BoxEmitter 盒形发射器,ConeEmitter 锥形发射器,SphereEmitter 球形发射器,CircleEmitter圆形发射器
 | 
					        emitter: new Cesium.CircleEmitter(5.0), //BoxEmitter 盒形发射器,ConeEmitter 锥形发射器,SphereEmitter 球形发射器,CircleEmitter圆形发射器
 | 
				
			||||||
        emitter: new Cesium.CircleEmitter(2.0), //BoxEmitter 盒形发射器,ConeEmitter 锥形发射器,SphereEmitter 球形发射器,CircleEmitter圆形发射器
 | 
					 | 
				
			||||||
        //回调函数,实现各种喷泉、烟雾效果
 | 
					 | 
				
			||||||
        updateCallback: (p, dt) => {
 | 
					 | 
				
			||||||
          return this.applyGravity(p, dt)
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    this.particleSystem = particleSystem
 | 
					    this.particleSystem = particleSystem
 | 
				
			||||||
    this.preUpdateEvent()
 | 
					    this.preUpdateEvent()
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  applyGravity(p, dt) {
 | 
					 | 
				
			||||||
    let gravityScratch = new Cesium.Cartesian3()
 | 
					 | 
				
			||||||
    let position = p.position
 | 
					 | 
				
			||||||
    Cesium.Cartesian3.normalize(position, gravityScratch)
 | 
					 | 
				
			||||||
    Cesium.Cartesian3.fromElements(
 | 
					 | 
				
			||||||
      20 * dt,
 | 
					 | 
				
			||||||
      30 * dt,
 | 
					 | 
				
			||||||
      gravityScratch.y * dt,
 | 
					 | 
				
			||||||
      gravityScratch
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
    p.velocity = Cesium.Cartesian3.add(p.velocity, gravityScratch, p.velocity)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  //场景渲染事件
 | 
					  //场景渲染事件
 | 
				
			||||||
  preUpdateEvent() {
 | 
					  preUpdateEvent() {
 | 
				
			||||||
    let _this = this
 | 
					    let _this = this
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										101
									
								
								src/utils/pos.js
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								src/utils/pos.js
									
									
									
									
									
								
							@ -32,107 +32,6 @@ export function getPositionFromTime(
 | 
				
			|||||||
  return points
 | 
					  return points
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function getOnePositionFromTime(startTime, i, pos) {
 | 
					 | 
				
			||||||
  const time = Cesium.JulianDate.addSeconds(
 | 
					 | 
				
			||||||
    startTime,
 | 
					 | 
				
			||||||
    i,
 | 
					 | 
				
			||||||
    new Cesium.JulianDate()
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
  const point = pos.getValue(time)
 | 
					 | 
				
			||||||
  return point
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function getBezierSpline(points) {
 | 
					export function getBezierSpline(points) {
 | 
				
			||||||
  return bezierSpline(lineString(points))
 | 
					  return bezierSpline(lineString(points))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
export async function test() {
 | 
					 | 
				
			||||||
  const points = createTrajectory(
 | 
					 | 
				
			||||||
    [137, 25, 0, 1183135285000],
 | 
					 | 
				
			||||||
    [140, 27, 100000, 1183135295000]
 | 
					 | 
				
			||||||
  ).map(point => {
 | 
					 | 
				
			||||||
    // const point = getTrajectoryPoint(i)
 | 
					 | 
				
			||||||
    console.log(point)
 | 
					 | 
				
			||||||
    // console.log(
 | 
					 | 
				
			||||||
    //   `t=${point.time}s, lon=${point.longitude.toFixed(
 | 
					 | 
				
			||||||
    //     3
 | 
					 | 
				
			||||||
    //   )}, lat=${point.latitude.toFixed(3)}, alt=${point.altitude.toFixed(2)}m`
 | 
					 | 
				
			||||||
    // )
 | 
					 | 
				
			||||||
    return [point.lon, point.lat, point.alt]
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  // const points = a.map(item => {
 | 
					 | 
				
			||||||
  //   return [item.lon, item.lat, item.alt]
 | 
					 | 
				
			||||||
  // })
 | 
					 | 
				
			||||||
  viewer.entities.add({
 | 
					 | 
				
			||||||
    name: 'line',
 | 
					 | 
				
			||||||
    polyline: {
 | 
					 | 
				
			||||||
      positions: Cesium.Cartesian3.fromDegreesArrayHeights(
 | 
					 | 
				
			||||||
        points.flat(Infinity)
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
      width: 10,
 | 
					 | 
				
			||||||
      material: new Cesium.PolylineGlowMaterialProperty({
 | 
					 | 
				
			||||||
        glowPower: 0.1,
 | 
					 | 
				
			||||||
        color: Cesium.Color.RED,
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export function createTrajectory(p1, p2, options = {}) {
 | 
					 | 
				
			||||||
  const {
 | 
					 | 
				
			||||||
    steps = 20,
 | 
					 | 
				
			||||||
    useStartAsPeak = false,
 | 
					 | 
				
			||||||
    useEndAsPeak = false,
 | 
					 | 
				
			||||||
    peakBias = 0.3, // 控制曲率偏向:0.5 表示中点;靠近 0 表示更靠近起点
 | 
					 | 
				
			||||||
    midOffset = 1000,
 | 
					 | 
				
			||||||
  } = options
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const [lon1, lat1, alt1, t1] = p1
 | 
					 | 
				
			||||||
  const [lon2, lat2, alt2, t2] = p2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const dt = (t2 - t1) / 1000 // 秒
 | 
					 | 
				
			||||||
  const tPeak =
 | 
					 | 
				
			||||||
    dt * (useEndAsPeak ? 1 - peakBias : useStartAsPeak ? peakBias : 0.5)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // 设置高度
 | 
					 | 
				
			||||||
  let h0 = alt1
 | 
					 | 
				
			||||||
  let h2 = alt2
 | 
					 | 
				
			||||||
  let h1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (useStartAsPeak) {
 | 
					 | 
				
			||||||
    h1 = (alt1 + alt2) / 2 - midOffset
 | 
					 | 
				
			||||||
  } else if (useEndAsPeak) {
 | 
					 | 
				
			||||||
    h1 = (alt1 + alt2) / 2 - midOffset
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    h1 = Math.max(alt1, alt2) + midOffset
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // 三点拟合抛物线
 | 
					 | 
				
			||||||
  const c = h0
 | 
					 | 
				
			||||||
  const A = [
 | 
					 | 
				
			||||||
    [tPeak ** 2, tPeak],
 | 
					 | 
				
			||||||
    [dt ** 2, dt],
 | 
					 | 
				
			||||||
  ]
 | 
					 | 
				
			||||||
  const B = [h1 - c, h2 - c]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const denom = A[0][0] * A[1][1] - A[0][1] * A[1][0]
 | 
					 | 
				
			||||||
  const a = (B[0] * A[1][1] - B[1] * A[0][1]) / denom
 | 
					 | 
				
			||||||
  const b = (A[0][0] * B[1] - A[1][0] * B[0]) / denom
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const result = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (let i = 0; i <= steps; i++) {
 | 
					 | 
				
			||||||
    const t = (dt * i) / steps
 | 
					 | 
				
			||||||
    const fraction = t / dt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const lon = lon1 + (lon2 - lon1) * fraction
 | 
					 | 
				
			||||||
    const lat = lat1 + (lat2 - lat1) * fraction
 | 
					 | 
				
			||||||
    const alt = a * t * t + b * t + c
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    result.push({ t: t1 + t * 1000, lon, lat, alt })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return result
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 示例:每秒插值
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -9,14 +9,8 @@ const panels = ['手动配置', 'STK轨迹文件配置']
 | 
				
			|||||||
export default defineComponent({
 | 
					export default defineComponent({
 | 
				
			||||||
  setup() {
 | 
					  setup() {
 | 
				
			||||||
    const { daodanData, showOrHideDdConfig } = useDaodan()
 | 
					    const { daodanData, showOrHideDdConfig } = useDaodan()
 | 
				
			||||||
    const {
 | 
					    const { trajData, interceptData, loadStoreData, addIntercept, initDaodan } =
 | 
				
			||||||
      trajData,
 | 
					      useTestConfig()
 | 
				
			||||||
      boosterList,
 | 
					 | 
				
			||||||
      interceptData,
 | 
					 | 
				
			||||||
      loadStoreData,
 | 
					 | 
				
			||||||
      addIntercept,
 | 
					 | 
				
			||||||
      initDaodan,
 | 
					 | 
				
			||||||
    } = useTestConfig()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    watch(daodanData, newval => {
 | 
					    watch(daodanData, newval => {
 | 
				
			||||||
      loadStoreData()
 | 
					      loadStoreData()
 | 
				
			||||||
@ -60,19 +54,8 @@ export default defineComponent({
 | 
				
			|||||||
                  <div class="detail-container">
 | 
					                  <div class="detail-container">
 | 
				
			||||||
                    {panel === '手动配置' ? (
 | 
					                    {panel === '手动配置' ? (
 | 
				
			||||||
                      <>
 | 
					                      <>
 | 
				
			||||||
                        <div class="flex flex-col gap-4 rounded border border-blue-500 p-4">
 | 
					                        <div class="rounded border border-blue-500 p-4">
 | 
				
			||||||
                          <TrajTable
 | 
					                          <TrajTable title="轨迹点" data={trajData.value} />
 | 
				
			||||||
                            title="轨迹点"
 | 
					 | 
				
			||||||
                            data={trajData.value}
 | 
					 | 
				
			||||||
                            showPosIcon={false}
 | 
					 | 
				
			||||||
                          />
 | 
					 | 
				
			||||||
                          {boosterList.value.map((booster, index) => (
 | 
					 | 
				
			||||||
                            <TrajTable
 | 
					 | 
				
			||||||
                              title={`${['一', '二', '三'][index]}级助推器`}
 | 
					 | 
				
			||||||
                              data={booster}
 | 
					 | 
				
			||||||
                              showPosIcon={false}
 | 
					 | 
				
			||||||
                            />
 | 
					 | 
				
			||||||
                          ))}
 | 
					 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                        <div class="flex flex-col gap-4 rounded border border-red-500 p-4">
 | 
					                        <div class="flex flex-col gap-4 rounded border border-red-500 p-4">
 | 
				
			||||||
                          {interceptData.value.map(data => (
 | 
					                          {interceptData.value.map(data => (
 | 
				
			||||||
@ -80,7 +63,6 @@ export default defineComponent({
 | 
				
			|||||||
                              title="拦截"
 | 
					                              title="拦截"
 | 
				
			||||||
                              data={data}
 | 
					                              data={data}
 | 
				
			||||||
                              onRemoveIntercept={removeIntercept}
 | 
					                              onRemoveIntercept={removeIntercept}
 | 
				
			||||||
                              showPosIcon={false}
 | 
					 | 
				
			||||||
                            />
 | 
					                            />
 | 
				
			||||||
                          ))}
 | 
					                          ))}
 | 
				
			||||||
                          <div>
 | 
					                          <div>
 | 
				
			||||||
@ -93,9 +75,6 @@ export default defineComponent({
 | 
				
			|||||||
                    ) : (
 | 
					                    ) : (
 | 
				
			||||||
                      <>
 | 
					                      <>
 | 
				
			||||||
                        <TrajUpload title="轨迹点" />
 | 
					                        <TrajUpload title="轨迹点" />
 | 
				
			||||||
                        <TrajUpload title="一级助推器" />
 | 
					 | 
				
			||||||
                        <TrajUpload title="二级助推器" />
 | 
					 | 
				
			||||||
                        <TrajUpload title="三级助推器" />
 | 
					 | 
				
			||||||
                        <TrajUpload title="拦截" />
 | 
					                        <TrajUpload title="拦截" />
 | 
				
			||||||
                      </>
 | 
					                      </>
 | 
				
			||||||
                    )}
 | 
					                    )}
 | 
				
			||||||
 | 
				
			|||||||
@ -38,7 +38,7 @@ export default defineComponent({
 | 
				
			|||||||
        render(row) {
 | 
					        render(row) {
 | 
				
			||||||
          return (
 | 
					          return (
 | 
				
			||||||
            <div class="flex items-center justify-between gap-2">
 | 
					            <div class="flex items-center justify-between gap-2">
 | 
				
			||||||
              <div>{row.name}</div>
 | 
					              <div>{row.name} </div>
 | 
				
			||||||
              {props.showPosIcon && (
 | 
					              {props.showPosIcon && (
 | 
				
			||||||
                <NButton
 | 
					                <NButton
 | 
				
			||||||
                  // quaternary
 | 
					                  // quaternary
 | 
				
			||||||
@ -75,7 +75,7 @@ export default defineComponent({
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        title: getTitle('lon'),
 | 
					        title: '经度',
 | 
				
			||||||
        key: 'lon',
 | 
					        key: 'lon',
 | 
				
			||||||
        render(row) {
 | 
					        render(row) {
 | 
				
			||||||
          return (
 | 
					          return (
 | 
				
			||||||
@ -88,7 +88,7 @@ export default defineComponent({
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        title: getTitle('lat'),
 | 
					        title: '纬度',
 | 
				
			||||||
        key: 'lat',
 | 
					        key: 'lat',
 | 
				
			||||||
        render(row) {
 | 
					        render(row) {
 | 
				
			||||||
          return (
 | 
					          return (
 | 
				
			||||||
@ -109,7 +109,7 @@ export default defineComponent({
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        title: getTitle('time'),
 | 
					        title: '时间',
 | 
				
			||||||
        key: 'time',
 | 
					        key: 'time',
 | 
				
			||||||
        render(row) {
 | 
					        render(row) {
 | 
				
			||||||
          return (
 | 
					          return (
 | 
				
			||||||
@ -117,27 +117,52 @@ export default defineComponent({
 | 
				
			|||||||
          )
 | 
					          )
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        title: '助推器脱落',
 | 
				
			||||||
 | 
					        key: 'detached',
 | 
				
			||||||
 | 
					        render(row, rowIndex) {
 | 
				
			||||||
 | 
					          return rowIndex !== 0 && rowIndex < trajData.value.length - 1 ? (
 | 
				
			||||||
 | 
					            <NSwitch v-model:value={row.detached} type="datetime"></NSwitch>
 | 
				
			||||||
 | 
					          ) : (
 | 
				
			||||||
 | 
					            '-'
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        title: '操作',
 | 
				
			||||||
 | 
					        render(row, rowIndex) {
 | 
				
			||||||
 | 
					          return rowIndex !== 0 && rowIndex < trajData.value.length - 1 ? (
 | 
				
			||||||
 | 
					            <NButton
 | 
				
			||||||
 | 
					              type="error"
 | 
				
			||||||
 | 
					              text
 | 
				
			||||||
 | 
					              v-slots={{
 | 
				
			||||||
 | 
					                icon: () => (
 | 
				
			||||||
 | 
					                  <NIcon>
 | 
				
			||||||
 | 
					                    <TrashOutline />
 | 
				
			||||||
 | 
					                  </NIcon>
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					              }}
 | 
				
			||||||
 | 
					              onClick={() => {
 | 
				
			||||||
 | 
					                trajData.value.splice(rowIndex, 1)
 | 
				
			||||||
 | 
					              }}
 | 
				
			||||||
 | 
					            ></NButton>
 | 
				
			||||||
 | 
					          ) : (
 | 
				
			||||||
 | 
					            '-'
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function getTitle(key) {
 | 
					    const addFeaturePoint = () => {
 | 
				
			||||||
      const isIntercept = props.title.indexOf('拦截') > -1
 | 
					      trajData.value.splice(trajData.value.length - 1, 0, {
 | 
				
			||||||
      const isBooster = props.title.indexOf('助推器') > -1
 | 
					        name: '中间特征点',
 | 
				
			||||||
 | 
					        lon: 0,
 | 
				
			||||||
      const dict = {
 | 
					        lat: 0,
 | 
				
			||||||
        time: isIntercept ? '命中时间' : isBooster ? '脱离时间' : '时间',
 | 
					        alt: 0,
 | 
				
			||||||
        lat: isIntercept ? '发射纬度' : isBooster ? '落点纬度' : '纬度',
 | 
					        time: Date.now(),
 | 
				
			||||||
        lon: isIntercept ? '发射经度' : isBooster ? '落点经度' : '经度',
 | 
					        detached: false,
 | 
				
			||||||
        alt: '高度',
 | 
					      })
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      return dict[key] || key
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (props.title.indexOf('助推器') > -1) {
 | 
					 | 
				
			||||||
      columns.splice(3, 1)
 | 
					 | 
				
			||||||
    } else if (props.title.indexOf('拦截') > -1) {
 | 
					 | 
				
			||||||
      columns.splice(3, 1)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dialog = useDialog()
 | 
					    const dialog = useDialog()
 | 
				
			||||||
    const remove = () => {
 | 
					    const remove = () => {
 | 
				
			||||||
      dialog.warning({
 | 
					      dialog.warning({
 | 
				
			||||||
@ -155,6 +180,9 @@ export default defineComponent({
 | 
				
			|||||||
        <div class="flex justify-between">
 | 
					        <div class="flex justify-between">
 | 
				
			||||||
          <div class="detail-item-title">{props.title}</div>
 | 
					          <div class="detail-item-title">{props.title}</div>
 | 
				
			||||||
          <div>
 | 
					          <div>
 | 
				
			||||||
 | 
					            <NButton quaternary type="primary" onClick={addFeaturePoint}>
 | 
				
			||||||
 | 
					              添加特征点
 | 
				
			||||||
 | 
					            </NButton>
 | 
				
			||||||
            {props.title.indexOf('拦截') > -1 && (
 | 
					            {props.title.indexOf('拦截') > -1 && (
 | 
				
			||||||
              <NButton quaternary type="error" onClick={remove}>
 | 
					              <NButton quaternary type="error" onClick={remove}>
 | 
				
			||||||
                删除拦截
 | 
					                删除拦截
 | 
				
			||||||
 | 
				
			|||||||
@ -1,20 +1,12 @@
 | 
				
			|||||||
import { ref, toRaw } from 'vue'
 | 
					import { ref, toRaw } from 'vue'
 | 
				
			||||||
import { useDaodan } from '../../ddHooks'
 | 
					import { useDaodan } from '../../ddHooks'
 | 
				
			||||||
import {
 | 
					import { cartesian32LonLat, getPositionFromTime } from '@/utils/pos'
 | 
				
			||||||
  cartesian32LonLat,
 | 
					 | 
				
			||||||
  getPositionFromTime,
 | 
					 | 
				
			||||||
  getOnePositionFromTime,
 | 
					 | 
				
			||||||
  test,
 | 
					 | 
				
			||||||
  createTrajectory,
 | 
					 | 
				
			||||||
} from '@/utils/pos'
 | 
					 | 
				
			||||||
import ExplosionEffect from '@/js/Explosion'
 | 
					import ExplosionEffect from '@/js/Explosion'
 | 
				
			||||||
import { generateId } from '@/utils/id'
 | 
					import { generateId } from '@/utils/id'
 | 
				
			||||||
import store from 'store2'
 | 
					import store from 'store2'
 | 
				
			||||||
import { lineString, bezierSpline } from '@turf/turf'
 | 
					// import { getPositionFromTime } from '@/utils/pos'
 | 
				
			||||||
// import { useDaodan } from '../../ddHooks'
 | 
					// import { useDaodan } from '../../ddHooks'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ddScale = 30
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const trajData = ref({
 | 
					const trajData = ref({
 | 
				
			||||||
  id: 'dd',
 | 
					  id: 'dd',
 | 
				
			||||||
  data: [
 | 
					  data: [
 | 
				
			||||||
@ -26,69 +18,63 @@ const trajData = ref({
 | 
				
			|||||||
      time: 1183135260000,
 | 
					      time: 1183135260000,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      name: '最高点',
 | 
					      name: '中间特征点',
 | 
				
			||||||
      lon: 125,
 | 
					      lon: 122,
 | 
				
			||||||
      lat: 25,
 | 
					      lat: 21,
 | 
				
			||||||
 | 
					      alt: 1000000,
 | 
				
			||||||
 | 
					      time: 1183135265000,
 | 
				
			||||||
 | 
					      detached: true,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: '中间特征点',
 | 
				
			||||||
 | 
					      lon: 124,
 | 
				
			||||||
 | 
					      lat: 21,
 | 
				
			||||||
 | 
					      alt: 1500000,
 | 
				
			||||||
 | 
					      time: 1183135270000,
 | 
				
			||||||
 | 
					      detached: true,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      name: '中间特征点',
 | 
				
			||||||
 | 
					      lon: 128,
 | 
				
			||||||
 | 
					      lat: 21,
 | 
				
			||||||
      alt: 2000000,
 | 
					      alt: 2000000,
 | 
				
			||||||
      time: 1183135280000,
 | 
					      time: 1183135280000,
 | 
				
			||||||
 | 
					      detached: true,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      name: '落点',
 | 
					      name: '落点',
 | 
				
			||||||
      lon: 160,
 | 
					      lon: 135,
 | 
				
			||||||
      lat: 40,
 | 
					      lat: 21,
 | 
				
			||||||
      alt: 0,
 | 
					      alt: 1500000,
 | 
				
			||||||
      time: 1183135300000,
 | 
					      time: 1183135290000,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
const boosterList = ref([
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    id: 'booster-1',
 | 
					 | 
				
			||||||
    data: [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        // name: '落点',
 | 
					 | 
				
			||||||
        lon: 130,
 | 
					 | 
				
			||||||
        lat: 23,
 | 
					 | 
				
			||||||
        alt: 0,
 | 
					 | 
				
			||||||
        time: 1183135265000,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    id: 'booster-2',
 | 
					 | 
				
			||||||
    data: [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        // name: '落点',
 | 
					 | 
				
			||||||
        lon: 135,
 | 
					 | 
				
			||||||
        lat: 28,
 | 
					 | 
				
			||||||
        alt: 0,
 | 
					 | 
				
			||||||
        time: 1183135270000,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    id: 'booster-3',
 | 
					 | 
				
			||||||
    data: [
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        // name: '落点',
 | 
					 | 
				
			||||||
        lon: 140,
 | 
					 | 
				
			||||||
        lat: 35,
 | 
					 | 
				
			||||||
        alt: 0,
 | 
					 | 
				
			||||||
        time: 1183135275000,
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
])
 | 
					 | 
				
			||||||
const interceptData = ref([
 | 
					const interceptData = ref([
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    id: 'intercept-1',
 | 
					    id: 'dd1',
 | 
				
			||||||
    data: [
 | 
					    data: [
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        // name: '起始点',
 | 
					        name: '起始点',
 | 
				
			||||||
        lon: 137,
 | 
					        lon: 137,
 | 
				
			||||||
        lat: 25,
 | 
					        lat: 25,
 | 
				
			||||||
        alt: 0,
 | 
					        alt: 0,
 | 
				
			||||||
        time: 1183135285000,
 | 
					        time: 1183135270000,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: '中间特征点',
 | 
				
			||||||
 | 
					        lon: 138,
 | 
				
			||||||
 | 
					        lat: 24,
 | 
				
			||||||
 | 
					        alt: 1000000,
 | 
				
			||||||
 | 
					        time: 1183135280000,
 | 
				
			||||||
 | 
					        detached: true,
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        name: '落点',
 | 
				
			||||||
 | 
					        lon: 135,
 | 
				
			||||||
 | 
					        lat: 21,
 | 
				
			||||||
 | 
					        alt: 1500000,
 | 
				
			||||||
 | 
					        time: 1183135290000,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@ -99,7 +85,6 @@ const { daodanData, showDdConfigCom } = useDaodan()
 | 
				
			|||||||
export function useTestConfig() {
 | 
					export function useTestConfig() {
 | 
				
			||||||
  return {
 | 
					  return {
 | 
				
			||||||
    trajData,
 | 
					    trajData,
 | 
				
			||||||
    boosterList,
 | 
					 | 
				
			||||||
    interceptData,
 | 
					    interceptData,
 | 
				
			||||||
    loadStoreData,
 | 
					    loadStoreData,
 | 
				
			||||||
    addIntercept,
 | 
					    addIntercept,
 | 
				
			||||||
@ -109,16 +94,13 @@ export function useTestConfig() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function saveDataToStore() {
 | 
					function saveDataToStore() {
 | 
				
			||||||
  // test()
 | 
					 | 
				
			||||||
  const daodanDataRaw = toRaw(daodanData.value)
 | 
					  const daodanDataRaw = toRaw(daodanData.value)
 | 
				
			||||||
  const storeData = store.get('daodanData')
 | 
					  const storeData = store.get('daodanData')
 | 
				
			||||||
 | 
					 | 
				
			||||||
  store.set('daodanData', {
 | 
					  store.set('daodanData', {
 | 
				
			||||||
    ...storeData,
 | 
					    ...storeData,
 | 
				
			||||||
    [daodanDataRaw.id]: {
 | 
					    [daodanDataRaw.id]: {
 | 
				
			||||||
      ...daodanDataRaw,
 | 
					      ...daodanDataRaw,
 | 
				
			||||||
      trajData: trajData.value,
 | 
					      trajData: trajData.value,
 | 
				
			||||||
      boosterList: boosterList.value,
 | 
					 | 
				
			||||||
      interceptData: interceptData.value,
 | 
					      interceptData: interceptData.value,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
@ -192,23 +174,20 @@ function addDaodan(trajData, type = 0) {
 | 
				
			|||||||
    ddTrajData[0].alt
 | 
					    ddTrajData[0].alt
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  const hpRoll = new Cesium.HeadingPitchRoll()
 | 
					  const hpRoll = new Cesium.HeadingPitchRoll()
 | 
				
			||||||
  // const fixedFrameTransform = Cesium.Transforms.eastNorthUpToFixedFrame
 | 
					 | 
				
			||||||
  const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator(
 | 
					  const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator(
 | 
				
			||||||
    'north',
 | 
					    'north',
 | 
				
			||||||
    'west'
 | 
					    'west'
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  // hpRoll.pitch = (90 * Math.PI) / 180
 | 
					  hpRoll.pitch = (90 * Math.PI) / 180
 | 
				
			||||||
  const modelObj = Cesium.Model.fromGltf({
 | 
					  const modelObj = Cesium.Model.fromGltf({
 | 
				
			||||||
    // url: './models/launchvehicle.glb',
 | 
					    url: './models/launchvehicle.glb',
 | 
				
			||||||
    url: './models/美三叉戟2动画.glb',
 | 
					 | 
				
			||||||
    modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
 | 
					    modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
 | 
				
			||||||
      position,
 | 
					      position,
 | 
				
			||||||
      hpRoll,
 | 
					      hpRoll,
 | 
				
			||||||
      Cesium.Ellipsoid.WGS84,
 | 
					      Cesium.Ellipsoid.WGS84,
 | 
				
			||||||
      fixedFrameTransform
 | 
					      fixedFrameTransform
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
    scale: ddScale,
 | 
					    minimumPixelSize: 70,
 | 
				
			||||||
    minimumPixelSize: ddScale,
 | 
					 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const ddPrimitive = viewer.scene.primitives.add(modelObj)
 | 
					  const ddPrimitive = viewer.scene.primitives.add(modelObj)
 | 
				
			||||||
@ -231,16 +210,17 @@ function addDaodan(trajData, type = 0) {
 | 
				
			|||||||
  // })
 | 
					  // })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ddPrimitive.readyPromise.then(model => {
 | 
					  ddPrimitive.readyPromise.then(model => {
 | 
				
			||||||
    console.log('model', model)
 | 
					 | 
				
			||||||
    nodes = model.pickIds.map(item => item.object.detail.node)
 | 
					    nodes = model.pickIds.map(item => item.object.detail.node)
 | 
				
			||||||
    console.log('nodes', nodes)
 | 
					    nodes.forEach(i => {
 | 
				
			||||||
    // nodes.forEach(i => {
 | 
					      // console.log(i._name, model.getNode(i._name))
 | 
				
			||||||
    //   // console.log(i._name, model.getNode(i._name))
 | 
					      if (new RegExp(/SRB\d/).test(i._name)) {
 | 
				
			||||||
    //   if (new RegExp(/SRB\d/).test(i._name)) {
 | 
					        model.getNode(i._name).show = false
 | 
				
			||||||
    //     model.getNode(i._name).show = false
 | 
					      }
 | 
				
			||||||
    //   }
 | 
					    })
 | 
				
			||||||
    // })
 | 
					 | 
				
			||||||
    computePath(ddPrimitive, trajData, type)
 | 
					    computePath(ddPrimitive, trajData, type)
 | 
				
			||||||
 | 
					    // setTimeout(() => {
 | 
				
			||||||
 | 
					    // playDaodan(ddPrimitive, nodes)
 | 
				
			||||||
 | 
					    // }, 3000)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -249,16 +229,16 @@ function initDaodan() {
 | 
				
			|||||||
  saveDataToStore()
 | 
					  saveDataToStore()
 | 
				
			||||||
  minTime = getMinTime([
 | 
					  minTime = getMinTime([
 | 
				
			||||||
    ...toRaw(trajData.value.data),
 | 
					    ...toRaw(trajData.value.data),
 | 
				
			||||||
    // ...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity),
 | 
					    ...toRaw(interceptData.value.map(item => toRaw(item.data))).flat(Infinity),
 | 
				
			||||||
  ])
 | 
					  ])
 | 
				
			||||||
  // console.log(minTime)
 | 
					  // console.log(minTime)
 | 
				
			||||||
  addDaodan(trajData.value)
 | 
					  addDaodan(trajData.value)
 | 
				
			||||||
  aniIndexMap.set(trajData.value.id, 0)
 | 
					  aniIndexMap.set(trajData.value.id, 0)
 | 
				
			||||||
  // interceptData.value.forEach(item => {
 | 
					  interceptData.value.forEach(item => {
 | 
				
			||||||
  //   const { id, data } = item
 | 
					    const { id, data } = item
 | 
				
			||||||
  //   addDaodan(item, 1)
 | 
					    addDaodan(item, 1)
 | 
				
			||||||
  //   aniIndexMap.set(id, 0)
 | 
					    aniIndexMap.set(id, 0)
 | 
				
			||||||
  // })
 | 
					  })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function getMinTime(data) {
 | 
					function getMinTime(data) {
 | 
				
			||||||
@ -269,16 +249,14 @@ function getMinTime(data) {
 | 
				
			|||||||
  return minTime
 | 
					  return minTime
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const pathLine = new Map()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function computePath(daodan, trajData, type) {
 | 
					function computePath(daodan, trajData, type) {
 | 
				
			||||||
  const { id, data: ddTrajData } = trajData
 | 
					  const { data: ddTrajData } = trajData
 | 
				
			||||||
  const points = ddTrajData.map(item => {
 | 
					  const points = ddTrajData.map(item => {
 | 
				
			||||||
    const { time, lon, lat, alt } = item
 | 
					    const { time, lon, lat, alt, detached } = item
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      position: Cesium.Cartesian3.fromDegrees(lon, lat, alt),
 | 
					      position: Cesium.Cartesian3.fromDegrees(lon, lat, alt),
 | 
				
			||||||
      time: time - minTime,
 | 
					      time: time - minTime,
 | 
				
			||||||
 | 
					      detached,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  const totalAnimationTime = points.at(-1).time
 | 
					  const totalAnimationTime = points.at(-1).time
 | 
				
			||||||
@ -292,13 +270,13 @@ function computePath(daodan, trajData, type) {
 | 
				
			|||||||
      point.time / 1000,
 | 
					      point.time / 1000,
 | 
				
			||||||
      new Cesium.JulianDate()
 | 
					      new Cesium.JulianDate()
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    // const point = viewer.entities.add({
 | 
					    viewer.entities.add({
 | 
				
			||||||
    //   position: point.position,
 | 
					      position: point.position,
 | 
				
			||||||
    //   point: {
 | 
					      point: {
 | 
				
			||||||
    //     color: Cesium.Color.WHITE,
 | 
					        color: Cesium.Color.WHITE,
 | 
				
			||||||
    //     pixelSize: 5,
 | 
					        pixelSize: 5,
 | 
				
			||||||
    //   },
 | 
					      },
 | 
				
			||||||
    // })
 | 
					    })
 | 
				
			||||||
    positionProperty.addSample(time, point.position)
 | 
					    positionProperty.addSample(time, point.position)
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  positionProperty.setInterpolationOptions({
 | 
					  positionProperty.setInterpolationOptions({
 | 
				
			||||||
@ -307,28 +285,7 @@ function computePath(daodan, trajData, type) {
 | 
				
			|||||||
    // interpolationDegree: 5,
 | 
					    // interpolationDegree: 5,
 | 
				
			||||||
    // interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
 | 
					    // interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
  const line = createLine({
 | 
					  createLine({ totalAnimationTime, startTime, positionProperty, type })
 | 
				
			||||||
    totalAnimationTime,
 | 
					 | 
				
			||||||
    startTime,
 | 
					 | 
				
			||||||
    positionProperty,
 | 
					 | 
				
			||||||
    type,
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pathLine.set(id, line)
 | 
					 | 
				
			||||||
  if (type === 0) {
 | 
					 | 
				
			||||||
    computeBoosterOrInterceptPath({
 | 
					 | 
				
			||||||
      dataList: boosterList.value,
 | 
					 | 
				
			||||||
      startTime,
 | 
					 | 
				
			||||||
      positionProperty,
 | 
					 | 
				
			||||||
      type: 'booster',
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    computeBoosterOrInterceptPath({
 | 
					 | 
				
			||||||
      dataList: interceptData.value,
 | 
					 | 
				
			||||||
      startTime,
 | 
					 | 
				
			||||||
      positionProperty,
 | 
					 | 
				
			||||||
      type: 'intercept',
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  daodanAnimation({
 | 
					  daodanAnimation({
 | 
				
			||||||
    totalAnimationTime,
 | 
					    totalAnimationTime,
 | 
				
			||||||
    startTime,
 | 
					    startTime,
 | 
				
			||||||
@ -338,140 +295,11 @@ function computePath(daodan, trajData, type) {
 | 
				
			|||||||
  })
 | 
					  })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const boosterMap = new Map()
 | 
					 | 
				
			||||||
const interceptMap = new Map()
 | 
					 | 
				
			||||||
const interceptTime = ref()
 | 
					 | 
				
			||||||
function computeBoosterOrInterceptPath({
 | 
					 | 
				
			||||||
  dataList,
 | 
					 | 
				
			||||||
  startTime,
 | 
					 | 
				
			||||||
  positionProperty,
 | 
					 | 
				
			||||||
  type,
 | 
					 | 
				
			||||||
}) {
 | 
					 | 
				
			||||||
  dataList.forEach((dataItem, index) => {
 | 
					 | 
				
			||||||
    const { id, data } = dataItem
 | 
					 | 
				
			||||||
    let points = []
 | 
					 | 
				
			||||||
    data.forEach(item => {
 | 
					 | 
				
			||||||
      const { time, lon, lat, alt } = item
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const position = getOnePositionFromTime(
 | 
					 | 
				
			||||||
        startTime,
 | 
					 | 
				
			||||||
        (time - minTime) / 1000,
 | 
					 | 
				
			||||||
        positionProperty
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // points.push({
 | 
					 | 
				
			||||||
      //   position,
 | 
					 | 
				
			||||||
      //   time: time - minTime,
 | 
					 | 
				
			||||||
      // })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const lonlat = cartesian32LonLat(position)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const pointTime = time - minTime
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      const aniPointTime = pointTime + (type === 'booster' ? 10000 : -10000)
 | 
					 | 
				
			||||||
      type === 'intercept' && (interceptTime.value = pointTime / 1000)
 | 
					 | 
				
			||||||
      const pointInline = {
 | 
					 | 
				
			||||||
        position: Cesium.Cartesian3.fromDegrees(lon, lat, alt),
 | 
					 | 
				
			||||||
        time: aniPointTime,
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      // points.push(pointInline)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      points = createTrajectory(
 | 
					 | 
				
			||||||
        [lon, lat, alt, aniPointTime],
 | 
					 | 
				
			||||||
        [...lonlat, time - minTime],
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          useEndAsPeak: true,
 | 
					 | 
				
			||||||
          peakBias: 0.65,
 | 
					 | 
				
			||||||
          midOffset: 1000,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ).map(item => {
 | 
					 | 
				
			||||||
        return {
 | 
					 | 
				
			||||||
          position: Cesium.Cartesian3.fromDegrees(item.lon, item.lat, item.alt),
 | 
					 | 
				
			||||||
          time: item.t,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dataPositionProperty = new Cesium.SampledPositionProperty()
 | 
					 | 
				
			||||||
    points.forEach(point => {
 | 
					 | 
				
			||||||
      const time = Cesium.JulianDate.addSeconds(
 | 
					 | 
				
			||||||
        startTime,
 | 
					 | 
				
			||||||
        point.time / 1000,
 | 
					 | 
				
			||||||
        new Cesium.JulianDate()
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      // viewer.entities.add({
 | 
					 | 
				
			||||||
      //   position: point.position,
 | 
					 | 
				
			||||||
      //   point: {
 | 
					 | 
				
			||||||
      //     color: Cesium.Color.ORANGE,
 | 
					 | 
				
			||||||
      //     pixelSize: 5,
 | 
					 | 
				
			||||||
      //   },
 | 
					 | 
				
			||||||
      // })
 | 
					 | 
				
			||||||
      dataPositionProperty.addSample(time, point.position)
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    dataPositionProperty.setInterpolationOptions({
 | 
					 | 
				
			||||||
      interpolationDegree: 2,
 | 
					 | 
				
			||||||
      interpolationAlgorithm: Cesium.HermitePolynomialApproximation,
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const dataLine = createLine({
 | 
					 | 
				
			||||||
      totalAnimationTime: points.at(-1).time,
 | 
					 | 
				
			||||||
      startTime,
 | 
					 | 
				
			||||||
      positionProperty: dataPositionProperty,
 | 
					 | 
				
			||||||
      type: 2,
 | 
					 | 
				
			||||||
      color: type === 'booster' ? 'ORANGE' : 'RED',
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const modelUrl =
 | 
					 | 
				
			||||||
      type === 'booster'
 | 
					 | 
				
			||||||
        ? `./models/美三叉戟2第${['一', '二', '三'][index]}级.glb`
 | 
					 | 
				
			||||||
        : './models/美三叉戟2动画.glb'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dataLine.model = {
 | 
					 | 
				
			||||||
      show: true,
 | 
					 | 
				
			||||||
      uri: modelUrl,
 | 
					 | 
				
			||||||
      runAnimations: false,
 | 
					 | 
				
			||||||
      // uri: `./models/第${['一', '二', '三'][index]}级.glb`,
 | 
					 | 
				
			||||||
      scale: type === 'booster' ? ddScale / 4 : ddScale,
 | 
					 | 
				
			||||||
      minimumPixelSize: type === 'booster' ? ddScale / 4 : ddScale,
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    dataLine.orientation = new Cesium.VelocityOrientationProperty(
 | 
					 | 
				
			||||||
      dataPositionProperty
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    type === 'booster'
 | 
					 | 
				
			||||||
      ? boosterMap.set(id, dataLine)
 | 
					 | 
				
			||||||
      : interceptMap.set(id, dataLine)
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function daodanAnimation(params) {
 | 
					function daodanAnimation(params) {
 | 
				
			||||||
  const { totalAnimationTime, startTime, positionProperty, daodan, trajData } =
 | 
					  const { totalAnimationTime, startTime, positionProperty, daodan, trajData } =
 | 
				
			||||||
    params
 | 
					    params
 | 
				
			||||||
  // const { data: ddTrajData } = trajData
 | 
					  // const { data: ddTrajData } = trajData
 | 
				
			||||||
  // dianhuo(daodan)
 | 
					  dianhuo(daodan)
 | 
				
			||||||
 | 
					 | 
				
			||||||
  // setTimeout(() => {
 | 
					 | 
				
			||||||
  //   modelAnimationController({
 | 
					 | 
				
			||||||
  //     primitive: daodan,
 | 
					 | 
				
			||||||
  //     type: '第一级发动机 MoveZ',
 | 
					 | 
				
			||||||
  //     initVal: 0,
 | 
					 | 
				
			||||||
  //     minVal: -450,
 | 
					 | 
				
			||||||
  //     step: -3,
 | 
					 | 
				
			||||||
  //     fn: () => {
 | 
					 | 
				
			||||||
  //       console.log(
 | 
					 | 
				
			||||||
  //         `一级脱离`,
 | 
					 | 
				
			||||||
  //         'color: red;font-size: 20px;border: 1px solid red'
 | 
					 | 
				
			||||||
  //       )
 | 
					 | 
				
			||||||
  //       nodes.forEach(i => {
 | 
					 | 
				
			||||||
  //         const nodeName = i._name
 | 
					 | 
				
			||||||
  //         if (new RegExp(/第一级发动机/).test(nodeName)) {
 | 
					 | 
				
			||||||
  //           daodan.getNode(nodeName).show = false
 | 
					 | 
				
			||||||
  //         }
 | 
					 | 
				
			||||||
  //       })
 | 
					 | 
				
			||||||
  //     },
 | 
					 | 
				
			||||||
  //   })
 | 
					 | 
				
			||||||
  // }, 3000)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let lastFrameTime = performance.now()
 | 
					  let lastFrameTime = performance.now()
 | 
				
			||||||
  let customElapsedTime = 0
 | 
					  let customElapsedTime = 0
 | 
				
			||||||
@ -489,17 +317,12 @@ function daodanAnimation(params) {
 | 
				
			|||||||
    if (customElapsedTime >= totalAnimationTime) {
 | 
					    if (customElapsedTime >= totalAnimationTime) {
 | 
				
			||||||
      customElapsedTime = totalAnimationTime // 限制时间为总时长
 | 
					      customElapsedTime = totalAnimationTime // 限制时间为总时长
 | 
				
			||||||
      isAnimationRunning = false // 停止动画
 | 
					      isAnimationRunning = false // 停止动画
 | 
				
			||||||
 | 
					 | 
				
			||||||
      setTimeout(() => {
 | 
					 | 
				
			||||||
        removeAllEntity()
 | 
					 | 
				
			||||||
      }, 6000)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    ddNodesAnimationController({
 | 
				
			||||||
    // ddNodesAnimationController({
 | 
					      ddPrimitive: daodan,
 | 
				
			||||||
    //   ddPrimitive: daodan,
 | 
					      curTime: minTime + customElapsedTime * 1000,
 | 
				
			||||||
    //   curTime: minTime + customElapsedTime * 1000,
 | 
					      trajData,
 | 
				
			||||||
    //   trajData,
 | 
					    })
 | 
				
			||||||
    // })
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 计算自定义时间下的位置
 | 
					    // 计算自定义时间下的位置
 | 
				
			||||||
    const customTime = Cesium.JulianDate.addSeconds(
 | 
					    const customTime = Cesium.JulianDate.addSeconds(
 | 
				
			||||||
@ -517,27 +340,16 @@ function daodanAnimation(params) {
 | 
				
			|||||||
        new Cesium.JulianDate()
 | 
					        new Cesium.JulianDate()
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (interceptTime.value && customElapsedTime >= interceptTime.value) {
 | 
					 | 
				
			||||||
      customElapsedTime = totalAnimationTime
 | 
					 | 
				
			||||||
      isAnimationRunning = false
 | 
					 | 
				
			||||||
      explosion = explosionEffect(position)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      setTimeout(() => {
 | 
					 | 
				
			||||||
        removeAllEntity()
 | 
					 | 
				
			||||||
      }, 6000)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (position && !nextPosition && !explosion) {
 | 
					    if (position && !nextPosition && !explosion) {
 | 
				
			||||||
      // const [lon, lat, height] = cartesian32LonLat(position)
 | 
					      const [lon, lat, height] = cartesian32LonLat(position)
 | 
				
			||||||
      // explosion = new ExplosionEffect(viewer, {
 | 
					      explosion = new ExplosionEffect(viewer, {
 | 
				
			||||||
      //   lng: lon,
 | 
					        lng: lon,
 | 
				
			||||||
      //   lat: lat,
 | 
					        lat: lat,
 | 
				
			||||||
      //   height,
 | 
					        height,
 | 
				
			||||||
      // })
 | 
					      })
 | 
				
			||||||
      // setTimeout(() => {
 | 
					      setTimeout(() => {
 | 
				
			||||||
      //   explosion && explosion.remove()
 | 
					        explosion && explosion.remove()
 | 
				
			||||||
      // }, 6000)
 | 
					      }, 6000)
 | 
				
			||||||
      explosion = explosionEffect(position)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (position && nextPosition) {
 | 
					    if (position && nextPosition) {
 | 
				
			||||||
      const fixedFrameTransform =
 | 
					      const fixedFrameTransform =
 | 
				
			||||||
@ -551,22 +363,16 @@ function daodanAnimation(params) {
 | 
				
			|||||||
        fixedFrameTransform,
 | 
					        fixedFrameTransform,
 | 
				
			||||||
        daodan.modelMatrix
 | 
					        daodan.modelMatrix
 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Cesium.Matrix4.fromTranslationQuaternionRotationScale(
 | 
				
			||||||
 | 
					      //   position,
 | 
				
			||||||
 | 
					      //   orientation,
 | 
				
			||||||
 | 
					      //   new Cesium.Cartesian3(1.0, 1.0, 1.0), // 缩放比例,
 | 
				
			||||||
 | 
					      //   daodan.modelMatrix
 | 
				
			||||||
 | 
					      // )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
function explosionEffect(position) {
 | 
					 | 
				
			||||||
  const [lon, lat, height] = cartesian32LonLat(position)
 | 
					 | 
				
			||||||
  const explosion = new ExplosionEffect(viewer, {
 | 
					 | 
				
			||||||
    lng: lon,
 | 
					 | 
				
			||||||
    lat: lat,
 | 
					 | 
				
			||||||
    height,
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  setTimeout(() => {
 | 
					 | 
				
			||||||
    explosion && explosion.remove()
 | 
					 | 
				
			||||||
  }, 6000)
 | 
					 | 
				
			||||||
  return explosion
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
function dianhuo(ddPrimitive) {
 | 
					function dianhuo(ddPrimitive) {
 | 
				
			||||||
  modelAnimationController({
 | 
					  modelAnimationController({
 | 
				
			||||||
    primitive: ddPrimitive,
 | 
					    primitive: ddPrimitive,
 | 
				
			||||||
@ -586,6 +392,14 @@ function ddNodesAnimationController(params) {
 | 
				
			|||||||
  const { id: ddId, data: ddTrajData } = trajData
 | 
					  const { id: ddId, data: ddTrajData } = trajData
 | 
				
			||||||
  const nodeAniList = ddTrajData.filter(item => item.detached)
 | 
					  const nodeAniList = ddTrajData.filter(item => item.detached)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // console.log(
 | 
				
			||||||
 | 
					  //   curTime,
 | 
				
			||||||
 | 
					  //   aniIndex,
 | 
				
			||||||
 | 
					  //   nodeAniList[aniIndex].time,
 | 
				
			||||||
 | 
					  //   curTime >= nodeAniList[aniIndex].time,
 | 
				
			||||||
 | 
					  //   'curTime'
 | 
				
			||||||
 | 
					  // )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!ddPrimitive || !aniIndexMap.has(ddId)) return
 | 
					  if (!ddPrimitive || !aniIndexMap.has(ddId)) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const aniIndex = aniIndexMap.get(ddId)
 | 
					  const aniIndex = aniIndexMap.get(ddId)
 | 
				
			||||||
@ -781,36 +595,38 @@ function getHeadingPitchRoll(curPos, nextPos) {
 | 
				
			|||||||
  return hpr
 | 
					  return hpr
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function createLine({
 | 
					function createLine({ totalAnimationTime, startTime, positionProperty, type }) {
 | 
				
			||||||
  totalAnimationTime,
 | 
					 | 
				
			||||||
  startTime,
 | 
					 | 
				
			||||||
  positionProperty,
 | 
					 | 
				
			||||||
  type,
 | 
					 | 
				
			||||||
  color,
 | 
					 | 
				
			||||||
}) {
 | 
					 | 
				
			||||||
  const positionList = getPositionFromTime(
 | 
					  const positionList = getPositionFromTime(
 | 
				
			||||||
    startTime,
 | 
					    startTime,
 | 
				
			||||||
    positionProperty,
 | 
					    positionProperty,
 | 
				
			||||||
    totalAnimationTime
 | 
					    totalAnimationTime
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  // if (type === 2) {
 | 
					  viewer.entities.add({
 | 
				
			||||||
  //   console.log('positionList', positionList)
 | 
					 | 
				
			||||||
  // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return viewer.entities.add({
 | 
					 | 
				
			||||||
    position: positionProperty,
 | 
					    position: positionProperty,
 | 
				
			||||||
    polyline: {
 | 
					    polyline: {
 | 
				
			||||||
      positions: positionList,
 | 
					      positions: positionList,
 | 
				
			||||||
      width: 8,
 | 
					      width: 2,
 | 
				
			||||||
      material: new Cesium.PolylineGlowMaterialProperty({
 | 
					      material: type
 | 
				
			||||||
        glowPower: 0.1,
 | 
					        ? Cesium.Color.RED.withAlpha(0.5)
 | 
				
			||||||
        color: type
 | 
					        : Cesium.Color.BLUE.withAlpha(0.5),
 | 
				
			||||||
          ? type === 2 && Cesium.Color[color].withAlpha(0.5)
 | 
					 | 
				
			||||||
          : Cesium.Color.BLUE.withAlpha(0.5),
 | 
					 | 
				
			||||||
      }),
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					// function getPositionFromTime(startTime, pos, totalAnimationTime) {
 | 
				
			||||||
 | 
					//   const points = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//   for (let i = 0; i <= totalAnimationTime / 100; i++) {
 | 
				
			||||||
 | 
					//     const time = Cesium.JulianDate.addSeconds(
 | 
				
			||||||
 | 
					//       startTime,
 | 
				
			||||||
 | 
					//       i,
 | 
				
			||||||
 | 
					//       new Cesium.JulianDate()
 | 
				
			||||||
 | 
					//     )
 | 
				
			||||||
 | 
					//     const point = pos.getValue(time)
 | 
				
			||||||
 | 
					//     point && points.push(point)
 | 
				
			||||||
 | 
					//   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//   return points
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function modelAnimationController(controller) {
 | 
					function modelAnimationController(controller) {
 | 
				
			||||||
  const { type, initVal, maxVal, fn, step, minVal, primitive } = controller
 | 
					  const { type, initVal, maxVal, fn, step, minVal, primitive } = controller
 | 
				
			||||||
@ -832,25 +648,3 @@ function modelAnimationController(controller) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  render()
 | 
					  render()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
function removeAllEntity() {
 | 
					 | 
				
			||||||
  boosterMap.values().forEach(i => {
 | 
					 | 
				
			||||||
    viewer.entities.remove(i)
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  boosterMap.clear()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  interceptMap.values().forEach(i => {
 | 
					 | 
				
			||||||
    viewer.entities.remove(i)
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  interceptMap.clear()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  pathLine.values().forEach(i => {
 | 
					 | 
				
			||||||
    viewer.entities.remove(i)
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  pathLine.clear()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ddMap.values().forEach(i => {
 | 
					 | 
				
			||||||
    viewer.scene.primitives.remove(i.primitive)
 | 
					 | 
				
			||||||
  })
 | 
					 | 
				
			||||||
  ddMap.clear()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user