OpenGL之矩阵转换

2020-10-17 15:36:10 蜻蜓队长

向量

  • 定义在 3D 笛卡尔坐标系, 基本上. ⼀一个顶点 就是XYZ 坐标空间上的⼀一个位置. ⽽而在空间中给定的一个位置 恰恰是由⼀一个单独的 XYZ 定义的. ⽽而这这样的 XYZ 就是向量量 。
  • 向量的长度:(x^2 + y^2 + z^2)和的平方根
  • 单位向量:向量长度为1的向量为单位向量
  • 向量标准化:如果一个向量的长度不为1,那么将这个向量的长度缩放到1的过程叫做向量标准化

OpenGL中的向量

OpenGL中使用math3d库定义向量,其中有两个数据类型:M3DVector3f 、M3DVector4f,分别定义三维 向量(x,y,z)以及四维向量(x,y,z,w),其中w表示缩放因子,x、y、z除以w来进行缩放,通常情况下w为1.0

代码参考

//三维向量量/四维向量量的声明
typedef float M3DVector3f[3]; 

typedef float M3DVector4f[4];

//声明⼀一个三维向量量 M3DVector3f:类型 vVector:变量量名

 M3DVector3f vVector;

//声明⼀一个四维向量量并初始化⼀一个四维向量量 

M3DVector4f vVertex = {0,0,1,1}; 

向量的点乘

向量的点乘发生在两个三维单位向量之间,得到的结果是这两个向量的夹角的余弦值,即cosA,因此结果是一个标量,不在是向量,故而向量点乘必须先转成单位向量

  • 前提条件:2个向量必须是单位向量 
  • 动作:2个三维向量之间是点乘
  • 结果:返回一个[-1,1]之间的一个值,是这两个向量夹角的余弦值(cos值)
  • 单位化向量:使⽤一个⾮非零向量除以它的模(向量的⻓度), 就可以得到方向相同的单位向量 ,即(x/|xyz|, y/|xyz|, z/|xyz|) 

math3d库中提供了计算向量点乘的API:

  • m3dDotProduct3 函数获得2个向量量之间的点乘结果
  • m3dGetAngleBetweenVector3 即可获取2个向量量之间夹⻆角的弧度值

需要注意的是向量点乘不符合交换律,所以向量的前后顺序不能改变 

向量的叉乘

2个向量量 之间叉乘就可以得到另外⼀一个向量量,新的向量量会与原来2个向量量定义的平⾯面垂直

  •  相乘的向量是两个普通向量
  • 动作:向量叉乘
  • 结果:得到一个新的向量与原来两个向量所在的平面垂直

math3d 库中提供了了关于叉乘的API

m3dCrossProduct3 函数获得2个向量之间的叉乘结果得到一个新的向量,例如

void m3dCrossProduct3(M3DVector3f result,const M3DVector3f  u ,const
    M3DVector3f v)
复制代码

 其中第一个参数保存相乘的结果向量,第二三个参数是相乘的向量,不满足交换律

矩阵

矩阵只有一行或者一列都是合理的,只有一行或者一列可以称为向量,也可以叫矩阵。

OpenGL中矩阵的定义API,

//三维矩阵/四维矩阵的声明
typedef float M3DMatrix33f[9];

typedef float M3DMatrix44f[16];

在其他编程语言中一般把矩阵定义为二维数组,但是在OpenGL中习惯定义为一维数组,因为OpenGL使用的是列矩阵

行矩阵


列矩阵


注意:矩阵的最后⼀行都为0,只有最后⼀个元素为1 

单元矩阵

单元矩阵初始化三种方式

  • 直接定义数组方式 

GLFloat m[] = {
            1,0,0,0,
            0,1,0,0,
            0,0,1,0,
            0,0,0,1
}复制代码

  • 使用M3DMatrix44f 定义

M3DMatrix44f = {
            1,0,0,0,
            0,1,0,0,    
            0,0,1,0,
            0,0,0,1
}复制代码

  •  使用API定义

//m用来接收矩阵					m3dLoadIdentity44f(M3DMatrix44f m);复制代码

 一个向量乘以单位矩阵还是等于一个向量,没有任何改变。

顶点向量变换

计算公式

  1. 在线性代数中,为了书写方便,坐标计算都是从左往右按着顺序进行计算,如下公式


例子如下


2. 在OpenGL中,计算公式如下

例子如下


变换

 对于变换的理解

  • 视图变换:指定观察者的位置
  • 模型变换:在场景中移动物体
  • 模型窗口:描述视图/模型变换的二元性(2种看到模型转换的方式,一个是观察者不动,物体移动;一个是观察者移动,物体不动)
  • 投影:改变观景体大小以及设置它的投影
  • 视口:伪变化,对窗口上最终输出进行缩放

注意:所有的变换之前必须先应用视图变换,因为所有的变换都是基于新调整的坐标系来进行的。

视图变换

观察者对于屏幕位置的移动

模型变换

  • 平移

m3dTranslationMatrix44复制代码

  • 缩放
    
    m3dScaleMatrix44复制代码

  • 旋转

    m3dRotationMatrix44复制代码

  • 综合

    		
    						void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a, const M3DMatrix44f b)
    
    					复制代码

投影变换

  • 透视投影
  • 正投影


以上内容来自于网络,如有侵权联系即删除
相关文章

上一篇: 懒人版二进制重排

下一篇: iOS视觉 OpenGL初探

客服紫薇:15852074331
在线咨询
客户经理