Three.js 旋转矩阵、平移矩阵、缩放矩阵
在 WebGL 中对一个对象进行平移、旋转或缩放本质就是对对象的顶点坐标进行平移、旋转、缩放矩阵变换。
关键词
在学习本节课之前最好对旋转、平移、缩放等变换矩阵有一定的了解,可以学习WebGL相关教程或图形学书籍。
平移矩阵
平移矩阵 T:表示一个顶点坐标沿着 X、Y、Z 轴分别平移 Tx、Ty、Tz
| 1 0 0 Tx |
| 0 1 0 Ty |
| 0 0 1 Tz |
| 0 0 0 1 |
一个点的坐标是(x, y, z),假设沿着 X、Y、Z 轴分别平移 Tx、Ty、Tz,毫无疑问平移后的坐标是(x+Tx, y+Ty, z+Tz)。
矩阵和表示顶点坐标的向量进行乘法运算
| 1 0 0 Tx | | x | | x+Tx |
| 0 1 0 Ty | x | y | = | y+Ty |
| 0 0 1 Tz | | z | | z+Tz |
| 0 0 0 1 | | 1 | | 1 |
缩放矩阵
比如一个几何体的所有顶点坐标沿着 X、Y、Z轴分别缩放矩阵 Sx、Sy、Sz 倍,可以用如下矩阵S表示。
| Sx 0 0 0 |
| 0 Sy 0 0 |
| 0 0 Sz 0 |
| 0 0 0 1 |
顶点坐标缩放变换
| Sx 0 0 0 | | x | | x*Sx |
| 0 Sy 0 0 | x | y | = | y*Sy |
| 0 0 Sz 0 | | z | | z*Sz |
| 0 0 0 1 | | 1 | | 1 |
旋转矩阵
绕x轴旋转 α 度对应的旋转矩阵 Rx
| 1 0 0 0 | | x | | x |
| 0 cosα -sinα 0 | x | y | = | cosα*y-sinα*z |
| 0 sinα cosα 0 | | z | | sinα*y+cosα*z |
| 0 0 0 1 | | 1 | | 1 |
绕y轴旋转α度对应的旋转矩阵Ry
| cosα 0 -sinα 0 | | x | | cosα*x+sinα*z |
| 0 1 0 0 | x | y | = | y |
| sinα 0 cosα 0 | | z | | -sinα*x+cosα*z |
| 0 0 0 1 | | 1 | | 1 |
绕z轴旋转α度对应的旋转矩阵Rz
| cosα -sinα 0 0 | | x | | cosα*x-sinα*y |
| sinα cosα 0 0 | x | y | | sinα*x+cosα*y |
| 0 0 1 0 | | z | | z |
| 0 0 0 1 | | 1 | | 1 |
创建变换矩阵
直接通过矩阵对象的 elements
属性或 .set()
方法设置常见变换矩阵的元素比较麻烦,比如设置一个缩放矩阵,Three.js 的 4x4 矩阵 Matrix4
对常见变换矩阵的设置封装了一些方法。
- 绕 x 轴旋转
.makeRotationX(theta)
- 绕 y 轴旋转
.makeRotationY(theta)
- 绕 z 轴旋转
.makeRotationZ(theta)
- 缩放
.makeScale(Sx,Sy,Sz)
- 平移
.makeTranslation(Tx,Ty,Tz)
- 剪切
.makeShear
平移矩阵创建案例
| 1 0 0 5 |
| 0 1 0 3 |
| 0 0 1 9 |
| 0 0 0 1 |
.set()
方法设置平移矩阵
var T = new THREE.Matrix4()
// set方法设置平移矩阵
T.set(
1, 0, 0, 5,
0, 1, 0, 3,
0, 0, 1, 9,
0, 0, 0, 1
)
makeTranslation 方法设置平移矩阵
var T = new THREE.Matrix4()
// 顶点坐标沿着X、Y、Z轴分别平移5,3,9
T.makeTranslation(5,3,9)
console.log('查看平移矩阵', T.elements);
向量矩阵变换 .applyMatrix4()
.applyMatrix4()
是三维向量 Vector3
的一个方法,
var T = new THREE.Matrix4()
// 创建一个平移矩阵,顶点坐标沿着X、Y、Z轴分别平移5,3,9
T.makeTranslation(5, 3, 9)
// 三维向量表示一个顶点坐标
var v1 = new THREE.Vector3(10,10,10);
// 向量进行矩阵变换
var v2 = v1.clone().applyMatrix4(T);
console.log('查看平移后坐标', v2);
多次变换
顶点坐标经过多次变换可以把多个变换矩阵进行乘法运算,然后再和表示顶点的坐标进行变换。
模型矩阵M、平移矩阵T、缩放矩阵S、旋转矩阵R、绕X轴旋转矩阵Rx、绕X轴旋转矩阵Ry、绕X轴旋转矩阵Rz
- 旋转矩阵: R = RxRyRz
- 模型矩阵:M = RST
- 顶点 V1 执行模型矩阵变换:V2 = M*V1
顶点进行两次平移变换代码
// 创建平移矩阵T1:x轴平移100
var T1 = new THREE.Matrix4().makeTranslation(100, 0, 0)
// 创建平移矩阵T2:y轴平移100
var T2 = new THREE.Matrix4().makeTranslation(0, 100, 0)
// 两个变换矩阵相乘表示顶点先后经过两次
var M = new THREE.Matrix4()
M.multiplyMatrices(T2,T1)
// 三维向量表示一个顶点坐标
var v1 = new THREE.Vector3(10, 10, 10);
// 向量进行矩阵变换
var v2 = v1.clone().applyMatrix4(M);
console.log('查看平移后坐标', v2);
Object3D
本地矩阵属性 .matrix
通过前面知识的学习,应该都知道对象 Object3D
的位置.position
、缩放.scale
、角度.rotation
等属性,这些属性本质上都是矩阵变换。Object3D
对象的.translateX()
、.translateZ()
等平移方法会改变.position
属性的值,Object3D
对象的.rotateX()
、.rotateZ()
等旋转方法会改变.rotation
属性的值,Three.js渲染模型解析的时候,Three.js会解析Object3D
对象位置.position
、缩放.scale
、角度.rotation
属性对应的平移、旋转、缩放矩阵相乘转化为本地矩阵.matrix
的属性值。
执行旋转方法.rotateZ()
查看,查看角度属性.rotation
属性值欧拉对象z属性的变化
// 一个网格模型对象,基类是Object3D
var mesh = new THREE.Mesh()
// 绕z轴旋转
mesh.rotateZ(Math.PI)
console.log('查看角度属性值的变化',mesh.rotation);
执行平移方法 .translateX()
查看,查看位置.position
属性值x分量变化
// 一个网格模型对象,基类是Object3D
var mesh = new THREE.Mesh()
// 沿着x轴平移100
mesh.translateX(100)
console.log('查看位置属性的变化',mesh.position);
查看位置 .position
、缩放 .scale
、角度 .rotation
等属性对本地矩阵属性 .matrix
的影响。Three.js渲染的时候会把模型的矩阵值传递给着色器对顶点进行矩阵变换,具体细节这里不展开讲解。
// 一个网格模型对象,基类是Object3D
var mesh = new THREE.Mesh()
// 缩放网格模型
mesh.scale.set(900,900,900)
// 位置、角度、缩放属性值更新到矩阵属性matrix
mesh.updateMatrix()
console.log('查看本地矩阵属性matrix',mesh.matrix.elements);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论