矩阵和向量在三个js中的使用教程
前言
说到矩阵,很容易让人想起我们学不会的线性代数和离散数学。然而,作为图形开发的核心部分,它代表了每一个运动和转变。就像鱼离不开水一样,矩阵也不是一个可以回避的话题。
好消息是,Three.js帮助我们将许多矩阵运算打包成一些顶级方法,并提供了一个优秀的数学库。我们不需要知道如何计算,我们只需要知道如何使用,我们就能得到我们想要的大部分东西。
本文将介绍如何在不知道内部结构的情况下,使用trial . js中的矩阵和向量。
从一个例子开始
在解释一些枯燥的概念之前,先举一个小例子来简要说明我们为什么要用矩阵法。
这是我们想要达到的最终结果。
首先,我们想要创建三个几何图形:
var box_geometry=new THREE。box geometry();var sphere_geometry=new THREE。球面测量法(0.5,32,32);变化圆柱体几何=新三。气缸几何形状(0.1、0.1、0.5);Var material=newthree。meshlambertmaterial({ color : new three。颜色(0.9、0.55、0.4)})这三种几何形状分别是长方体、球体和圆柱体。
然后创建三个网格,并将其放入场景中。
var box=new THREE。网格(box_geometry,材质);var sphere=new THREE。网格(球体_几何体,材质);sphere . position . y=1;可变气缸=新三缸。网格(圆柱体_几何体,材质);气缸位置=1.75scene.add(方框);scene.add(球体);scene.add(圆柱体);这段代码将生成以下场景:
虽然没有那么美,但作为例子已经足够了。现在我希望这堆物体的大小减半。通常我会将对象的比例属性减半,如下所示:
box . scale . multiplyscalar(0.5);球体.刻度.多刻度(0.5);圆柱体.刻度.多刻度(0.5);
与想象有一些偏差。我的意图是将这组对象作为一个整体来缩放,我不希望它们相互偏离。为了纠正这一点,我需要根据其他对象的缩放比例重新计算每个对象的位置。但这并不是一个很难解决的问题。three.js提供了一种优雅的方式来处理这个问题。我们可以定义一个空对象,然后在其中放置三个对象,然后将比例应用于父对象。
var pile=new THREE。object 3D();pile . scale . multiplyscalar(0.5);pile.add(方框);pile.add(球体);pile.add(圆柱体);scene.add(堆);
接下来,让我们做一些更有趣的事情。
我将为这个对象组合添加旋转。让我们试试绕球体表面旋转的圆柱体,就像它要滑下来一样。
事情变成了这样。显然,这不是我想要的。这里我们有两个选择:第一,通过数学计算,计算出圆柱体相对于球体的正确位置;其次,创建另一个Object3D,将圆柱体和球放入其中并旋转它。听起来很复杂,一点也不酷。
因此,我们可以尝试自己计算矩阵。
首先,我需要将属性maxtrixAutoUpdate设置为false,然后我就不能再通过位置、比例和旋转来修改矩阵了。
box.matrixAutoUpdate=falsesphere.matrixAutoUpdate=falsecylinder . matrix autoupdate=false;现在,我将使用applyMatrix方法来解决这个问题。为此,我们为每个对象创建一个矩阵4,然后将矩阵乘以矩阵以应用后续操作。
var sphere_matrix=new THREE。Matrix4()。makeTranslation(0.0,1.0,0.0);sphere . applymatrix(sphere _ matrix);var柱面_矩阵=球面_矩阵. clone();cylinder _ matrix.multiply(新三。Matrix4()。makeTranslation(0.0,0.75,0.0));柱面. applyMatrix(柱面_矩阵);有了这些步骤,我们可以解锁很多知识,看看这里发生了什么。
首先,我们把盒子放在一边,因为它不需要移动。
然后,我创建了一个翻译矩阵,并将其应用于球对象。
最后,在圆柱体上,我克隆了球的矩阵信息,并在此基础上创建了一个新的平移矩阵。圆柱体将移动1.75。
了解了以上步骤,你就知道最后一步该怎么做了。
只需要一行代码就可以对球进行操作:
sphere_matrix.multiply(新的三。Matrix4()。make rotationz(-数学。PI * 0.25));
达到了预期的效果,很酷。
示例中使用的方法
在上面的例子中,我将球和圆柱体沿着Y轴移动了一定的距离,并使用了makeTranslation的方法。这种方法的功能是创建一个翻译矩阵。然后,我再次使用了applyMatrix方法。该方法的作用是将平移矩阵应用于球体和圆柱体。
那么什么是翻译矩阵呢?它如何完成一个翻译?
Three.js中最常见的4x4矩阵称为变换矩阵,其变换类型包括平移、旋转和缩放。
用一个简单的数学问题解释转换矩阵:
有一个起点,用一个向量表示,就是向量3 (20,20,0);现在,我想把它移到另一个位置,Vector3(30,60,0)。
接下来,我设置一个平移矩阵来显示向量如何移动。
t=| 1 0 0 10 | | 0 1 0 40 | | 0 0 1 0 | | 0 0 1 |最后,将变换矩阵的向量乘以初始向量。
| 20 | | 10010 | | 30 | | 20 | x | 01040 |=| 60 | | 0 | | 0010 | | 0 | | 1 | | 0001 | | 1 |变换公式如下:
transformed vector=vector * transformation matrix
最终变换向量=原始向量*变换矩阵
使用我们上面例子中的方法来恢复这个公式,即:
var vector=new THREE。Vector3(20,20,0);var矩阵=新三。matrix 4();matrix.makeTranslation(10,40,0);vector.applyMatrix4(矩阵);除了翻译,三的API还提供旋转和缩放。比例的变化很简单,它会用makeScale(x,y,z)来表示比例。
旋转比较复杂,Three.js提供了以下旋转方法:
matrix.makeRotationX(角度);matrix.makeRotationY(角度);matrix.makeRotationZ(角度);matrix.makeRotationAxis(轴,角度);matrix.makeRotationFromEuler(欧拉);matrix.makeRotationFromQuaternion四元数(四元数);前三种方法表示围绕三个轴的旋转:x、y和z,因此无需重复。
第四种方法是前三种方法的集成版本。第一个参数代表三。代表xyz的向量3,第二个参数是旋转弧度。以下两行代码是等效的:
matrix.makeRotationX(数学。PI);matrix.makeRotationAxis(新三。向量3(1,0,0),数学。PI);第五种方法表示围绕x、y、z轴的旋转,这是最常见的表示旋转的方式;第六种方法是基于轴和角度表达旋转的替代方法。
最后,Three.js api提供了一种方法来创建一个表示平移、旋转和缩放组合的矩阵。
var翻译=new THREE。vector 3();var旋转=新三。四元数();var scale=new THREE。vector 3();var矩阵=新三。matrix 4();matrix.compose(平移、旋转、缩放);矩阵乘法
矩阵乘法的意义在于叠加。
上图显示了三个变化:旋转、缩放和移动。
通过依次相乘,三个变化矩阵可以得到最终的变化矩阵:
combined matrix=rotationMatrix * scale matrix * translation matrix;《三个一》中提供了两种矩阵乘法方法:
矩阵。乘法(其他矩阵)矩阵。乘法矩阵(matrixa,matrixb)第一种方法是将一个矩阵乘以另一个矩阵;第二种方法表示将矩阵设置为matrixA * matrixB的结果。
我们还使用了示例中的第一种方法:用新的平移矩阵乘以圆柱体矩阵,用旋转矩阵乘以球体矩阵。
需要注意的是,乘法交换定律不适用于矩阵乘法,矩阵乘法是有阶的,先旋转后移动和先移动后旋转的结果是完全不同的。
矩阵的逆
在数字的运算中,除法相当于乘法的“撤销”运算:
4 x 5=2020/5=4,但是在矩阵计算中,这个代码也不适用。我们不能用向量来去掉一个矩阵,我们只能用向量来乘以一个矩阵的逆矩阵来完成“撤销”的操作。
变化向量=原始向量*变化矩阵;逆矩阵=变化矩阵。逆();原始向量=变化向量*逆矩阵;
逆矩阵表示相反的变换。
Three.js提供了一种计算逆矩阵的方法:
var矩阵=新三。matrix 4();var inverseMatrix=new THREE。matrix 4();matrix.getInverse(逆矩阵);此外,在处理3D场景中的相机对象时也使用逆矩阵。
最后的
矩阵是3D世界中非常强大的工具,可以将任何变换表示为相似的结构,采用相同的计算过程。其实矩阵的世界远不止这里介绍的。希望通过这些简短的介绍,可以进入更深的领域,用它来处理图形开发中更复杂的场景。
好了,这就是本文的全部内容。希望本文的内容对大家的学习或工作有一定的参考价值。谢谢你的支持。
版权声明:矩阵和向量在三个js中的使用教程是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。