threejs系列之:几何变换(上)🍺

这里是 4. threejs系列之:几何变换(上):

往期回顾:

  1. # threejs系列:相机与投影 📷
  2. # threejs系列:光源与光照🪀
  3. # threejs系列:自定义几何体🎃

threejs 变换

物体变换通常代表物体的平移、旋转、缩放。在学习如何变换之前,我们来熟悉一下一些预备知识。

坐标轴

threejs 的坐标轴是遵循 openGL 的右手坐标系。如右图所示,四根手指的方向是Y 轴的正方向,大拇指指向的是X轴的正方向,手臂朝向身体的方向是Z轴的正方向。

threejs系列之:几何变换(上)🍺

threejs封装了一个坐标系辅助对象,展示三个轴的方向,红色代表 X 轴. 绿色代表 Y 轴. 蓝色代表 Z 轴。

threejs系列之:几何变换(上)🍺

向量 Vector3

在 Three.js 中,三维向量是具有三个分量的数字数组。这些分量通常表示在三维空间中的 x、y 和 z 坐标。

向量可以用来表示许多事物,例如:

  • 位置
  • 方向
  • 速度

在前面的文章中,我们接触到了很多的关于向量的东西,如上篇文章给BufferGeometry设置法向量就是方向,如给灯光设置位置就是位置,如给物体的位置每秒添加一个向量,这个向量就是速度

用法

new THREE.Vector3(x, y, z);

用法非常简单,就是设置 3 个标量。标量是什么? 标量是没有方向的具体的大小数值。

向量相加

const a = new THREE.Vector3(2, 3, 4);
const b = new THREE.Vector3(3, 4, 5);

// console.log(a.add(b));                              // 5,7,9
// console.log(new THREE.Vector3().addVectors(a, b))   // 5,7,9
// console.log(a.addScalar(2))                         // 4,5,6

当向量OA + 向量AC首尾相连时遵循三角形法则:

threejs系列之:几何变换(上)🍺

当向量OB + 向量OA起点相同时,遵循平行四边形法则

threejs系列之:几何变换(上)🍺

向量相减

// a.sub(b);                              // -1,-1, -1
// new THREE.Vector3().subVectors(a, b)   // -1, -1, -1
// a.subScalar(2)                         // 0, 1, 2

如下图,AC – AB,因为 AC = AB + BC,所以 AC – AB = AB + BC -AB = BC; 此处的AB、AC、BC都为向量。

threejs系列之:几何变换(上)🍺

向量相减通常用来计算两点的距离。

threejs系列之:几何变换(上)🍺

threejs系列之:几何变换(上)🍺

也可使用distanceTo方法计算(推荐)

a.distanceTo(b); 

向量相乘

// a.multiply(b);                              // 6,12, 20
// new THREE.Vector3().multiplyVectors(a, b)   // 6,12, 20
// a.multiplyScalar(2)                         // 4, 6, 8

向量点乘

a.dot(b);

点乘是什么?点乘是两个向量 xyz 相乘再相加的结果,可以用来判断两个向量的空间关系。

  • 如结果大于0,则方向基本相同,夹角在0°到90°之间

  • 如结果等于0,则正交,相互垂直

  • 如效果小于0,则方向基本相反,夹角在90°到180°之间

单位向量的点乘可以用来计算两个向量之间的夹角。


// a、b完全反方向
const a = new THREE.Vector3(5, 5, 0);
const b = new THREE.Vector3(-5, 5, 0);

let aUnit = a.normalize();
let bUnit = b.normalize();

const cos = aUnit.dot(bUnit); // 计算点积
const radian = Math.acos(cos); // 计算弧度
console.log(THREE.MathUtils.radToDeg(radian)); // 转角度 = 90

也可以使用angleTo 求两向量的夹角 (推荐)

a.angleTo(b)

向量叉乘

