图形学:Transform矩阵(3维 2维) 平移,旋转,缩放

0. 简介

在图形学领域中,Transform矩阵(变换矩阵)是一种表示图形对象在二维或三维空间中的位置、方向和大小变化的数学工具。它们用于执行各种图形变换,如平移、旋转、缩放。Transform矩阵通常表示为一个二维或三维矩阵,具体形式取决于空间的维度。

0.1 二维变换矩阵

  • 在二维图形学中,通常使用3x3的矩阵表示变换,其中最后一行通常是[0, 0, 1],因为二维变换不影响z轴。这个矩阵可以表示平移、旋转、缩放和剪切。
  • 例如,一个简单的二维平移矩阵可以写成:
   [ 1  0  tx ]
   [ 0  1  ty ]
   [ 0  0  1  ]

其中txty是平移的水平和垂直距离。

0.2 三维变换矩阵

  • 在三维图形学中,通常使用4x4的矩阵表示变换,其中最后一列通常是[0, 0, 0, 1]。这种矩阵可以表示平移、旋转、缩放以及更复杂的变换。
  • 一个简单的三维平移矩阵可以写成:
   [ 1  0  0  tx ]
   [ 0  1  0  ty ]
   [ 0  0  1  tz ]
   [ 0  0  0  1  ]

其中txtytz是平移的xyz轴距离。

不管是二维变换矩阵还是三维变换矩阵,它的最后一行都是齐次坐标,通常是[0, ... , 1]用于处理齐次坐标,使得可以用矩阵乘法来同时处理旋转和平移。

1. 举个例子

1.1 平移

给定的初始 Transform 矩阵如下:

[ 1  0  0  tx ]
[ 0  1  0  ty ]
[ 0  0  1  tz ]
[ 0  0  0  1  ]

希望在 x 轴增加 2 个单位,y 轴增加 1 个单位,z 轴减小 3 个单位。

1.1.1 计算过程

  1. 对 x 轴进行增加 2 个单位: 可以将 tx(原始平移量)增加 2 个单位。
  2. 对 y 轴进行增加 1 个单位: 将 ty(原始平移量)增加 1 个单位。
  3. 对 z 轴进行减小 3 个单位: 要使物体沿 z 轴负方向移动,需要将 tz 减小 3 个单位。

1.1.2 计算结果

[ 1  0  0  tx + 2 ]
[ 0  1  0  ty + 1 ]
[ 0  0  1  tz - 3 ]
[ 0  0  0     1   ]

这个新的矩阵表示了对原始物体进行了所需的平移操作。

1.2 旋转

1.2.1 2维旋转矩阵

