cesium之飞线数据获取(贝塞尔曲线转换)

cesium之飞线数据获取(贝塞尔曲线转换)

最近研究了一下飞线生成的原理,找到一种实现方法。

以下:x指经度,y指纬度,h指飞线高度

原理:

  1.通过两个点和飞线高度计算出控制贝塞尔曲线弧度的第三个点

  2.将三个点的(y, h)传入贝塞尔曲线算法,得到一条垂直于地面的贝塞尔曲线点数组arr

  3.通过两点的直线公式,获取数组arr中每个点的x值,得到空间曲线数组

代码:

// 贝塞尔曲线二维转三维  返回一个三维点数组
// 参数: x1,y1,x2,y2,h 两点经纬度坐标和飞线高度
export function getBSRPoints (x1,y1,x2,y2,h) {
  let point1 = [y1, 0]
  let point2 = [(y2+y1)/2, h]
  let point3 = [y2, 0]
  let arr = getBSR(point1, point2, point3)
  let arr3d = []
  for (let i in arr) {
    let x = (x2-x1)*(arr[i][0]-y1)/(y2-y1) + x1
    arr3d.push([x, arr[i][0], arr[i][1]])
  }
  return arr3d
}
// 生成贝塞尔曲线
function getBSR (point1, point2, point3) {
  var ps = [{ x: point1[0], y: point1[1] }, { x: point2[0], y: point2[1] }, { x: point3[0], y: point3[1] }]
  let guijipoints = CreateBezierPoints(ps, 100);
  return guijipoints
}
// 贝赛尔曲线算法
// 参数:
// anchorpoints: [{ x: 116.30, y: 39.60 }, { x: 37.50, y: 40.25 }, { x: 39.51, y: 36.25 }]
function CreateBezierPoints(anchorpoints, pointsAmount) {
  var points = [];
  for (var i = 0; i < pointsAmount; i++) {
    var point = MultiPointBezier(anchorpoints, i / pointsAmount)
    points.push([point.x, point.y]);
  }
  return points;
}
function MultiPointBezier(points, t) {
  var len = points.length;
  var x = 0, y = 0;
  var erxiangshi = function (start, end) {
    var cs = 1, bcs = 1;
    while (end > 0) {
      cs *= start;
      bcs *= end;
      start--;
      end--;
    }
    return (cs / bcs);
  };
  for (var i = 0; i < len; i++) {
    var point = points[i];
    x += point.x * Math.pow((1 - t), (len - 1 - i)) * Math.pow(t, i) * (erxiangshi(len - 1, i));
    y += point.y * Math.pow((1 - t), (len - 1 - i)) * Math.pow(t, i) * (erxiangshi(len - 1, i));
  }
  return { x: x, y: y };
}

调用:

  引入以上代码文件,调用getBSRPoints方法即可获取飞线数据,将其赋予动态材质,即可实现飞线。

  动态材质见:https://www.cnblogs.com/s313139232/p/12804734.html

注意:

  以上方法获取到的数据格式为[[x,y,z],[x,y,z],[x,y,z],[x,y,z]],而cesium创建线fromDegreesArrayHeights方法需要的数据格式为:[x,y,z,x,y,z,x,y,z,x,y,z]

  将一下方法加入上面文件中调用即可:

export function getBSRxyz (x1,y1,x2,y2,h) {
  let arr3d = getBSRPoints(x1,y1,x2,y2,h)
  let arrAll = []
  for (let i in arr3d) {
    arrAll.push(arr3d[i][0])
    arrAll.push(arr3d[i][1])
    arrAll.push(arr3d[i][2])
  }
  return arrAll
}

 

 

 

钻研不易,转载请注明出处。。。。。。

 

posted @ 2020-04-30 15:14  莫小龙  阅读(4742)  评论(1编辑  收藏  举报