当前位置:   article > 正文

Cesium中常用的一些数学计算(矩阵、向量)用法——向量_cesium.cartesian3.subtract

cesium.cartesian3.subtract

刚好本人最近在研究数字孪生模拟相关的专题,涉及到三维空间中跟线代相关的计算,顺便重温了一下现代,在使用的过程中遇到的一些总结和实用技巧在下头阐述,相信这篇文章能够给短时间接触这些API的人一些启发。

不同人看向量存在着差异。物理专业学生的视角,向量由方向和长度决定;对于数学专业的学生来说,向量则会被概括为列表的形式方便计算机的存储;

向量是将几何问题转化为代数问题的桥梁,通常,我们研究的二维向量是平面的,而对于我们生活的三维空间,则更多使用三维的向量表示。理解其几何意义可以更好的运用于实际的案例,理解其代数实现可以更好地在计算机进行实现,先来总结一下Cesium 中Cartesian3的一些常见用法:

笛卡尔坐标系(Cartesian3)

地球几何中心为原点,以米为单位。
在这里插入图片描述

坐标经典转换

如何将经纬度或弧度转空间直角坐标系

// wgs84的弧度的经纬度
var position = Cesium.Cartesian3.fromRadians(-2.007, 0.645)
 //#WGS84经纬度转换为世界(笛卡尔)坐标直接转换
var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result)//其中,高度默认值为0,可以不用填写;longitude和latitude为经纬度
var positions = Cesium.Cartesian3.fromDegreesArray(coordinates);//其中,coordinates格式为不带高度的数组。例如:[-115.0, 37.0, -107.0, 33.0]
var positions = Cesium.Cartesian3.fromDegreesArrayHeights(coordinates);//coordinates格式为带有高度的数组。例如:[-115.0, 37.0, 100000.0, -107.0, 33.0, 150000.0]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如何将笛卡尔空间直角坐标(Cartesian3)转经纬度或弧度(wgs84)

// 第一种:直接转换,转换为弧度
const cartographic = Cesium.Cartographic.fromCartesian(cartesian3)
// 第二种:间接转化,转换为角度
const ellipsoid = viewer.scene.globe.ellipsoid
const cartesian3 = new Cesium.cartesian3(x,y,z)
const cartographic = ellipsoid.cartesianToCartographic(cartesian3)
const lat = Cesium.Math.toDegrees(cartograhphic.latitude)
const lng = Cesium.Math.toDegrees(cartograhpinc.longitude)
const alt = cartographic.height

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

常用方法

Cesium.Cartesian3.abs(cartesian, new Cesium.Cartesian3())

求向量的绝对值

Cesium.Cartesian3.add(a, b, new Cesium.Cartesian3())

  // 源码
  // 代数理解
  // A(X1,Y1) B(X2,Y2),则A + B=(X1+X2,Y1+Y2)
  result.x = left.x + right.x;
  result.y = left.y + right.y;
  result.z = left.z + right.z;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

向量相加得到的结果。由起点指向下一个向量的终点(几何意义的理解)。
向量和

Cesium.Cartesian3.subtract(pointA, pointB, new Cesium.Cartesian3());

  // 源码
  // A(X1,Y1) B(X2,Y2),A - B=(X1-X2,Y1-Y2)
  result.x = left.x - right.x;
  result.y = left.y - right.y;
  result.z = left.z - right.z;
  • 1
  • 2
  • 3
  • 4
  • 5

计算A、B两个笛卡尔向量差,第一个参数是起点,第二个参数是终点。
由减向量的终点指向被减向量的终点。
在这里插入图片描述

Cesium.Cartesian3.normalize(vector, new Cesium.Cartesian3());

  // 源码
  const magnitude = Cartesian3.magnitude(cartesian);
  result.x = cartesian.x / magnitude;
  result.y = cartesian.y / magnitude;
  result.z = cartesian.z / magnitude;
  • 1
  • 2
  • 3
  • 4
  • 5

将向量归一化(即单位向量),实际应用中使得我们可以只考虑单位向量的方向,不去管他的大小。

Cesium.Cartesian3.negate(cartesian, new Cesium.Cartesian3())

向量方向取反

// 例子
Cesium.Cartesian3.negate(new Cesium.Cartesian3(3,4,5), new Cesium.Cartesian3()) 
// new Cesium.Cartesian3(-3, -4, -5)
  • 1
  • 2
  • 3

Cesium.Cartesian3.dot(left, right) ;

// 源码
// 代数实现: 两个维数相同的向量对应维相乘再相加
// 计算向量的点积(注:点积是标量,只有数值,没有方向)
 return left.x * right.x + left.y * right.y + left.z * right.z;
  • 1
  • 2
  • 3
  • 4

几何意义:b在a向量上的投影和a长度的乘积;
如果两个向量的指向方向大致相同时,则点积为正数;两个互相垂直的向量结果为0;两个向量的指向大致相反时,点积为负数。
在这里插入图片描述
点积与顺序无关。

点积在图形学上的用途:主要用于求夹角、求两个向量投影的长度、比较两个向量的接近程度(方向上,如果点积越大,说明夹角越小)

Cesium.Cartesian3.cross(left, right, result)

