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);
本站版权所有,本站任何内容未经允许不得转载   备案号:豫ICP备16004767号