a.cross(b);
  • 向量叉乘的结果是一个向量,该向量垂直于输入的两个向量。
  • 向量叉乘的结果的大小等于两个向量所围成的平行四边形的面积。
  • 向量叉乘的结果的方向可以使用右手螺旋定则来确定。

通常用来计算法向量,在上篇文章中有使用到。

平移

平移是指物体往X、Y、Z的方向上进行移动,可通过修改物体的position属性实现,position属性是向量,所以看下下列情景。

  1. 设置物体往前 2 个距离
mesh.position.add(new THREE.Vector3(0, 0, 2));

mesh.position.addVectors(mesh.position, new THREE.Vector3(0, 0, 2));
  1. 判断物体距离坐标(5, 6, 7)有多远
mesh.position.distanceTo(new THREE.Vector(5, 6, 7))
  1. 求物体与坐标(5,6,7)的角度
THREE.MathUtils.radToDeg(mesh.position.angleTo(new THREE.Vector3(5, 6, 7)));

向量展示告一段落,还有很多没有介绍,后面用到会补充。

旋转

three.js 提供了两种表示三维旋转的方式:欧拉角(Euler angles)和四元数(Quaternions),以及两者之间的转换方法。

欧拉角 Euler

欧拉角是三维旋转的一种常用表示方式,它使用三个角度来描述物体绕XYZ轴的旋转。

new THREE.Euler(x, y, z , order)

前三个参数表示旋转的角度值,以弧度单位。第四个参数是旋转顺序,默认’XYZ’,正常不变。

弧度与角度

弧度是什么?在初中学习三角函数的时候大家肯定都背的滚瓜烂熟,弧度的定义是

等于半径长的圆弧所对的圆心角叫做1弧度的角。

threejs系列之:几何变换(上)🍺

知乎上有一篇三角函数动态详解,详细讲解了弧度和角度的关系,感兴趣的可前往了解。

总之记得弧度角度互换公式就行

  • 角度转弧度:角度 / 180 * Math.PI
  • 弧度转角度: 弧度 * 180 / Math.PI

在threejs中基本是以弧度为单位,所以用到角度弧度互转的地方有很多,threejs封装了数学方法类
THREE.MathUtils ,里面封装了很多繁琐的数学方法。

弧度转角度:THREE.MathUtils.radToDeg(),角度转弧度:THREE.MathUtils.degToRad();

例子:绕x轴做匀速旋转运动

let cube = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshStandardMaterial({ color: 0xCCCCCC }));

let animate = () => {
    requestAnimationFrame(animate);
    renderer.render(scene, camera);

    const euler = new THREE.Euler(0, THREE.MathUtils.degToRad(1), 0, 'XYZ');
    cube.position.applyEuler(euler);
}

我们定义了一个cube物体,然后定义了一个欧拉角,x参数为1角度,因为要使用弧度单位,所以我们使用了THREE.MathUtils.degToRad 转成弧度,最后物体应用了欧拉角。

threejs系列之:几何变换(上)🍺

物体(Object3D)的rotation属性是欧拉角,他会绕中心点旋转,通过.set方法来设置旋转角度

// 局部x方向上旋转
cube.rotation.x += 0.01;

threejs系列之:几何变换(上)🍺

我们可以使用物体的geometry.translate修改中心点

cube.geometry.translate(0, 0, 1);

threejs系列之:几何变换(上)🍺

缩放

缩放是指修改物体某一维度的大小,物体(Object3D)中属性叫做scale,也是一个向量,所以使用向量的所有方法进行花式缩放。

开发中常用于模型缩放、各种物体缩放等等

cube.scale.set(0.33, 0.33, 0.33);

很简单,这里就不展开叙述了

原文链接:https://juejin.cn/post/7315246744158044210 作者:兰奇

(0)
上一篇 2023年12月23日 下午4:22
下一篇 2023年12月23日 下午4:33

相关推荐

发表回复

登录后才能评论