Three.js笔记(五)变换坐标
简述
现在探索Three.js功能。
在为场景制作动画之前,我们需要知道如何变换场景中的对象。
我们已经使⽤相机完成了此操作,⽅法是使⽤
camera.position.z = 3
有 4 个属性可⽤于变换对象
position(移动对象)
scale(调整对象⼤⼩)
rotation(旋转对象)
quaternion(也可以旋转对象;稍后会详细介绍)
从Object类继承的透视相机类、⽹格体类以及我们尚未介绍的类都具有这样的属性。
您可以在 Three.js ⽂档看到哪些类继承了这个类。
电话会议英文
这些属性将被编译为我们所谓的矩阵。矩阵 在Three.js、WebGL 和 GPU 内部使⽤,⽤于变换对象坐标。幸运的是,不必⾃⼰处理矩阵,只需修改前⾯提到的属性即可。
设置
在⼀开始,画布中只有之前⼏节创建的⽴⽅体,⽴⽅体处在视⾓中⼼。
dream是什么意思
移动对象
position位置具有 3 个基本属性x、y、z。
每个轴的⽅向都是⾃⼰定义的。在 Three.js 中,我们通常认为y轴向上,z轴向后,x轴向右。
⾄于数量1的单位也可以是任意的,这根据⾃⼰的需要来决定。
尝试调整mesh⽹格体的position位置属性,推测下⽴⽅体会去哪⾥。
请确保在执⾏渲染操作render()前完成移动操作,否则⽹格体会在移动前被渲染。
mesh.position.x = 0.7
mesh.position.y = - 0.6
mesh.position.z = 1
position位置不是对象。它是Vector3类的⼀个实例,不光有x、y、z属性,还有许多拥有的⽅法。
可以得到向量的模
武汉健身教练培训
console.log(mesh.position.length())
两个Vector3类之间的距离,但以下代码先要确保创建相机后运⾏
console.log(mesh.position.distanceTo(camera.position))
您可以规范化其值(这意味着您将向量的长度减少到单位1,但保留其⽅向):
console.log(alize())将来完成时
若要更改值,⽽不是单独更改 x、y、z,还可以使⽤以下⽅法:
mesh.position.t(0.7, - 0.6, 1)
辅助轴
在空间中盲⽬定位很困难,尤其是在移动相机之后就更加困难。此时就需要调⽤Three.js的AxesHelper辅助轴。AxesHelper辅助轴会从场景中⼼向x、y、z⽅向放射出与轴同向的线。
要创建AxesHelper辅助轴,⾸先需要实例化并在实例化场景后,将其添加到场景,可以通过⼀个参数修改线的长度。
beforehand
/**
* AxesHelper辅助轴
*/
const axesHelper = new THREE.AxesHelper(2)
scene.add(axesHelper)
此时应该看到
红线。
绿线和⼀条红
您应该看到⼀条绿
蓝线对应于z轴,但看不到它,因为它与相机完全同向。
红线对应于x轴,有⼀条蓝
绿线对应于y轴。红裙子的拼音
如果需要视觉参考,请随时添加它。
缩放对象
scale缩放也是Vector3。默认情况下,x、y、z都是1。这就意味着对象没有被缩放。如果设置成0.5,对象将在该轴⽅向上的尺⼨缩⼩⼀半;如果设置成2,对象将在该轴⽅向上的尺⼨放⼤⼀倍。
如果更改了这些值,对象将会相应缩放。注释掉之前的position位置,然后添加缩放
mesh.scale.x = 2
mesh.scale.y = 0.25
mesh.scale.z = 0.5
很明显,⽆法直观的看到z轴的缩放,因为⽹格体是正对相机的。
缩放可以使⽤负值,但是会出现BUG,尽量避免这样做。
旋转对象
旋转有两个不同的属性,rotation旋转和quaternion四元数两种,当修改⼀个,另⼀个也会有相应变化。
旋转
rotation旋转也有x、y、z,但是它不是Vector3,⽽是欧拉数。当更改欧拉数的x、y、z时,你可以想象是绕对应轴旋转对象的操作。
旋转的值以弧度表⽰,如果想要实现旋转半圈,就需要写Π。在JavaScript的原⽣环境中,可以使⽤Math.PI,来表⽰这个数。
注释掉之前的scale缩放,然后添加绕x、y轴⼋分之⼀圈的旋转。
容易吧?但是当把这些旋转混合在⼀起,反⽽会出现不同的结果。其原因就在于当绕x旋转时,同时也影响了其他两个轴的⽅向。这就导致了旋转的结果和预期的不同。
我们可以使⽤reorder()⽅法来更正旋转的顺序,der('yxz')
虽然欧拉数易于理解,但是旋转的顺序会导致这些问题。这就是为什么⼤多数引擎和3D软件使⽤quaternion四元数⽅案
四元数
Quaternion四元数属性同样表达了旋转,但是使⽤了更数学化的⽅式,从⽽解决了顺序的问题。
这⾥不会讲解四元数如何运作,但是要记得Quaternion四元数随rotation旋转的变化⽽更新。这意味着可以随意使⽤两者中的任何⼀个。
⼤突破
tapestry
special forceObject3D实例有⼀个很棒的⽅法,名字是lookAt(),这个⽅法可以控制对象直接⾯向某个东西。对象会⾃动将-z轴旋转到提供的⽬标,⽽⽆需复杂的数学。
这可以被⽤在将相机看向物体的操作上,或是将⼤炮定向以⾯对敌⼈,或将⾓⾊的眼睛移动到物体上。
该参数是⽬标,必须是 Vector3。可以尝试创建⼀个:
camera.lookAt(new THREE.Vector3(0, - 1, 0))
⽴⽅体似乎变⾼了,但实际上,相机正在观察⽴⽅体下⽅。
我们也可以使⽤任何现有的 Vector3,例如前⾯的⽹格体的位置,但这将导致相机指向默认的位置,因为我们位于场景的中⼼。
camera.lookAt(mesh.position)
组合变换
可以将position(移动对象)、scale(调整对象⼤⼩)、rotation(旋转对象 也可以⽤quaternion)以任意顺序组合。运⾏的结果将是相同的。因为它就是对象的状态。
尝试把之前的所有变换组合在⼀起
mesh.position.x = 0.7
mesh.position.y = - 0.6
mesh.position.z = 1
mesh.scale.x = 2
mesh.scale.y = 0.25
mesh.scale.z = 0.5
场景分组
在某些时候,可能希望对事物进⾏分组。假设正在建造⼀座有墙壁,门,窗户,屋顶,灌⽊丛等的房⼦。
当认为已经完成了时,可能就会意识到房⼦太⼩了,那么必须重新缩放每个对象并更新它们的位置。
⼀个好的替代⽅法是将所有这些对象分组到⼀个容器中,并缩放该容器。
可以使⽤Group组类执⾏此操作。
实例化Group组,并把它添加到场景。现在,当要创建⼀个新的对象的时候,只需使⽤add()⽅法把他添加到组中,⽽⾮直接添加到场景中。
由于Group组类继承了Object3D类,所以它也具备前述的所有属性和⽅法。
注释掉之前的lookAt()调⽤,创建三个⽴⽅体并添加到⼀个组中,来替代之前的⽴⽅体。然后向组应⽤变换。
wiper是什么意思/**
* 创建对象
*/
const group = new THREE.Group()
group.scale.y = 2
scene.add(group)
const cube1 = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0xff0000 }) )
cube1.position.x = - 1.5november怎么读
group.add(cube1)
const cube2 = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0xff0000 }) )
cube2.position.x = 0
group.add(cube2)
const cube3 = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0xff0000 }) )
cube3.position.x = 1.5
group.add(cube3)