Three.js中矩阵和向量的使用教程

提起矩阵,很容易让人想起我们曾经学不会的线性代数和离散数学,但是作为图形开发中的核心部分,它代表着每一次的运动和变换,就像鱼不能脱离水一样,矩阵并不是一个可以避之不谈的话题。

好消息是,Three.js帮助我们把许多矩阵运算封装成了一些顶层的方法,并提供了一个优秀的数学库,我们不太需要知道HowToCalc,只需要知道HowToUse,就可以得到绝大部分我们想要的东西。

这篇文章将要介绍的就是,如何在不了解内部结构的情况下在Three.js中使用矩阵和向量。

从一个例子开始

在讲解一些枯燥的概念前先举一个小例子,来简要说明一下为什么我们要使用矩阵方法。

Three.js中矩阵和向量的使用教程

这是我们最终要完成的效果。

首先,我们要创建三个几何体:

var box_geometry = new THREE.BoxGeometry(); var sphere_geometry = new THREE.SphereGeometry(0.5, 32, 32); var cylinder_geometry = new THREE.CylinderGeometry(0.1, 0.1, 0.5); var material = new THREE.MeshLambertMaterial({color: new THREE.Color(0.9, 0.55, 0.4)})

这三个几何体分别是盒子、球和圆柱体。

然后去创建三个网格,并将它们置入场景。

var box = new THREE.Mesh(box_geometry, material); var sphere = new THREE.Mesh(sphere_geometry, material); sphere.position.y += 1; var cylinder = new THREE.Mesh(cylinder_geometry, material); cylinder.position.y += 1.75; scene.add(box); scene.add(sphere); scene.add(cylinder);

这段代码将生成如下场景:

Three.js中矩阵和向量的使用教程

虽然不那么美观,但作为示例已经足够了,现在我希望这堆物体尺寸减半。通常我会把物体的scale属性减半,像这样:

box.scale.multiplyScalar(0.5); sphere.scale.multiplyScalar(0.5); cylinder.scale.multiplyScalar(0.5);

Three.js中矩阵和向量的使用教程

和想象中的有些偏差。我的本意是让这一组物体进行一个整体的缩放,并不想让它们彼此偏离,为了修正这件事,我需要根据其他对象的缩放重新计算每个对象的位置。但这并不是一件很难解决的问题,three.js提供了一种优雅的方式,来处理这个问题。我们可以定义一个空对象,然后将三个对象放在其中,然后将比例应用于父对象。

var pile = new THREE.Object3D(); pile.scale.multiplyScalar(0.5); pile.add(box); pile.add(sphere); pile.add(cylinder); scene.add(pile);

Three.js中矩阵和向量的使用教程

接下来我们做一点更有趣的事。

我将在这个物体组合里添加旋转,让我们尝试围绕球体表面旋转的那个圆柱体,就像他将要滑落一样。

Three.js中矩阵和向量的使用教程

它变成了这样,很明显,这不是我想要的东西。我们在这里有两个做法可供选择:第一,通过数学计算算出圆柱相对于球体的正确位置;第二,创建另一个Object3D,将圆柱和球放进去并旋转。这听上去挺复杂的,而且也很不酷。

所以,我们可以尝试自己去计算矩阵。

首先,我需要将属性maxtrixAutoUpdate设置为false,然后我就不能再通过position,scale和rotation去修改矩阵。

box.matrixAutoUpdate = false; sphere.matrixAutoUpdate = false; cylinder.matrixAutoUpdate = false;

现在,我将用applyMatrix方法来解决这个问题。具体做法是:为每个对象创建一个Matrix4,然后我们将矩阵与该矩阵相乘以应用后续操作。

var sphere_matrix = new THREE.Matrix4().makeTranslation(0.0, 1.0, 0.0); sphere.applyMatrix(sphere_matrix); var cylinder_matrix = sphere_matrix.clone(); cylinder_matrix.multiply(new THREE.Matrix4().makeTranslation(0.0, 0.75, 0.0)); cylinder.applyMatrix(cylinder_matrix);

这几步下来,可以让我们解锁很多知识,来看看这里发生了什么。

首先,我们把盒子单独留下,因为它不需要动。

接着,我创建了一个平移矩阵并把它应用到了球对象上。

最后,在圆柱体上,我clone了球的矩阵信息,并在此基础上又创建了一个新的平移矩阵,圆柱体将移动1.75。

Three.js中矩阵和向量的使用教程

理解了上面几步,你就会知道最后一步该做什么了。

只需要一行代码,作用在球上:

sphere_matrix.multiply(new THREE.Matrix4().makeRotationZ(-Math.PI * 0.25));

Three.js中矩阵和向量的使用教程

达成了想要的效果,很酷。

示例中用到的方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5a2fe0e921dcd0b53727acfe5690d425.html