本篇简单介绍three.js
中矩阵变换及两种旋转表达方式。
矩阵变换
three.js
使用矩阵来保存Object3D
的变换信息。
矩阵变换的基础
平移变换
比例变换
旋转变换
(x,y,z,1)
绕x
轴旋转
(x,y,z,1)
绕y
轴旋转
(x,y,z,1)
绕z
轴旋转
three.js
中的矩阵
<pre style="margin: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background-color, border-color, border-radius, padding, margin, color, opacity; overflow: auto; font-family: "Courier New"; font-size: 12px; overflow-wrap: break-word;"> var cube = new THREE.Mesh(new THREE.CubeGeometry(1,1,1),new THREE.MeshBasicMaterial());
cube.position.set(1,2,3);
cube.scale.set(7,8,9);
scene.add(cube);</pre>
我们可以看到正如上面的公式 cube
的平移(1,2,3)
所以elements[12]、elements[13]、elements[14]依次为1,2,3
cube
的缩放为(7,8,9)所以elements[0]、elements[5]、elements[10]依次为7,8,9
然后我们选择一下cube
的x
轴
<pre style="margin: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background-color, border-color, border-radius, padding, margin, color, opacity; overflow: auto; font-family: "Courier New"; font-size: 12px; overflow-wrap: break-word;">var cube = new THREE.Mesh(new THREE.CubeGeometry(1,1,1),new THREE.MeshBasicMaterial());
cube.rotation.x = Math.PI/3;//60°(2πr=C(圆周长)=>π =0.5C(半弧长)/r =>π弧度=180° =>π/3=60°) scene.add(cube);</pre>
三维旋转表达方式
three.js
提供了两种三维旋转表达方式:欧拉角(euler)
和四元数(quaternion)
。它们相比较使用矩阵的方式
进行变换更加的节省存储空间和更方便的进行插值。
但是欧拉角(euler)
存在万向锁问题,配置可能失去一定的自由度所以都是使用在四元数(quaternion)
。
欧拉角
欧拉角需要指定x,y,z三个轴的角度和旋转的顺序。
<pre style="margin: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background-color, border-color, border-radius, padding, margin, color, opacity; overflow: auto; font-family: "Courier New"; font-size: 12px; overflow-wrap: break-word;">Euler( x, y, z, order )</pre>
万向锁
问题:当三个万向节其中两个的轴发生重合时,会失去一个自由度的情形。
正常状态:三个独立的旋转轴
万向锁:一旦选择±90°作为pitch角,就会导致第一次旋转和第三次旋转等价,整个旋转表示系统被限制在只能绕竖直轴旋转,丢失了一个表示维度。
四元数
四元数的出现就可以解决欧拉角的万向锁问题和万向锁带来的插值不是线性的问题。
具体的四元数在旋转的使用的原理可以参照:
<pre style="margin: 0px; padding: 0px; transition-duration: 0.2s; transition-property: background-color, border-color, border-radius, padding, margin, color, opacity; overflow: auto; font-family: "Courier New"; font-size: 12px; overflow-wrap: break-word;">Quaternion( x, y, z, w )</pre>