computer Graphics 课程大纲:
线性代数:
光栅化Rasterization:栅格化,深度缓冲,插值,光照模型,着色
几何:曲线,曲面
Ray Tracing:光线追踪:求交,物理光照模型——路径追踪,着色
动画animation/物理simulation/仿真:
线性代数
Vector
投影:一个向量不仅可以投影到2维坐标系,也可以3维坐标系,根据cos和sin计算
//
点乘(结果为浮点数):||a||||b||costheta
矩阵表示:A^-1 * B
点乘在二维中的几何意义,反映的是两个向量之间的夹角关系, 计算两个向量的夹角,
点乘等于向量 A 在 B 方向上的投影长度乘以 B 的模长,或者反过来,向量 B 在 A 方向上的投影长度乘以 A 的模长
已知两个向量,我们可以求出点乘的结果,等于对应的分量相乘,当两个向量表示方向都是单位向量时,点乘结果等价于costheta
- a·b>0 方向基本相同,夹角在0°到90°之间
- a·b=0 正交,相互垂直
- a·b<0 方向基本相反,夹角在90°到180°之间
点乘类似*,满足交换结合分配率
点乘还可以判断向量的方向是否基本一致,两向量夹角,>90为负数,=90度为0,<90为正数,=0为1
//
叉乘(结果为向量):||a||||b||sintheta
矩阵表示:A * b
二维空间几何意义:向量的叉乘结果是这两个向量构成的平行四边形的有向面积,结果是一个标量,而不是一个向量。
作用:求正交于两个向量的第3个向量
作用:判定左右,通过z分量==axby−aybx,判断左右关系,如果结果为正,那么第二个向量在向量1的左边,否则右边
作用:判定内外,比如判断一个点是否在逆时针三角形内,只需要看,是否在ab边的左,ac边的左,bc边的左,即可,也就是点同时在3个边的左侧(方法:向量起点放在一处,看手心由第一个转到向量2大拇指方向,不用考虑角度转了多少)
对于顺时针三角形,虽然都在3条边的右侧,但也成立,只要同时在左侧或右侧就可以
如果正好叉乘结果为0,都ok
一个向量叉乘本身 = 0,因为sin0 = 0
//
右手定则:模拟opengl的笛卡尔坐标系
右手螺旋定则:模拟正交的结果,y * z = +x, z * y = -x,由掌心从y到z,从z到y旋转,大拇指方向即为x方向
matrices
矩阵:表示顶点的变换
矩阵一定要符合条件才能相乘,矩阵1的列 == 矩阵2的行 = 结果为 = 1行2列
发现规律:结果矩阵的行列的某元素,正好为AB矩阵的行列运算
矩阵没有交换率,但又结合和分配率
注意
约定俗称下,向量为列向量,矩阵在左边,矩阵的每一行影响决定对应的向量行分量
矩阵的乘法顺序是非常重要的,
SRT变换
二维变换
线性变换
等比缩放,不等比缩放,对称,切变
//
旋转默认绕原点逆时针,
那如果想要绕指定点旋转怎么做到,先平移到原点,后旋转,再移动回c,否则将直接绕原点旋转而不是绕c旋转
//
旋转如何推导旋转矩阵?
推导绕z逆时针旋转矩阵,xy坐标发生变化,通过单位边长的正方形,通过两个点旋转theta角度,可以很容易得出新的primer的坐标,根据 p1 = 旋转矩阵 * p
同样如果顺时针旋转,矩阵中的sin都变为相反数,而且矩阵为转置矩阵,和逆矩阵
二维变换
S
R:因为二维仅有绕z旋转
T
齐次坐标
齐次坐标:将所有的矩阵可以写为统一的形式,为线性变换,而不希望写为非线性变换如放射变换
//
对于点新增一个分量x,y,1,对于向量x,y,0,为什么要这样区别呢?
因为向量不受平移的影响,将最后分量写为0,不会被平移矩阵影响
//
如何判断向量与点加减结果是向量还是点?看最后是1还是0
特殊情况:点 + 点,w结果是2,在齐次坐标下,结果是两个点的中点
x,y,w(w !=0)-> x/w,y/w,1转为点
首先两个点相加可以写为x1 + x2, y1 + y2, 1 + 1,同时除以w,为zh
性能:有性能损耗
逆变换
变换矩阵的逆矩阵
SRT,MVP
矩阵乘法正确顺序需要为SRT,但是在乘法中其实要TRSp,因为是从最右侧计算的
同样MVP矩阵也是一样PVMp
因为有结合律的存在,其实无论从右到左理解,还是从左到右理解都一样
在opengl中SRT是在局部空间进行的,在通过模型矩阵从局部到世界空间
三维变换
S
R:
对于3维的,绕哪轴哪轴不变,比如绕x,第一行不变,第一列不变,将2维的写到对应的地方,绕y2行2列不变,绕z3行3列不变,
其中对于绕y的sin可以看到取了相反值,因为z叉乘x得到y,因此z应该写为二维中的第一行,对于y叉乘z得到x,x叉乘y得到z都没有问题
如何绕任意轴旋转?
首先移到原点,旋转后,移动回原位
T
欧拉角
分解:pitch,yaw,roll
罗德里格斯公式(Rodrigues' Rotation Formula):
正常来说,我们可以绕着3个轴分别旋转,从而旋转到任意角度,但是这个公式可以求得,绕任意过原点的轴旋转角度a后的矩阵
绕n向量旋转a角度,起点在原点,方向任意罗德里格斯公式附图推导,理解-CSDN博客
推导解释:
原向量v,旋转theta角度,后新向量v prime, n为旋转轴
首先将两向量投影,建立新向量w(黄色线) = n 乘 v,其中
用n和v表示原向量投影的向量
在将v prime投影的用v和w(黄色线)轴表示投影分量,
得到所有式子带入v prime的两个投影分量,就可以得到罗德里格斯公式
MVP(模型,Viewing观测变换)
模型变换(scene)
SRT……
视图变换(camera)
摆放好场景,我们需要移动摄像机,本质移动摄像机,实则移动场景
摄像机位置,看向的方向,上向量(因为相机可能旋转)
视图矩阵:平移矩阵 * 旋转矩阵 (缩放不影响相机)
旋转矩阵:可以先求逆矩阵 * 坐标向量,又因为旋转矩阵是正交矩阵,逆=转置,所以很容易得到将向量变换到坐标向量的矩阵
比如这个逆矩阵可以将1000,0100,0010三个坐标分别乘以矩阵,得到的结果分别就是变换后的向量,
投影变换(3D->2D)
正交投影
首先定义长方体,指定大小rl左右,tb顶底,nf前后,通过正交矩阵,映射为标准立方体,
正交投影矩阵 = 平移矩阵 * 缩放矩阵
平移矩阵:首先取两边差/2,向负方向移动,这样长方形就变换到了原点上
缩放矩阵:将长方形变形到-1----1的坐标,如何做到?乘以1/两边差 的缩放因子,这样相乘就变为了-1---1,比如2 / (r-l) * - (r+l) / 2 = -1 , 2 / (r-l) * (r+l) / 2 = 1
透视投影
定义视锥(近平面的宽高比radio,field垂直可视角度),定义四棱锥(近平面,远平面),通过透视矩阵,映射为长方形,通过正交矩阵,映射为标准立方体
xyz * 透视矩阵 = 新的坐标
n, 0, 0, 0,
0, n, 0, 0,
0, 0, n + f, -n * f,
0, 0, 1, 0;
推导过程:
- 首先根据相似三角形原理,可以得到新的坐标:收缩的x,y坐标,新坐标 == n/z * 原坐标,其中z为原距离,n为从相机到近平面的距离,如果同时×z,依旧是一个点(和原来的点等价),且最后一项为z
对于任意一个点来说,z深度值是不确定的,而对于n是固定的,所以为了满足所有点,z是未知的
- 有了2个条件,对于透视矩阵,我们已经可以推导4*4矩阵的124行了,对于第3行,z是未知的,下面推导第3行
根据原理:近平面上坐标永远不变,远平面z值和中心点不变,只是收缩
- 当近平面时,向量的z值==n,因为坐标永远不变,可以根据矩阵第3行 * xyn1 = n^2(同时*n)
求得前两个数为0,而对于后两个数其实不确定,因为可以为n,0, 也可以为0,n^2
- 对于远平面,假设为中心点,00f1(xy都为0),因为中心点坐标不变,仍是00f1,即第3行 * 00f1 = f ^2(同时*n)
- 最后3行3列 = n = f,3行4列=-nf
Eigen 库:线性代数运算库
#include<eigen3/Eigen/Core>
#include<eigen3/Eigen/Dense>
Eigen::Vector3f v(1.0f,2.0f,3.0f);
Eigen::Matrix3f i;
i << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0;
Eigen::Matrix4f::Identity()//单位矩阵