计算向量叉积(注:叉积是向量)

  // 源码
  const leftX = left.x;
  const leftY = left.y;
  const leftZ = left.z;
  const rightX = right.x;
  const rightY = right.y;
  const rightZ = right.z;

  const x = leftY * rightZ - leftZ * rightY;
  const y = leftZ * rightX - leftX * rightZ;
  const z = leftX * rightY - leftY * rightX;

  result.x = x;
  result.y = y;
  result.z = z;
  return result;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

向量的叉积:两个互相垂直的向量,结果是向量的乘积;向量叉乘自身得到长度为0的向量;

叉积的用途很多,可用于求平面的法向量(向量的方向同时垂直于向量a、b组成的平面)、建立三维空间坐标中的直角坐标系、计算三角形的面积、判断左右和内外等等;例如可以判断凹凸多边形、点是否在三角形面内。

Cesium.Cartesian3.projectVector(a, b, new Cesium.Cartesian3())

求向量a投影到向量b上的向量

 // 源码
  const scalar = Cartesian3.dot(a, b) / Cartesian3.dot(b, b);
  return Cartesian3.multiplyByScalar(b, scalar, result);
  • 1
  • 2
  • 3

源码解析:按照几何理解,a、b的点积是a向量在b向量上投影的长度 乘以 b向量的长度(模),b的点积是b长度的平方,所以scalar = a向量在b向量上投影的长度/b向量的长度,将b向量乘以他们的比例即等于a在b上的投影。

Cesium.Cartesian3.midpoint(left, right, new Cesium.Cartesian3())

求两个点的中间点

  result.x = (left.x + right.x) * 0.5;
  result.y = (left.y + right.y) * 0.5;
  result.z = (left.z + right.z) * 0.5;
  • 1
  • 2
  • 3

绿色的点
绿色的点为蓝色点的中点

Cesium.Cartesian3.multiplyByScalar(cartesian, scalar, new Cesium.Cartesian3())

向量的缩放比例

  // 源码
  result.x = cartesian.x * scalar;
  result.y = cartesian.y * scalar;
  result.z = cartesian.z * scalar;
  • 1
  • 2
  • 3
  • 4

Cesium.Cartesian3.multiplyComponents(left, right, new Cesium.Cartesian3())

两个Cartesian的分量乘积

  result.x = left.x * right.x;
  result.y = left.y * right.y;
  result.z = left.z * right.z;
  • 1
  • 2
  • 3

Cesium.Cartesian3.divideByScalar(cartesian, scalar, new Cesium.Cartesian3())

将提供的笛卡尔分量除以提供的标量

  result.x = cartesian.x / scalar;
  result.y = cartesian.y / scalar;
  result.z = cartesian.z / scalar;
  • 1
  • 2
  • 3

Cesium.Cartesian3.divideComponents(left, right, new Cesium.Cartesian3())

两个笛卡尔坐标的分量商

  result.x = left.x / right.x;
  result.y = left.y / right.y;
  result.z = left.z / right.z;
  • 1
  • 2
  • 3

Cesium.Cartesian3.magnitude(cartesian)

求向量的长度(向量的模)(注:一个向量)

// 源码
return Math.sqrt(Cartesian3.magnitudeSquared(cartesian));
  • 1
  • 2

Cesium.Cartesian3.magnitudeSquared(cartesian)

求向量长度的平方(向量模的平方)(注:一个向量)

// 源码
return (cartesian.x * cartesian.x + cartesian.y * cartesian.y + cartesian.z * cartesian.z);
  • 1
  • 2

Cesium.Cartesian3.distance(left, right)

求两个向量之间的距离(注:求两点的直线距离)

 // 源码
 Cartesian3.subtract(left, right, distanceScratch);
  return Cartesian3.magnitude(distanceScratch);
  • 1
  • 2
  • 3

区别于直线距离,还有地表距离,可以用下面的方式计算:

// 求取地表两点距离  由经纬度返回弧度
 let startPosition1=new Cesium.Cartographic.fromDegrees(110,30);
 let endPosition1=new Cesium.Cartographic.fromDegrees(110,30.1);
 let geodesic = new Cesium.EllipsoidGeodesic(startPosition1,endPosition1);
 //设置测地线的起点和终点
 // geodesic.setEndPoints(startPosition1, endPosition1);
 let distance1 = geodesic.surfaceDistance;//求地表距离,单位为米
 console.log("两点的地表距离:",distance1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Cesium.Cartesian3.distanceSquared(left, right)

求两个向量之间距离的平方(注:两个向量)

  // 源码
  Cartesian3.subtract(left, right, distanceScratch);
  return Cartesian3.magnitudeSquared(distanceScratch);
  • 1
  • 2
  • 3

Cesium.Cartesian3.angleBetween(left, right)

求两个向量的夹角

  Cartesian3.normalize(left, angleBetweenScratch);
  Cartesian3.normalize(right, angleBetweenScratch2);
  const cosine = Cartesian3.dot(angleBetweenScratch, angleBetweenScratch2);
  const sine = Cartesian3.magnitude(
    Cartesian3.cross(
      angleBetweenScratch,
      angleBetweenScratch2,
      angleBetweenScratch
    )
  );
  return Math.atan2(sine, cosine);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/35276
推荐阅读
相关标签
  

闽ICP备14008679号