作者:非妃是公主
专栏:《计算机图形学》
博客地址: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​ ​= ​adhl​beim​cfjn​pqrs​ ​⋅ ​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​= ​1000​0100​0010​tx​ty​tz​1​ ​

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​= ​a000​0e00​00j0​0001​ ​

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​= ​1000​0cosθsinθ0​0−sinθcosθ0​0001​ ​

绕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θ0​0100​sinθ0cosθ0​0001​ ​

绕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θ00​0010​0001​ ​


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​= ​1000​0100​00−10​0001​ ​ 
同理可得,关于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​= ​−1000​0100​0010​0001​ ​ 
关于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​= ​1000​0−100​0010​0001​ ​


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​= ​1000​0−100​00−10​0001​ ​ 
同理可得,关于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​= ​−1000​0100​00−10​0001​ ​ 
关于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​= ​−1000​0−100​0010​0001​ ​


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​= ​1000​b100​c010​0001​ ​

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​= ​1d00​0100​0f10​0001​ ​

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​= ​10g0​01h0​0010​0001​ ​


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:三维图形的几何变换相关推荐

  1. 【计算机图形学】三维图形投影和消隐(正等轴测投影图 消隐图构造)

    模块4-2 三维图形投影和消隐 一 实验目的 编写三维图形各种变换的投影或消隐算法 二 实验内容 1:自行选择三维物体(不能选长方体),建立坐标系,给定点的三维坐标值,建立边表结构,完成正等轴测投影图 ...

  2. 计算机图形学之三维图形变换

    三维物体几何变换 同二维变换一样,三维基本几何变换都是相对于坐标原点和坐标轴j进行的几何变换:有平移.比例.旋转.对称和错切等 与二维变换类似,引入齐次坐标表示,即:三维空间中的某点变换可以表示成点的 ...

  3. c语言二维图形变换程序,【计算机图形学】3-2 二维几何变换根本代码

    [计算机图形学]3-2 二维几何变换基本代码 返回目录 基本理论参见:[计算机图形学]3-1 二维几何变换基本理论 注:这里不考虑插值的问题. 全部的代码都在https://github.com/Cy ...

  4. 计算机图形学 | 欢迎来到图形世界

    计算机图形学 | 欢迎来到图形世界 计算机图形学 | 欢迎来到图形世界 1.1 初识图形学 计算机图形学 相关学科 发展历史 1.2 探秘图形应用与研究 有趣的图形应用 计算机辅助设计(Compute ...

  5. 计算机图形学-二维图形-几何变换

    几何变化 一.概述 图形变换:是一种几何变换,在二维图形处理过程中,常常需要对平面图形的形状,尺寸,显示方向和显示位置进行修改,来达到改变图形的目的. 几何变换:是一种先行变换,对原来图形中的一点坐标 ...

  6. 计算机图形学二维图形基本变换实验原理,【实验课件】二维及三维图形基本变换的实现...

    实验二 二维及三维图形基本变换的实现 一.实验学时 4学时 二.实验类型 设计型实验 三.实验目的和要求 1. 掌握二维图形变换的原理,对一条直线实现二维基本变换(平移.错切.比例.旋转). 2. 掌 ...

  7. 计算机图形学-二维图形变换 笔记总结与代码实战

    文章目录 1.向量基础知识 2.图形坐标系 3.二维图形变换原理 4.二维图形几何变换 5.窗口视区变换 基本二维几何变换代码 二维复合变换实战-五星红旗绘制 1.向量基础知识 为什么向量如此重要:在 ...

  8. 计算机图形学二维图形基本变换实验原理,计算机图形学实验:二维图形变换.docx...

    计算机图形学实验:二维图形变换.docx (9页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 实验三 二维图形变换一.实验任务1. 通 ...

  9. OpenGL学习笔记 - 计算机图形学和现代图形API

    一.计算机图形学 1.简述 wiki上的解释说,"计算机图形学是计算机科学的一个子领域,它研究数字合成和操纵视觉内容的方法.尽管该术语通常指的是对三维计算机图形学的研究,但它也包括二维图形和 ...

最新文章

  1. centos7 python3.6升级到3.7_Centos7下把python 2.7升级到python 3.6(升级过程遇到的一些相关问题)...
  2. CentOS7安装Zabbix
  3. 三大工厂模式的优缺点
  4. 多索引表 (4)multi_index.hpp源代码
  5. Linux系统弱口令检测和网络端口扫描方法(JR、NMAP)
  6. datax 模板_datax模板
  7. java使用ajax异步刷新_2018.6.27 Ajax实现异步刷新
  8. c++ 显示三维散点图_【无机纳米材料科研制图——OriginLab 0209】Origin散点图线性拟合与非线性拟合...
  9. amtlib.dll被McAfee删除之后?
  10. APP版本更新通知流程图
  11. Android中的传感器之---陀螺仪传感器
  12. html整体字体微软雅黑,网页布局中对全局字体的最佳控制_html/css_WEB-ITnose
  13. 7号团队-团队任务5:项目总结会
  14. MogaFX—日元兑美元30多年来首次突破150日元
  15. java基础结构图_java基础之【堆、栈、方法区】结构图
  16. 剑指offer 专项突破版 74、合并区间
  17. PMSM控制器硬件设计
  18. 奥林匹克计算机竞赛保送,奥数再见!清北保送生为什么都选信息学奥赛
  19. 狼人杀总结之“警下预言家 必是真预言家”
  20. QQ音乐与网易云音乐的比较

热门文章

  1. 【编程基础】浮点数在计算机中的存储 —— IEEE 754标准
  2. 通达信通道交易系统选股公式,结合MACD绿柱缩短底背离
  3. 帮我写一段dart代码,目的是将字符串里的windows、macos、linux系统中的文件名保留字符替换成中文全角字符。使最后返回的字符串可以用于windows、macos、linux的文件名...
  4. 外购入库单,金蝶KIS旗舰版盘点机PDA,生产企业仓库条码管理进销存
  5. 德国光量子计算机,新型量子光源为光学量子计算机铺平道路
  6. glob通配及IO重定向 笔记
  7. Android kotlin GridView 的使用
  8. macos双系统 wintogo_我的 WinToGo 踩坑指南
  9. Generalizing A Person Retrieval Model Hetero- and Homogeneously
  10. ASP.NET书法网站源码免费分享