计算机图形学13:三维图形的几何变换
作者:非妃是公主
专栏:《计算机图形学》
博客地址:https://blog.csdn.net/myf_666
个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩
文章目录
- 专栏推荐
- 专栏系列文章
- 序
- 一、三维图形的几何变换
- 二、数据结构及工具函数定义
- 三、平移变换
- 1. 平移变换矩阵
- 2. 代码实现
- 3. 效果展示
- 四、比例变换
- 1. 比例变换矩阵
- 2. 代码实现
- 3. 效果展示
- 五、旋转变换
- 1. 旋转变换矩阵
- 2. 代码实现
- 3. 效果展示
- 六、对称变换
- 1. 关于坐标平面对称变换矩阵
- 2. 关于坐标轴对称变换矩阵
- 3. 代码实现
- 4. 效果展示
- 七、错切变换
- 1. 变换矩阵
- 2. 代码实现
- 3. 效果展示
- 八、相对任意参考点的复合变换
- 九、相对任意方向的复合变换
- the end……
专栏推荐
专栏名称 | 专栏地址 |
---|---|
软件工程 | 专栏——软件工程 |
计算机图形学 | 专栏——计算机图形学 |
操作系统 | 专栏——操作系统 |
软件测试 | 专栏——软件测试 |
机器学习 | 专栏——机器学习 |
数据库 | 专栏——数据库 |
算法 | 专栏——算法 |
专栏系列文章
文章名称 | 文章地址 |
---|---|
直线生成算法(DDA算法) | 计算机图形学01——DDA算法 |
中点BH算法绘制直线 | 计算机图形学02——中点BH算法 |
改进的中点BH算法 | 计算机图形学03——改进的中点BH算法 |
中点Bresenham画椭圆 | 计算机图形学04——中点BH绘制椭圆 |
中点BH算法绘制任意斜率直线 | 计算机图形学05——中点BH算法绘制任意斜率的直线 |
中点Bresenham画圆 | 计算机图形学06——中点BH算法画圆 |
有效边表法的多边形扫描转换 | 计算机图形学07——有效边表法绘制填充多边形 |
中点BH算法绘制抛物线 100 x = y 2 100x = y^2 100x=y2 | 计算机图形学08——中点BH绘制抛物线 |
二维观察之点的裁剪 | 计算机图形学09——二维观察之点裁剪 |
二维观察之线的裁剪 | 计算机图形学10——二维观察之线裁剪 |
二维观察之多边形的裁剪 | 计算机图形学11——二维观察之多边形裁剪 |
二维图形的几何变换 | 计算机图形学12——二维图形几何变换 |
三维图形的几何变换 | 计算机图形学13——三维图形几何变换 |
三维图形的投影变换 | 计算机图形学14——三维图形投影变换 |
序
计算机图形学(英语:computer graphics,缩写为CG)是研究计算机在硬件和软件的帮助下创建计算机图形的科学学科,是计算机科学的一个分支领域,主要关注数字合成与操作视觉的图形内容。虽然这个词通常被认为是指三维图形,事实上同时包括了二维图形以及影像处理。
一、三维图形的几何变换
对三维图形的几何信息经过平移、比例、旋转等变换后生成新的三维图形,复杂图形的几何变换可通过变换矩阵对图形的基本元素点、线、面作用,其中对点的矩阵是基础。
其中的变换形式如下:
[ x ′ y ′ z ′ 1 ] = T 2 D ⋅ [ x y z 1 ] = [ a b c p d e f q h i j r l m n s ] ⋅ [ x y z 1 ] \begin{bmatrix} x'\\y'\\z'\\1\\ \end{bmatrix}=T_{2D}\cdot\begin{bmatrix} x\\ y\\ z\\ 1\\ \end{bmatrix}=\begin{bmatrix} a&b&c&p\\ d&e&f&q\\ h&i&j&r\\ l&m&n&s\\ \end{bmatrix}\cdot\begin{bmatrix} x\\ y\\ z\\ 1\\ \end{bmatrix} x′y′z′1 =T2D⋅ xyz1 = adhlbeimcfjnpqrs ⋅ xyz1
二、数据结构及工具函数定义
struct VERTEX3D { double x, y, z; }; // 三维空间点结构
#define PI acos(-1)
/// <summary>
/// 矩阵结构体
/// </summary>
struct Matrix {vector<vector<double>> matrix;Matrix() { // 初始化为 4 * 4 的矩阵matrix = vector<vector<double>>(4, vector<double>(4, 0.0));}Matrix(int m, int n) { // 初始化为 m * n 的矩阵matrix = vector<vector<double>>(m, vector<double>(n, 0.0));}friend ostream& operator<<(ostream& out, Matrix& m) {for (int i = 0; i < m.matrix.size(); i++) {for (int j = 0; j < m.matrix[0].size(); j++) {out << m.matrix[i][j] << " ";}out << endl;}return out;}
};/// <summary>
/// 矩阵相乘
/// </summary>
/// <param name="m1">矩阵相乘的第一个矩阵</param>
/// <param name="m2">矩阵相乘的第二个矩阵</param>
/// <returns></returns>
Matrix dotMatrix(Matrix m1, Matrix m2) {Matrix res;for (int i = 0; i < m1.matrix.size(); i++) {for (int j = 0; j < m2.matrix[0].size(); j++) {for (int k = 0; k < m1.matrix[0].size(); k++) {res.matrix[i][j] += m1.matrix[i][k] * m2.matrix[k][j];}}}return res;
}/// <summary>
/// 将点转化为其次坐标
/// </summary>
/// <param name="vertex">点</param>
/// <returns>齐次坐标</returns>
Matrix vertex3D2qici(VERTEX3D vertex3D) {Matrix qiciVertex(4, 1);qiciVertex.matrix[0][0] = vertex3D.x;qiciVertex.matrix[1][0] = vertex3D.y;qiciVertex.matrix[2][0] = vertex3D.z;qiciVertex.matrix[3][0] = 1;return qiciVertex;
}
三、平移变换
1. 平移变换矩阵
T t = [ 1 0 0 t x 0 1 0 t y 0 0 1 t z 0 0 0 1 ] T_{t}=\begin{bmatrix} 1&0&0&t_x\\ 0&1&0&t_y\\ 0&0&1&t_z\\ 0&0&0&1\\ \end{bmatrix}\ Tt= 100001000010txtytz1
2. 代码实现
/// <summary>
/// 三维坐标平移变换
/// </summary>
/// <param name="vertex3D">待平移地三维点</param>
/// <param name="x">x方向平移距离</param>
/// <param name="y">y方向平移距离</param>
/// <param name="z">z方向平移距离</param>
/// <returns>平移后的三维点坐标</returns>
VERTEX3D transTransform3D(VERTEX3D vertex3D, int x, int y, int z) {Matrix qiciVertex= vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 变换矩阵transform.matrix[0][0] = 1;transform.matrix[1][1] = 1;transform.matrix[2][2] = 1;transform.matrix[3][3] = 1;// 设置各方向平移距离transform.matrix[0][3] = x;transform.matrix[1][3] = y;transform.matrix[2][3] = z;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}
3. 效果展示
测试代码如下:
void testTransTransform() {VERTEX3D vertex3D = { 0,1,0 };VERTEX3D res = transTransform3D(vertex3D, 1, -1, 1);cout << res.x << " " << res.y << " " << res.z << endl;
}
点(0,1,0)在x,y,z三个方向上分别平移(1,-1,1)个单位后,坐标为(1,0,1),如下图所示:
四、比例变换
1. 比例变换矩阵
T t = [ a 0 0 0 0 e 0 0 0 0 j 0 0 0 0 1 ] T_{t}=\begin{bmatrix} a&0&0&0\\ 0&e&0&0\\ 0&0&j&0\\ 0&0&0&1\\ \end{bmatrix}\ Tt= a0000e0000j00001
2. 代码实现
/// <summary>
/// 三维坐标比例变换
/// </summary>
/// <param name="vertex3D">待变换的三维点</param>
/// <param name="x">x方向变换比例</param>
/// <param name="y">y方向变换比例</param>
/// <param name="z">z方向变换比例</param>
/// <returns>比例变换后的三维点坐标</returns>
VERTEX3D scaleTransform3D(VERTEX3D vertex3D, double scaleX, int scaleY, int scaleZ) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 变换矩阵transform.matrix[0][0] = scaleX;transform.matrix[1][1] = scaleY;transform.matrix[2][2] = scaleZ;transform.matrix[3][3] = 1;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}
3. 效果展示
测试代码如下:
void testScaleTransform3D() {VERTEX3D vertex3D = { 1,1,2 };VERTEX3D res = scaleTransform3D(vertex3D, 5, -2, 3);cout << res.x << " " << res.y << " " << res.z << endl;
}
五、旋转变换
1. 旋转变换矩阵
旋转变换分为x、y、z三个方向上的旋转,遵循右手定则,拇指指向坐标轴的方向,手指的方向为正方向。
绕X轴旋转变换矩阵:
T R X = [ 1 0 0 0 0 c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 ] T_{RX}=\begin{bmatrix} 1&0&0&0\\ 0&cos\theta&-sin\theta&0\\ 0&sin\theta&cos\theta&0\\ 0&0&0&1\\ \end{bmatrix}\ TRX= 10000cosθsinθ00−sinθcosθ00001
绕Y轴旋转变换矩阵:
T R Y = [ c o s θ 0 s i n θ 0 0 1 0 0 − s i n θ 0 c o s θ 0 0 0 0 1 ] T_{RY}=\begin{bmatrix} cos\theta&0&sin\theta&0\\ 0&1&0&0\\ -sin\theta&0&cos\theta&0\\ 0&0&0&1\\ \end{bmatrix}\ TRY= cosθ0−sinθ00100sinθ0cosθ00001
绕Z轴旋转变换矩阵:
T R Z = [ c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ] T_{RZ}=\begin{bmatrix} cos\theta&-sin\theta&0&0\\ sin\theta&cos\theta&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix}\ TRZ= cosθsinθ00−sinθcosθ0000100001
2. 代码实现
VERTEX3D rotationForXTransform3D(VERTEX3D vertex3D, double theta) {Matrix qiciVertex(4, 1); // 转化为其次坐标qiciVertex.matrix[0][0] = vertex3D.x;qiciVertex.matrix[1][0] = vertex3D.y;qiciVertex.matrix[2][0] = vertex3D.z;qiciVertex.matrix[3][0] = 1;Matrix transform; // 变换矩阵transform.matrix[0][0] = 1;transform.matrix[1][1] = cos(2 * PI * theta / 360);transform.matrix[2][2] = cos(2 * PI * theta / 360);transform.matrix[3][3] = 1;transform.matrix[1][2] = -sin(2 * PI * theta / 360);transform.matrix[2][1] = sin(2 * PI * theta / 360);// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}VERTEX3D rotationForYTransform3D(VERTEX3D vertex3D, double theta) {Matrix qiciVertex(4, 1); // 转化为其次坐标qiciVertex.matrix[0][0] = vertex3D.x;qiciVertex.matrix[1][0] = vertex3D.y;qiciVertex.matrix[2][0] = vertex3D.z;qiciVertex.matrix[3][0] = 1;Matrix transform; // 变换矩阵transform.matrix[0][0] = cos(2 * PI * theta / 360);transform.matrix[1][1] = 1;transform.matrix[2][2] = cos(2 * PI * theta / 360);transform.matrix[3][3] = 1;transform.matrix[0][2] = sin(2 * PI * theta / 360);transform.matrix[2][0] = -sin(2 * PI * theta / 360);// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}VERTEX3D rotationForZTransform3D(VERTEX3D vertex3D, double theta) {Matrix qiciVertex(4, 1); // 转化为其次坐标qiciVertex.matrix[0][0] = vertex3D.x;qiciVertex.matrix[1][0] = vertex3D.y;qiciVertex.matrix[2][0] = vertex3D.z;qiciVertex.matrix[3][0] = 1;Matrix transform; // 变换矩阵transform.matrix[0][0] = cos(2 * PI * theta / 360);transform.matrix[1][1] = cos(2 * PI * theta / 360);transform.matrix[2][2] = 1;transform.matrix[3][3] = 1;transform.matrix[0][1] = -sin(2 * PI * theta / 360);transform.matrix[1][0] = sin(2 * PI * theta / 360);// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}
3. 效果展示
测试代码如下:
void testRotationForXTransform3D() {VERTEX3D vertex3D = { 1,1,1 };VERTEX3D res = rotationForXTransform3D(vertex3D, 135);cout << res.x << " " << res.y << " " << res.z << endl;
}void testRotationForYTransform3D() {VERTEX3D vertex3D = { 1,1,1 };VERTEX3D res = rotationForYTransform3D(vertex3D, 135);cout << res.x << " " << res.y << " " << res.z << endl;
}void testRotationForZTransform3D() {VERTEX3D vertex3D = { 1,1,1 };VERTEX3D res = rotationForZTransform3D(vertex3D, 135);cout << res.x << " " << res.y << " " << res.z << endl;
}
三个测试代码分别表示沿x,y,z轴旋转135度。
六、对称变换
对称变换包括关于xoy、yoz、zox三个平面对称,还包括,关于x轴、y轴、z轴对称,变换矩阵分别如下:
1. 关于坐标平面对称变换矩阵
关于xoy平面对称,因此x、y坐标不变,z坐标变为相反数(-z):
T F x y = [ 1 0 0 0 0 1 0 0 0 0 − 1 0 0 0 0 1 ] T_{Fxy}=\begin{bmatrix} 1&0&0&0\\ 0&1&0&0\\ 0&0&-1&0\\ 0&0&0&1\\ \end{bmatrix}\ TFxy= 1000010000−100001
同理可得,关于yoz平面对称:
T F y z = [ − 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 ] T_{Fyz}=\begin{bmatrix} -1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix}\ TFyz= −1000010000100001
关于zox平面对称:
T F z x = [ 1 0 0 0 0 − 1 0 0 0 0 1 0 0 0 0 1 ] T_{Fzx}=\begin{bmatrix} 1&0&0&0\\ 0&-1&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix}\ TFzx= 10000−10000100001
2. 关于坐标轴对称变换矩阵
关于x轴对称,因此x坐标不变,y、z坐标变为相反数(-y、-z):
T F x = [ 1 0 0 0 0 − 1 0 0 0 0 − 1 0 0 0 0 1 ] T_{Fx}=\begin{bmatrix} 1&0&0&0\\ 0&-1&0&0\\ 0&0&-1&0\\ 0&0&0&1\\ \end{bmatrix}\ TFx= 10000−10000−100001
同理可得,关于y轴对称:
T F y = [ − 1 0 0 0 0 1 0 0 0 0 − 1 0 0 0 0 1 ] T_{Fy}=\begin{bmatrix} -1&0&0&0\\ 0&1&0&0\\ 0&0&-1&0\\ 0&0&0&1\\ \end{bmatrix}\ TFy= −1000010000−100001
关于z轴对称:
T F z = [ − 1 0 0 0 0 − 1 0 0 0 0 1 0 0 0 0 1 ] T_{Fz}=\begin{bmatrix} -1&0&0&0\\ 0&-1&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix}\ TFz= −10000−10000100001
3. 代码实现
/// <summary>
/// x轴镜像/对称变换
/// </summary>
/// <param name="vertex3D">待变换的三维点</param>
/// <returns>比例变换后的三维点坐标</returns>
VERTEX3D symmetryForXTransform3D(VERTEX3D vertex3D) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 变换矩阵transform.matrix[0][0] = 1;transform.matrix[1][1] = -1;transform.matrix[2][2] = -1;transform.matrix[3][3] = 1;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}/// <summary>
/// y轴镜像/对称变换
/// </summary>
/// <param name="vertex3D">待变换的三维点</param>
/// <returns>比例变换后的三维点坐标</returns>
VERTEX3D symmetryForYTransform3D(VERTEX3D vertex3D) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 变换矩阵transform.matrix[0][0] = -1;transform.matrix[1][1] = 1;transform.matrix[2][2] = -1;transform.matrix[3][3] = 1;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}/// <summary>
/// z轴镜像/对称变换
/// </summary>
/// <param name="vertex3D">待变换的三维点</param>
/// <returns>比例变换后的三维点坐标</returns>
VERTEX3D symmetryForZTransform3D(VERTEX3D vertex3D) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 变换矩阵transform.matrix[0][0] = -1;transform.matrix[1][1] = -1;transform.matrix[2][2] = 1;transform.matrix[3][3] = 1;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}/// <summary>
/// XOY轴镜像/对称变换
/// </summary>
/// <param name="vertex3D">待变换的三维点</param>
/// <returns>比例变换后的三维点坐标</returns>
VERTEX3D symmetryForXOYTransform3D(VERTEX3D vertex3D) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 变换矩阵transform.matrix[0][0] = 1;transform.matrix[1][1] = 1;transform.matrix[2][2] = -1;transform.matrix[3][3] = 1;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}/// <summary>
/// YOZ轴镜像/对称变换
/// </summary>
/// <param name="vertex3D">待变换的三维点</param>
/// <returns>比例变换后的三维点坐标</returns>
VERTEX3D symmetryForYOZTransform3D(VERTEX3D vertex3D) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 变换矩阵transform.matrix[0][0] = -1;transform.matrix[1][1] = 1;transform.matrix[2][2] = 1;transform.matrix[3][3] = 1;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}/// <summary>
/// ZOX轴镜像/对称变换
/// </summary>
/// <param name="vertex3D">待变换的三维点</param>
/// <returns>比例变换后的三维点坐标</returns>
VERTEX3D symmetryForZOXTransform3D(VERTEX3D vertex3D) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 变换矩阵transform.matrix[0][0] = 1;transform.matrix[1][1] = -1;transform.matrix[2][2] = 1;transform.matrix[3][3] = 1;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}
4. 效果展示
坐标点(4,3,2)关于坐标平面、坐标轴对称的结果如下:
测试代码如下:
void testSymmetryForXTransform3D() {VERTEX3D vertex3D = { 4,3,2 };VERTEX3D res = symmetryForXTransform3D(vertex3D);cout << res.x << " " << res.y << " " << res.z << endl;
}void testSymmetryForYTransform3D() {VERTEX3D vertex3D = { 4,3,2 };VERTEX3D res = symmetryForYTransform3D(vertex3D);cout << res.x << " " << res.y << " " << res.z << endl;
}void testSymmetryForZTransform3D() {VERTEX3D vertex3D = { 4,3,2 };VERTEX3D res = symmetryForZTransform3D(vertex3D);cout << res.x << " " << res.y << " " << res.z << endl;
}void testSymmetryForXOYTransform3D() {VERTEX3D vertex3D = { 4,3,2 };VERTEX3D res = symmetryForXOYTransform3D(vertex3D);cout << res.x << " " << res.y << " " << res.z << endl;
}void testSymmetryForYOZTransform3D() {VERTEX3D vertex3D = { 4,3,2 };VERTEX3D res = symmetryForYOZTransform3D(vertex3D);cout << res.x << " " << res.y << " " << res.z << endl;
}void testSymmetryForZOXTransform3D() {VERTEX3D vertex3D = { 4,3,2 };VERTEX3D res = symmetryForZOXTransform3D(vertex3D);cout << res.x << " " << res.y << " " << res.z << endl;
}
七、错切变换
错切变换同样分为3种,分别为x、y、z三个方向进行变换。具体变换矩阵如下:
1. 变换矩阵
关于x方向错切,y、z坐标不会发生变换,x坐标发生变化的幅度会收到y、z坐标大小的影响,y、z越大,发生变换的程度也越大。
T S H x = [ 1 b c 0 0 1 0 0 0 0 1 0 0 0 0 1 ] T_{SHx}=\begin{bmatrix} 1&b&c&0\\ 0&1&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix}\ TSHx= 1000b100c0100001
T S H y = [ 1 0 0 0 d 1 f 0 0 0 1 0 0 0 0 1 ] T_{SHy}=\begin{bmatrix} 1&0&0&0\\ d&1&f&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix}\ TSHy= 1d0001000f100001
T S H z = [ 1 0 0 0 0 1 0 0 g h 1 0 0 0 0 1 ] T_{SHz}=\begin{bmatrix} 1&0&0&0\\ 0&1&0&0\\ g&h&1&0\\ 0&0&0&1\\ \end{bmatrix}\ TSHz= 10g001h000100001
2. 代码实现
/// <summary>
/// X方向错切变换
/// </summary>
/// <param name="vertex3D">待变换的点</param>
/// <param name="miscutY">Y方向错切量</param>
/// <param name="miscutZ">Z方向错切量</param>
/// <returns>变换后的点</returns>
VERTEX3D miscutForXTransform3D(VERTEX3D vertex3D, double miscutY, double miscutZ) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 平移变换矩阵transform.matrix[0][0] = 1;transform.matrix[1][1] = 1;transform.matrix[2][2] = 1;transform.matrix[3][3] = 1;// 错切量transform.matrix[0][1] = miscutY;transform.matrix[0][2] = miscutZ;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}/// <summary>
/// Y方向错切变换
/// </summary>
/// <param name="vertex3D">待变换的点</param>
/// <param name="miscutX">X方向错切量</param>
/// <param name="miscutZ">Z方向错切量</param>
/// <returns>变换后的点</returns>
VERTEX3D miscutForYTransform3D(VERTEX3D vertex3D, double miscutX, double miscutZ) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 平移变换矩阵transform.matrix[0][0] = 1;transform.matrix[1][1] = 1;transform.matrix[2][2] = 1;transform.matrix[3][3] = 1;// 错切量transform.matrix[1][0] = miscutX;transform.matrix[1][2] = miscutZ;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}/// <summary>
/// Z方向错切变换
/// </summary>
/// <param name="vertex3D">待变换的点</param>
/// <param name="miscutX">X方向错切量</param>
/// <param name="miscutY">Y方向错切量</param>
/// <returns>变换后的点</returns>
VERTEX3D miscutForZTransform3D(VERTEX3D vertex3D, double miscutX, double miscutY) {Matrix qiciVertex = vertex3D2qici(vertex3D); // 转化为其次坐标Matrix transform; // 平移变换矩阵transform.matrix[0][0] = 1;transform.matrix[1][1] = 1;transform.matrix[2][2] = 1;transform.matrix[3][3] = 1;// 错切量transform.matrix[2][0] = miscutX;transform.matrix[2][1] = miscutY;// 进行变换得到齐次坐标结果Matrix qicires = dotMatrix(transform, qiciVertex);// 将齐次坐标转化为三维点坐标VERTEX3D res;res.x = qicires.matrix[0][0];res.y = qicires.matrix[1][0];res.z = qicires.matrix[2][0];return res;
}void testMiscutTransform3D() {VERTEX3D vertex3D = { 4,3,2 };VERTEX3D res = miscutForZTransform3D(vertex3D, 2, 2);cout << res.x << " " << res.y << " " << res.z << endl;
}
3. 效果展示
测试代码如下:
void testMiscutTransform3D() {VERTEX3D vertex3D = { 4,3,2 };VERTEX3D res = miscutForXTransform3D(vertex3D, 2, 2);cout << res.x << " " << res.y << " " << res.z << endl;res = miscutForYTransform3D(vertex3D, 2, 2);cout << res.x << " " << res.y << " " << res.z << endl;res = miscutForZTransform3D(vertex3D, 2, 2);cout << res.x << " " << res.y << " " << res.z << endl;
}
八、相对任意参考点的复合变换
相对于参考点F(xf,yf,zf)作比例、旋转、错切等变换的过程分为以下三步:
(1)将参考点F移至坐标原点;
(2)针对原点进行三维几何变换;
(3)进行反平移。
九、相对任意方向的复合变换
针对任意方向轴的变换的五个步骤:
①使任意方向轴的起点与坐标原点重合,此时进行平移变换。
②使方向轴与某一坐标轴重合,此时需进行旋转变换,且旋转变换可能不止一次。
③针对该坐标轴完成变换。
④用逆旋转变换使方向轴回到其原始方向。
⑤用逆平移变换使方向轴回到其原始位置。
the end……
三维图形的几何变换到这里就要结束啦~~到此既是缘分,欢迎您的点赞、评论、收藏!关注我,不迷路,我们下期再见!!
计算机图形学13:三维图形的几何变换相关推荐
- 【计算机图形学】三维图形投影和消隐(正等轴测投影图 消隐图构造)
模块4-2 三维图形投影和消隐 一 实验目的 编写三维图形各种变换的投影或消隐算法 二 实验内容 1:自行选择三维物体(不能选长方体),建立坐标系,给定点的三维坐标值,建立边表结构,完成正等轴测投影图 ...
- 计算机图形学之三维图形变换
三维物体几何变换 同二维变换一样,三维基本几何变换都是相对于坐标原点和坐标轴j进行的几何变换:有平移.比例.旋转.对称和错切等 与二维变换类似,引入齐次坐标表示,即:三维空间中的某点变换可以表示成点的 ...
- c语言二维图形变换程序,【计算机图形学】3-2 二维几何变换根本代码
[计算机图形学]3-2 二维几何变换基本代码 返回目录 基本理论参见:[计算机图形学]3-1 二维几何变换基本理论 注:这里不考虑插值的问题. 全部的代码都在https://github.com/Cy ...
- 计算机图形学 | 欢迎来到图形世界
计算机图形学 | 欢迎来到图形世界 计算机图形学 | 欢迎来到图形世界 1.1 初识图形学 计算机图形学 相关学科 发展历史 1.2 探秘图形应用与研究 有趣的图形应用 计算机辅助设计(Compute ...
- 计算机图形学-二维图形-几何变换
几何变化 一.概述 图形变换:是一种几何变换,在二维图形处理过程中,常常需要对平面图形的形状,尺寸,显示方向和显示位置进行修改,来达到改变图形的目的. 几何变换:是一种先行变换,对原来图形中的一点坐标 ...
- 计算机图形学二维图形基本变换实验原理,【实验课件】二维及三维图形基本变换的实现...
实验二 二维及三维图形基本变换的实现 一.实验学时 4学时 二.实验类型 设计型实验 三.实验目的和要求 1. 掌握二维图形变换的原理,对一条直线实现二维基本变换(平移.错切.比例.旋转). 2. 掌 ...
- 计算机图形学-二维图形变换 笔记总结与代码实战
文章目录 1.向量基础知识 2.图形坐标系 3.二维图形变换原理 4.二维图形几何变换 5.窗口视区变换 基本二维几何变换代码 二维复合变换实战-五星红旗绘制 1.向量基础知识 为什么向量如此重要:在 ...
- 计算机图形学二维图形基本变换实验原理,计算机图形学实验:二维图形变换.docx...
计算机图形学实验:二维图形变换.docx (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 实验三 二维图形变换一.实验任务1. 通 ...
- OpenGL学习笔记 - 计算机图形学和现代图形API
一.计算机图形学 1.简述 wiki上的解释说,"计算机图形学是计算机科学的一个子领域,它研究数字合成和操纵视觉内容的方法.尽管该术语通常指的是对三维计算机图形学的研究,但它也包括二维图形和 ...
最新文章
- centos7 python3.6升级到3.7_Centos7下把python 2.7升级到python 3.6(升级过程遇到的一些相关问题)...
- CentOS7安装Zabbix
- 三大工厂模式的优缺点
- 多索引表 (4)multi_index.hpp源代码
- Linux系统弱口令检测和网络端口扫描方法(JR、NMAP)
- datax 模板_datax模板
- java使用ajax异步刷新_2018.6.27 Ajax实现异步刷新
- c++ 显示三维散点图_【无机纳米材料科研制图——OriginLab 0209】Origin散点图线性拟合与非线性拟合...
- amtlib.dll被McAfee删除之后?
- APP版本更新通知流程图
- Android中的传感器之---陀螺仪传感器
- html整体字体微软雅黑,网页布局中对全局字体的最佳控制_html/css_WEB-ITnose
- 7号团队-团队任务5:项目总结会
- MogaFX—日元兑美元30多年来首次突破150日元
- java基础结构图_java基础之【堆、栈、方法区】结构图
- 剑指offer 专项突破版 74、合并区间
- PMSM控制器硬件设计
- 奥林匹克计算机竞赛保送,奥数再见!清北保送生为什么都选信息学奥赛
- 狼人杀总结之“警下预言家 必是真预言家”
- QQ音乐与网易云音乐的比较
热门文章
- 【编程基础】浮点数在计算机中的存储 —— IEEE 754标准
- 通达信通道交易系统选股公式,结合MACD绿柱缩短底背离
- 帮我写一段dart代码,目的是将字符串里的windows、macos、linux系统中的文件名保留字符替换成中文全角字符。使最后返回的字符串可以用于windows、macos、linux的文件名...
- 外购入库单,金蝶KIS旗舰版盘点机PDA,生产企业仓库条码管理进销存
- 德国光量子计算机,新型量子光源为光学量子计算机铺平道路
- glob通配及IO重定向 笔记
- Android kotlin GridView 的使用
- macos双系统 wintogo_我的 WinToGo 踩坑指南
- Generalizing A Person Retrieval Model Hetero- and Homogeneously
- ASP.NET书法网站源码免费分享