此为个人学习笔记,总结内容来源于网络各个平台,如有错误欢迎指摘
光栅化成像
变换矩阵
线性变换
- 变换前是直线的,变换后依然是直线
- 直线比例保持不变
- 变换前是原点的,变换后依然是原点
2D线性变换
变换矩阵 (Transformation Matrices) 在图形学中的重要性不用多说,一切物体的缩放,旋转,位移,都可以通过变换矩阵作用得到。同时在投影 (projection) 变换的时候也有很多应用,本文将会介绍一些简要的变换矩阵。
我们将如下图所示的简单矩阵乘法定义为对向量 ( x , y ) T (x, y)^T (x,y)T的线性变换。
以下所有的变换方式均为以坐标原点为中心,逆时针方向操作
缩放
以坐标原点为基准点进行缩放操作
剪切
以坐标原点为固定点,将其拉伸
旋转
推导过程为
在其中选一点 a a a,记向量长度为 r r r,其坐标为
将其旋转过后的点 b b b记为
两者带入求解
绕任意点操作
上述中所有的矩阵操作都基于了坐标原点,如果我们希望绕任意一点进行操作可以遵循以下过程
- 将图像以基准点平移到坐标原点
- 进行需要的变换
- 将图像以基准点平移回原点
3D线性变换
与二维变化非常相似,大部分是仅仅是增加了Z轴的操作
缩放
剪切
旋转
三维中的旋转提供了更多种的可能
在此使用右手坐标系
- X:水平向右
- Y:垂直向前
- Z:垂直向上
旋转时以大拇指作为轴,其余四指进行旋转,故可得到以下矩阵
值得注意的是所有的旋转矩阵都是正交矩阵,则可知其逆矩阵与转置矩阵相同,几何意义为对于逆时针旋转30°的矩阵,其转置矩阵,即逆矩阵,则表示顺时针旋转30°
绕任意轴操作
思想与二维空间中一致
值得一提的是存在基于过坐标原点的任意轴旋转公式
仿射变换
仿射变换”就是:“线性变换”+“平移”
- 变换前是直线的,变换后依然是直线
- 直线比例保持不变
少了原点保持不变这一条。
位移
至此我们可以发现,线性变换需要四个元素来操作,而位移需要另外的两个元素,于是二维变化不能完全用二维矩阵描述完全,由此引入齐次坐标的概念
在此之中,先做线性变换,后做位移
多出来的矩阵第三行中,前两位固定为0,第三位区分点与方向
- 1表示点
- 0表示方向
方向的位移没有意义,方向始终不会变
并不意味着第三位只会出现这两种情况,但最终都会经过变换回归1或0
作业内容
任务目标
给定一个点 P=(2,1), 将该点绕原点先逆时针旋转 45◦,再平移 (1,2), 计算出变换后点的坐标(要求用齐次坐标进行计算)
代码解释
先线性变换(旋转),后平移,两者分开实现:
Eigen::Vector3f p(2.0f, 1.0f, 1.0f); //定义我们的p点 写成齐次坐标形式,P(2,1),1代表点,0代表向量
Eigen::Vector3f result;
// 目标是先旋转后平移 所以我们在p的左边依次乘以旋转矩阵和平移矩阵
Eigen::Matrix3f rotation; //定义旋转矩阵
Eigen::Matrix3f transform; //定义平移矩阵
float theta = 45.0 / 180.0 * M_PI; //转换成弧度数
rotation << cos(theta), -sin(theta), 0,
sin(theta), cos(theta), 0,
0, 0, 1; //旋转矩阵写成齐次坐标形式
transform << 1, 0, 1,
0, 1, 2,
0, 0, 1; // 平移矩阵
result = transform * rotation * p; // 转换过程
或者将两者结合到一起,使用一个矩阵完成操作:
//除上述方法以外可使用一个变换矩阵完成两步操作,称为仿射变换
Eigen::Matrix3f affine;//仿射变化矩阵
affine << cos(theta), -sin(theta), 1,
sin(theta), cos(theta), 2,
0, 0, 1; //仿射变换为一次线性变换后,再进行一次平移
result = affine * p; // 转换过程
完成两步操作,称为仿射变换
Eigen::Matrix3f affine;//仿射变化矩阵
affine << cos(theta), -sin(theta), 1,
sin(theta), cos(theta), 2,
0, 0, 1; //仿射变换为一次线性变换后,再进行一次平移
result = affine * p; // 转换过程
##