微软的文档也可以当作参考《转换的矩阵表示形式》
另外再推荐一本书 《计算机图形学编程(使用OpenGL和C++)(第2版)》
一、向量
1、点积
点积也叫做标量积、数量积、内积,假设有三维向量A(x1, y1, z1)和向量B(x2, y2, z2),则点积的计算公式如下(这里以三维向量为例,理论上适用于N维向量):
点积A·B = x1x2 + y1y2 + z1z2
(1)求两向量的夹角
假设向量A和向量B的夹角为θ,根据下面的公式就可以求出θ, |A|、|B| 是向量A和向量B的长度,也叫做向量的模,如果两个都是单位向量,点积值即为cos(θ):
A·B = |A| |B| cos(θ)
(2)求向量的长度
向量有大小有方向,表示方式却像是点的坐标,其实就是坐标系原点到该点的向量,计算长度就比较简单了,即各分量的平方和再开平方,也可看作是对向量自身的点积(A·A)开平方:
|A| = sqrt(A·A)
(3)判断两向量是否正交
如果A·B = 0,则向量A和向量B正交。
(4)判断两向量是否同向
如果A·B = |A| |B|,则向量A和向量B同向,同理,如果两向量平行,但是方向相反,则A·B = -|A| |B|。
(5)点积的其他应用
如果A·B > 0,则两向量的夹角在-90°~90°之间(不包含边界);
2、叉积
两向量叉积的一个重要特性是,它会生成一个新的向量,新的向量正交(垂直)于之前两个向量(不共线)所定义的平面,其计算公式如下:
叉积AxB = (y1z2 - z1y2, z1x2 - x1z2, x1y2 - y1x2)
公式是真不好记,画个图表示一下:
叉积的顺序会影响求得的法向量的方向,如 AxB 和 BxA 得到的是方向相反的两个向量,通过叉积求平面的法向量对于学习光照部分比较重要。
二、矩阵
4x4矩阵如下图所示,第一个下标是行号,第二个下标表示列号,下标从0开始:
1、单位矩阵
GLSL中的 mat4 用来存储 4x4 矩阵,如果A00、A11、A22、A33为1,其余全为0,则称该矩阵为单位矩阵(如下图),任何点或矩阵乘单位矩阵都不会发生变化:
2、矩阵加法
矩阵加法比较简单,就是对应位置的值相加
3、矩阵乘法
矩阵乘法一般可以从左向右或从右向左进行(注意,由于左乘和右乘是不同的,所以矩阵乘法不满足交换律)。 在3D图形学中,点与矩阵相乘通常将点视作列向量,并从右向左计算,得到点,如:
同理,矩阵乘矩阵,得到的也是矩阵:
矩阵乘法比较常用,一般用于平移、旋转、缩放等,即后面讲到的变换矩阵。
4、变换矩阵
平移、旋转、缩放一般都是作用于顶点坐标,绘图操作的基本图元是点,把矩阵作用于一组点,则最终的效果就是该组点表示的图形整体变化了,矩阵相乘即可实现多种效果的叠加,如平移矩阵乘旋转矩阵,就是把点的坐标平移再旋转。
(1)平移矩阵
平移矩阵是把点的坐标偏移一段距离,X、Y、Z的偏移量放在A03、A13、A23位置,如下图(从右往左计算):
(2) 缩放矩阵
缩放矩阵是在单位矩阵的基础上,把A00、A11、A22位置的1替换成X、Y、Z的缩放因子
(3)旋转矩阵
旋转矩阵稍微复杂点,原理本人也讲不太明白,不过各平台提供的矩阵转换API基本相似,输入的参数是x、y、z坐标,外加一个旋转角度,输出的是一个4x4矩阵,旋转轴即原点和输入的x、y、z所代表的点表示的那条直线(比如x y z分别为0 0 1就表示绕Z轴旋转)。