1、向量
在 3D 笛卡尔坐标系, 基本上一个顶点就是XYZ 坐标空间上的⼀个位置,而在空间中给定的一个位置恰恰是由一个单独的 XYZ 定义的,而这样的XYZ就是向量(图1.1
)。
在x轴上的向量(1,0,0)。向量的长度(也叫向量的模)为1。我们称为单位向量。在y轴(0,1,0)或z轴(0,0,1)也是单位向量。也可不在x、y、z轴上。
-
单位向量:向量的模为1的向量。
向量的模计算
向量模的计算: -
单位化向量(标准化):如果一个向量不是单位向量,而我们把它的模缩放到1,这个过程叫做标准化。将一个向量进行标准化就是将它的模变为1,也叫单位化向量。
单位化向量计算:非0向量,除以它的模就可以得到方向相同的单位向量。
向量a = (x,y,z),它的模为A。标准化向量为(x/A,y/A,z/A)
-
向量的点乘
向量的点乘,也叫向量的内积、数量积,对两个向量执行点乘运算,就是对这两个向量对应位一一相乘之后求和的操作,点乘的结果是一个标量(a向量和b向量的夹角,向量点乘的几何意义)。
//向量点乘
向量a=(x1,y1),向量b=(x2,y2)
a·b=x1x2+y1y2=|a||b|cosθ(θ是a,b夹角)
math3d 库中提供了关于点乘的API
//1.m3dDotProduct3 函数获得2个向量之间的点乘结果;
float m3dDotProduct3(const M3DVector3f u,const M3DVector3f v);
//2.m3dGetAngleBetweenVector3 即可获取2个向量之间夹角的弧度值;
float m3dGetAngleBetweenVector3(const M3DVector3f u,const M3DVector3f v);
-
向量的叉乘
2个向量之间叉乘就可以得到另外⼀个向量,新的向量会与原来2个向量定义的平面垂直(更为熟知的叫法是法向量,该向量垂直于a和b向量构成的平面)。
法向量的方向(右手判定方向):
a×b的方向:四指由a开始,指向b,拇指的指向就是a×b的方向,垂直于a和b所在的平面;
b×a的方向:四指由b开始,指向a,拇指的指向就是b×a的方向,垂直于b和a所在的平面;a×b的方向与b×a的方向是相反的,且有:a×b=-b×a
法向量方向
math3d 库中提供了关于叉乘的API
//1.m3dCrossProduct3 函数获得2个向量之间的叉乘结果得到一个新的向量
void m3dCrossProduct3(M3DVector3f result,const M3DVector3f u ,const M3DVector3f v);
2、矩阵Matrix
假设, 在空间有一个点.使用 xyz 描述它的位置. 此时让其围绕任意位置旋转一定⻆度后. 我们需要知道这个点的新的位置. 此时需要通过矩阵进行计算(因为新的位置的x 不单纯与原来的x还和旋转的参数有关. 甚至于y和z坐标有关)。
矩阵只有一行或者⼀列都是合理的. 只有⼀⾏或者⼀列数字可以称为向量。也可以称为矩阵。
在其他编程标准中, 许多矩阵库定义⼀个矩阵时,使⽤⼆维数组;
OpenGL的约定里,更多倾向使用 ⼀维数组; 这样做的原因是: OpenGL 使用的是 Column-Major(以列为主)矩阵排序的约定。
//三维矩阵/四维矩阵的声明
typedef float M3DMatrix33f[9];
typedef float M3DMatrix44f[16];
A1 A2 A3 A4 A1 A5 A9 A13
A5 A6 A7 A8 A2 A6 A10 A14
A9 A10 A11 A12 A3 A7 A11 A15
A13 A14 A15 A16 A4 A8 A12 A16
//4*4行优先矩阵排序 //4*4列优先矩阵排序
⼀个4*4矩阵是如何在3D空间中表示⼀个位置和方向的。矩阵的最后一⾏行都为0,只有最后一个元素为1
矩阵表示位置方向
-
矩阵相乘
矩阵相乘 - 1、当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。
- 2、矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
- 3、乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和。
2.1 在OpenGL 的维度,矩阵计算使用
-
变换顶点向量
变换顶点向量 =M_pro * M_view * M_model * V_local
变换顶点向量 =投影矩阵 x 视图变换矩阵 x 模型矩阵 x 顶点
变换顶点向量
在OpenGL 矩阵计算在栈中的变化。矩阵堆栈流程图
- 1、从栈顶取出栈顶矩阵,复制到mTemp中。
- 2、将栈顶矩阵mTemp左乘mMatrix。
- 3、将结果放回栈顶空间
inline void MultMatrix(const M3DMatrix44f mMatrix){
M3DMatrix44f mtemp;
m3dCopyMatrix44(mtemp, pStack[stackPointer]);
m3dMatrixMultiply44(pStack[stackPointer], mtemp, mMatrix);
}
2.2 在OpenGL 中的变换
变换 | 解释 |
---|---|
视图变换 | 指定观察者位置 |
模型变换 | 在场景中移动物体 |
模型视图 | 描述视图/模型变换的二元性(2种看到模型转换的⽅式) |
投影 | 改变视景体⼤小和设置它的投影⽅式 |
视⼝ | 伪变化,对窗⼝上最终输出进⾏缩放 |
-
视图变换
视图变换是应用到场景中的第一种变换, 它用来确定场景中的有利位置,在默认情况下, 透视投影中位于原点(0,0,0),并沿着 z 轴负方向进行察 (向显示器器内部”看过去”)。当观察者点位于原点(0,0,0) 时,就像在透视投影中一样。
视图变换将观察者放在你希望的任何位置。并允许在任何⽅向上观察场景。确定视图变换就像在场景中放置观察者并让它指向某一个方向。
从⼤局上考虑, 在应⽤任何其他模型变换之前, 必须先应⽤视图变换. 这样做是因为, 对于视觉坐标系而言, 视图变换移动了当前的⼯作的坐标系; 后续的变化都会基于新调整的坐系进⾏。 -
模型变换
模型变换: ⽤于操纵模型与其中某特定变换。这些变换将对象移动到需要的位置。通过旋转,缩放,平移。
模型变换
//平移
void m3dTranslationMatrix44(M3DMatrix44f m, floata x, float y, float z);
//旋转
m3dRotationMatrix44(m3dDegToRad(45.0), floata x, float y, float z);
//缩放
void m3dScaleMatrix44(M3DMatrix44f m, floata xScale, float yScale, float zScale);
//综合变换
void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a, const M3DMatrix44f b);
不同的变换顺序的结果
图形变换顺序不同。变成的最终结果也不相同(矩阵不满足乘法交换律)。
网友评论