美文网首页
OpenGL 向量与矩阵

OpenGL 向量与矩阵

作者: windy_3c22 | 来源:发表于2020-07-17 15:58 被阅读0次

    1、向量

    在 3D 笛卡尔坐标系, 基本上一个顶点就是XYZ 坐标空间上的⼀个位置,而在空间中给定的一个位置恰恰是由一个单独的 XYZ 定义的,而这样的XYZ就是向量(图1.1)。

    图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);
    
    不同的变换顺序的结果

    图形变换顺序不同。变成的最终结果也不相同(矩阵不满足乘法交换律)。

    相关文章

      网友评论

          本文标题:OpenGL 向量与矩阵

          本文链接:https://www.haomeiwen.com/subject/pwvphktx.html