Three.js 旋转矩阵、平移矩阵、缩放矩阵

发布于 2021-11-08 19:32:44 字数 5693 浏览 1746 评论 0

在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

虐人心

有一天你能到我的心里去,你会看到那里全是你给的伤悲。

0 文章
0 评论
24515 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文