Threejs实现3d地球记录(4)

三、地球信息流可视化(飞线)

1、曲线介绍

Three.js基础曲线函数有三种:

  • 样条曲线:在三维空间中设置5个顶点,输入三维样条曲线CatmullRomCurve3函数作为参数,然后返回更多个顶点,通过返回的顶点数据,构建一个几何体,然后绘制出来一条沿着5个顶点的光滑样条曲线。

  • 三维三次贝赛尔曲线: 由起点、终点、及两个控制点定义,通过三维三次贝塞尔曲线(CubicBezierCurve3)绘制出一条平滑的曲线
    三维三次贝塞尔曲线

  • 圆弧曲线:类似于画一个圆,取其中一段作为弧线;将圆心坐标,圆半径,圆弧起始角度作为ArcCurve参数,绘制一段圆弧。
    圆弧曲线

2、使用圆弧曲线绘制轨迹线

(1)、xoy平面上关于y轴对称的圆弧曲线

在这里插入图片描述

  • 根据起始点确定两点间的顶点坐标(上图青色的点)
    为了美观我们设定距离越远的两点,中间顶点距离球面也越远,简单来说就是顶点到球面的距离与两点之间和球心构成夹角成正相关,夹角越大距离越远,相反则越近。因此我们需要先计算出两点之间和球心构成夹角的弧度值:
//计算两点之间和球心构成夹角的弧度值方法
function radianAOB(A, B, O) {
   
  // dir1、dir2:球面上两个点和球心构成的方向向量
  var dir1 = A.clone().sub(O).normalize();
  var dir2 = B.clone().sub(O).normalize();
  //.dot()计算夹角余弦值
  var cosAngle = dir1.clone().dot(dir2);
  var radianAngle = Math.acos(cosAngle);//余弦值转夹角弧度值
  return radianAngle
}

首先算出两点的中点,然后根据中点确定出顶点与球心构成的方向向量,最后由顶点到球面的距离与两点之间和球心构成夹角成正相关关系式计算出顶点坐标:

// 计算两点的中点
  var middleV3 = new THREE.Vector3().addVectors(startPoint, endPoint).multiplyScalar(0.5);
  // 顶点与球心构成的方向向量
  var dir = middleV3.clone().normalize()
  // 计算夹角的弧度值
  var earthRadianAngle = radianAOB(startPoint, endPoint, new THREE.Vector3(0, 0, 0))
  //弧度值 * R * 0.2:表示飞线轨迹圆弧顶部距离地球球面的距离,与弧度值成正相关即可,可自行调整
  var arcTopCoord = dir.multiplyScalar(R + earthRadianAngle * R * 0.2)
  • 通过三个点确定圆弧线
    绘制圆弧曲线要使用到ArcCurve函数,那就得先计算出圆心坐标,圆半径以及圆弧的起始角度
    1)、计算圆心坐标:
//求p1, p2, p3三个点的外接圆圆心
function threePointCenter(p1, p2, p3) {
   
  var L1 = p1.lengthSq();//到坐标原点距离的平方
  var L2 = p2.lengthSq();
  var L3 = p3.lengthSq();
  var x1 = p1.x, y1 = p1.y, x2 = p2.x, y2 = p2.y, x3 = p3.x, y3 = p3.y;
  var S = x1 * y2 + x2 * y3 + x3 * y1 - x1 * y3 - x2 * y1 - x3 * y2;
  var x = (L2 * y3 + L1 * y2 + L3 * y1 - L2 * y1 - L3 * y2 - L1 * y3) / S / 2;
  var y = (L3 * x2 + L2 * x1 + L1 * x3 - L1 * x2 - L2 * x3 - L3 * x1) / S / 2;
  // 三点外接圆圆心坐标
  var center = new THREE.Vector3(x, y, 0);
  return center
}

2)、计算圆半径(通过顶点y坐标减去圆心y坐标获得)

var flyArcR = Math.abs(flyArcCenter.y - arcTopCoord.y);

3)、计算圆弧的起始角度(可使用到上边计算两点之间和球心构成夹角的弧度值方法)

  var flyRadianAngle = radianAOB(startPoint, new THREE.Vector3(0, -1, 0), flyArcCenter);
  var startAngle = -Math.PI / 2 + flyRadianAngle;//飞线圆弧开始角度
  var endAngle = Math.PI - startAngle;//飞线圆弧结束角度

4)、通过ArcCurve函数计算出圆弧曲线,使用getSpacedPoints(x)方法返回生成圆弧线的点坐标,返回多少个点由x决定,x越大圆弧越圆,但渲染性能越低,最后用setFromPoints渲染几何体顶点坐标以Line绘制出来

function circleLine(x, y, r, startAngle, endAngle) {
   
  var geometry = new THREE.BufferGeometry();
  // THREE.ArcCurve创建圆弧曲线
  var arc = new THREE.ArcCurve(x, y, r, startAngle, endAngle, false);
  //getSpacedPoints是基类Curve的方法,返回一个vector2对象作为元素组成的数组
  var points = arc.getSpacedPoints(50); //分段数50,返回51个顶点
  geometry.setFromPoints(points
  • 31
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值