OpenGL 向量 矩阵 变换
向量
单位向量
标量:只有大小,例如:1,2,3...
向量:既有大小又有方向。
单位向量:向量长度(向量的模)为1的向量。公式如下:
img1.png
如果一个向量不是单位向量,可以通过单位化将其转化为单位向量;即非零向量除以向量的模。公式如下:
img2.png
向量声明
math3d库,有2个数据类型,能够表示一个三维或者四维向量。
M3DVector3f可以表示⼀个三维向量(x,y,z),
M3DVector4f则可以表示一个四维向量(x,y,z,w)。
在典型情况下,w坐标设为1.0。x,y,z值通过除以w,来进行缩放。而除以1.0则本质上不改变x,y,z值。
//三维向量/四维向量的声明
typedef float M3DVector3f[3]; typedef float M3DVector4f[4];
//声明一个三维向量 M3DVector3f:类型 vVector:变量名
M3DVector3f vVector;
//声明一个四维向量并初始化一个四维向量
M3DVector4f vVertex = {0,0,1,1};
//声明一个三分量顶点数组,例如⽣成⼀个三角形
M3DVector3f vVerts[] = {
-0.5f,0.0f,0.0f, 0.5f,0.0f,0.0f, 0.0f,0.5f,0.0f
};
向量点乘
前提条件: 2个向量必须为单位向量
动作: 2个三维向量之间进行点乘
结果:返回⼀个[-1,1]范围的值,是一个标量。 这个值其实就是夹角的cos值(余弦值)。
//m3dDotProduct3 获得2个向量之间的点乘结果;
float m3dDotProduct3(const M3DVector3f u,const M3DVector3f v);
//m3dGetAngleBetweenVector3 获取2个向量之间夹角的弧度值;
float m3dGetAngleBetweenVector3(const M3DVector3f u,const
M3DVector3f v);
向量叉乘
2个向量之间叉乘就可以得到另外一个向量,新的向量会与原来2个向量定义的平面垂直。
前提: 2个普通向量
动作: 向量与向量叉乘
结果: 向量(垂直于原来2个向量定义的平面的向量,例如求法线)
//m3dCrossProduct3 获得2个向量之间的叉乘结果得到一个新的向量,例如求法线
void m3dCrossProduct3(M3DVector3f result,const M3DVector3f u,const
M3DVector3f v);
矩阵
单位矩阵
行优先矩阵:一行一行读取
列优先矩阵:一列一列读取
单位矩阵:主对角线上数据都是1,其余元素都是0。
以下就为单位矩阵:
//单元矩阵初始化方式①
GLFloat m[] = {
1,0,0,0, //X Column
0,1,0,0, //Y Column
0,0,1,0, //Z Column
0,0,0,1 // Translation
}
//单元矩阵初始化方式②
3DMatrix44f m = {
1,0,0,0, //X Column
0,1,0,0, //Y Column
0,0,1,0, //Z Column
0,0,0,1 // Translation
}
//单元矩阵初始化方式③
void m3dLoadIdentity44f(M3DMatrix44f m);
矩阵点乘
前提条件: 两个矩阵的行列数相等
动作:矩阵A的第一个元素与矩阵B的第一个元素的乘积 = 矩阵C的第一个元素
img3.png
矩阵叉乘
前提条件: 第一个矩阵的列数 = 第二个矩阵的行数
动作:矩阵A第一行与矩阵B第一列对应元素乘积的综合 = 矩阵C的第一个元素
img4.png
OpenGL中的矩阵相乘
数学中为了方便计算,都是以行矩阵为标准,从左到右的顺序进行计算,所以在数学中,顶点将以行向量的方式表示。
从数学角度理解mvp矩阵的计算,由于顶点是行向量,要满足矩阵相乘的规定条件(即 叉乘的前提),必须将mvp矩阵放在右边,属于右乘。
img5.png
OpenGL中的矩阵规定是以列为主,所以顶点以列向量的方式表示。
从OpenGL角度理解mvp矩阵的计算,由于顶点是列向量,如果项进行矩阵规则,就需要满足矩阵相乘的条件,需要将mvp矩阵的顺序颠倒为pvm,且放在列向量的左边,属于左乘。
img6.png
变换
#单位矩阵变换
#使用单位矩阵绘制的对象不会发生变换,他们还在原点,并且x轴、y轴、z轴与视觉坐标中一样。
#同样,单位着色器也完全不会对顶点做任何改变,我们可以将顶点乘以单位矩阵,但是这是一种毫无意义的操作。
#平移矩阵变换
#一个平移矩阵仅仅是将我们的顶点沿着3个坐标轴中的一个或多个进行平移。
#调用math3d库中的m3dTranslationMatrix44函数来使用变换矩阵。
M3DMatrix44f m;
void m3dTranslationMatrix44(M3DMatrix44f m, float x, float y, float z);
#旋转矩阵变换
#调用math3d库中的m3dRotationMatrix44函数来使用变换矩阵。
M3DMatrix44f m;
void m3dRotationMatrix44(M3DMatrix44f m, float angle, float x, float y, float z);
#缩放矩阵变换
#缩放矩阵可以沿着3个坐标轴方向,按照指定因子放大或缩小所有顶点,以改变对象大小。
#使用math3d库创建一个缩放矩阵,方法与创建平移和旋转矩阵的方法类似。
M3DMatrix44f m;
void m3dScaleMatrix44(M3DMatrix44f m, float xScale, float yScale, float zScale);
#综合矩阵变换
#math3d库函数m3dMatrixMultiply44用来将两个矩阵相乘并返回运算结果。
void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a, const M3DMatrix44f b);