```css
[ cos(θ)   -sin(θ) ]
[ sin(θ)    cos(θ) ]

1.2.1 3维旋转矩阵

  • 绕x轴旋转矩阵
[ 1     0        0      0 ]
[ 0  cos(θ)   -sin(θ)   0 ]
[ 0  sin(θ)    cos(θ)   0 ]
[ 0     0        0      1 ]
  • z轴旋转
[ cos(θ)  -sin(θ)   0   0 ]
[ sin(θ)   cos(θ)   0   0 ]
[    0       0      1   0 ]
[    0       0      0   1 ]
  • 绕y轴旋转
[ cos(θ)   0   sin(θ)   0 ]
[    0     1      0     0 ]
[-sin(θ)   0   cos(θ)   0 ]
[    0     0      0     1 ]

原始的Transform矩阵T与旋转矩阵R相乘,得到新的Transform矩阵 T'
T' = T * R

1.3 缩放

1.3.1 缩放矩阵

[ sx  0   0   0 ]
[ 0   sy  0   0 ]
[ 0   0   sz  0 ]
[ 0   0   0   1 ]

原始的Transform矩阵T与缩放矩阵S相乘,得到新的Transform矩阵 T'
T' = T * S

以下是一个使用C++和VS实现三角形绘制、平移旋转缩放的示例代码,使用变换矩阵实现: ```c++ #include <iostream> #include <graphics.h> #include <conio.h> #include <math.h> using namespace std; // 定义三角形的三个顶点 POINT p[3] = {{100, 100}, {200, 100}, {150, 200}}; // 定义三角形的中心点 POINT center = {150, 150}; // 定义旋转角度 double angle = 30; // 定义缩放比例 double scale = 1.5; // 定义变换矩阵 double transformMatrix[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}; // 绘制三角形 void drawTriangle() { // 设置线条颜色 setlinecolor(WHITE); // 绘制三角形 for(int i = 0; i < 3; i++) { int j = (i + 1) % 3; line(p[i].x, p[i].y, p[j].x, p[j].y); } } // 平移三角形 void translateTriangle(int dx, int dy) { // 更新变换矩阵 transformMatrix[0][2] += dx; transformMatrix[1][2] += dy; // 更新三角形的顶点坐标 for(int i = 0; i < 3; i++) { int x = p[i].x; int y = p[i].y; p[i].x = round(transformMatrix[0][0] * x + transformMatrix[0][1] * y + transformMatrix[0][2]); p[i].y = round(transformMatrix[1][0] * x + transformMatrix[1][1] * y + transformMatrix[1][2]); } } // 旋转三角形 void rotateTriangle(double angle) { // 计算旋转角度的弧度值 double radian = angle * 3.1415926 / 180; // 更新变换矩阵 transformMatrix[0][0] = cos(radian); transformMatrix[0][1] = -sin(radian); transformMatrix[1][0] = sin(radian); transformMatrix[1][1] = cos(radian); // 将坐标系原点移到三角形中心点 translateTriangle(-center.x, -center.y); // 更新三角形的顶点坐标 for(int i = 0; i < 3; i++) { int x = p[i].x; int y = p[i].y; p[i].x = round(transformMatrix[0][0] * x + transformMatrix[0][1] * y + transformMatrix[0][2]); p[i].y = round(transformMatrix[1][0] * x + transformMatrix[1][1] * y + transformMatrix[1][2]); } // 将坐标系原点移到原来的位置 translateTriangle(center.x, center.y); } // 缩放三角形 void scaleTriangle(double scale) { // 更新变换矩阵 transformMatrix[0][0] *= scale; transformMatrix[1][1] *= scale; // 将坐标系原点移到三角形中心点 translateTriangle(-center.x, -center.y); // 更新三角形的顶点坐标 for(int i = 0; i < 3; i++) { int x = p[i].x; int y = p[i].y; p[i].x = round(transformMatrix[0][0] * x + transformMatrix[0][1] * y + transformMatrix[0][2]); p[i].y = round(transformMatrix[1][0] * x + transformMatrix[1][1] * y + transformMatrix[1][2]); } // 将坐标系原点移到原来的位置 translateTriangle(center.x, center.y); } int main() { // 初始化绘图环境 initgraph(640, 480); // 绘制三角形 drawTriangle(); getch(); // 平移三角形 translateTriangle(50, 50); cleardevice(); drawTriangle(); getch(); // 旋转三角形 rotateTriangle(angle); cleardevice(); drawTriangle(); getch(); // 缩放三角形 scaleTriangle(scale); cleardevice(); drawTriangle(); getch(); // 关闭绘图环境 closegraph(); return 0; } ``` 在上面的代码中,我们使用了一个变换矩阵来实现三个图形变换函数:平移旋转缩放。每个函数都会更新变换矩阵,并使用变换矩阵计算三角形的新顶点坐标。在旋转缩放函数中,我们使用了平移函数来将坐标系原点移到三角形中心点,以便进行旋转缩放。 需要注意的是,在使用变换矩阵进行图形变换时,需要注意矩阵乘法的顺序。在本例中,我们将变换矩阵定义为一个 $3\times 3$ 的矩阵,其中前两行是旋转缩放矩阵,最后一行是平移矩阵。我们在计算新顶点坐标时,需要将每个顶点的坐标视为一个 $3\times 1$ 的矩阵,然后将变换矩阵与顶点坐标的矩阵相乘,得到新的顶点坐标的矩阵。最后,我们将新的顶点坐标的矩阵转换回普通的坐标形式,并更新三角形的顶点坐标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值