OpenGL学习之路(4.1) 向量的简单介绍

什么是向量?

  • 空间中的一个点,既是一个顶点,也是一个向量


    image.png

在代码中如何定义三维,四维向量或者三维向量数组、四维向量数组?

  • 在OpenGL中提供了一个数学库类 #include
  • 我们会两个比较常见的类:
    • M3DVector3f:表示三维向量(x,y,z)-(f)表示float类型的意思
      • 同时也可以用来设置三维数组也是没有问题的
        typedef float   M3DVector3f[3];     // Vector of three floats (x, y, z) 默认是一个一维数组
    
    
    • M3DVector4f:表示四维向量(x,y,z,w)w表示缩放因子w默认为1.0-(f)同上
    • 我们也可以用M3DVector4f来表示颜色值的设置

    M3DVector4f color[] = {1.0f, 1.0f, 0.0f, 1.0f};

简单了解点乘

  • 两点相乘可以求得两个向量之间的夹角
image.png
  • 那么在代码中如何实现点乘呢?2个向量相乘

 m3dDotProduct3(const M3DVector3f u, const M3DVector3f v)

  • 根据两个向量获取角度值

float m3dGetAngleBetweenVectors3(const M3DVector3f u, const M3DVector3f v)

  • 定义2个向量

    //定义2个向量V1,V2
    M3DVector3f v1 = {1.0, 0.0, 0.0};
    M3DVector3f v2 = {0.0, 1.0, 0.0};

  • 获取V1,V2的点积,获取夹角的cos值
    //点乘的时候v1和v2的位置可以随便交换,因为只是获取一个值
    GLfloat value1 = m3dDotProduct3(v1, v2);
    printf("v1v2的余弦值:%f\n", value1);

  • 通过acos(),获取value1的弧度值

    GLfloat value2 = acos(value1);
    printf("v1v2的弧度值:%f\n", value2);

  • 获取V1,V2的夹角弧度值

    GLfloat value3 = m3dGetAngleBetweenVectors3(v1, v2);
    printf("v1v2的弧度值:%f\n", value3);

  • m3dRadToDeg 弧度->度数 - m3dDegToRad 度数->弧度

    GLfloat value4 = m3dRadToDeg(value3);
    GLfloat value5 = m3dDegToRad(90);
    printf("V1V2角度:%f\n",value4);
    printf("弧度:%f\n",value5);
  • 定义向量vector2
    
    M3DVector3f vector2 = {0.0f, 0.0f, 0.0f};

  • 实现矩阵叉乘:结果,向量1,向量2 ,注意:与点乘不同的是,叉乘要按照顺序来设置,不然得出的值会是相反值,例如:v1乘v2是向上乘为正数v2乘v1是向下乘为负数,所以需要注意顺序,不能乱乘
    image.png
  
    m3dCrossProduct3(vector2, v1, v2);
    printf("%f, %f, %f\n",vector2[0],vector2[1],vector2[2]);

简单认识矩阵

  • OpenGL为渲染管线准备了4种不同类型的矩阵(GL_MODELVIEW,GL_PROJECTION, GL_TEXTURE and GL_COLOR)并且为这些矩阵提供了变换的操作:glLoadIdentity(),glTranslatef(),glRotatef(),glScalef(),glMultMatrixf(),glFrustum()和glOrtho().


    image.png
  • 通过M3DMatrix33f创建3*3矩阵
    
    //创建3*3矩阵
    M3DMatrix33f mv1;

  • 通过M3DMatrix44f创建4*4矩阵

    //创建4*4矩阵
    M3DMatrix44f mv2;

  • 创建单元矩阵
    //创建单元矩阵
    GLfloat m[] = {
        1.0f,0.0f,0.0f,0.0f,//X列
        0.0f,1.0f,0.0f,0.0f,//Y列
        0.0f,0.0f,1.0f,0.0f,//Z列
        0.0f,0.0f,0.0f,1.0f//变换
    };

  • 创建单元矩阵也可以用到M3DMatrix44f
    //创建单元矩阵
    M3DMatrix44f m2 = {
        1.0f,0.0f,0.0f,0.0f,//X列
        0.0f,1.0f,0.0f,0.0f,//Y列
        0.0f,0.0f,1.0f,0.0f,//Z列
        0.0f,0.0f,0.0f,1.0f//变换
    };

  • 每次都要写那么多矩阵很麻烦,那么可以通过以下方式进行

    //创建单元矩阵
    M3DMatrix44f m3;
    m3dLoadIdentity44(m3); // 这两句的作用与上面两个矩阵一样

  • 在OpenGL中可以通过矩阵来对视图的变换


    image.png
    • 平移矩阵--M2矩阵 往Y轴平移10个单位
      4d71e0fe47ff1c0fd4acf126401f68e2.png
    
          m3dTranslationMatrix44(m2, 0.0f, 10.0f, 0.0f);
    
    
    • 旋转变换


      image.png
    
            /*
            参数1:结果矩阵
            参数2:弧度,如果度数,使用m3dDegToRad(度数),将度数转为弧度
            参数3,4,5:表示围绕X,Y,Z轴旋转。
         */
        m3dRotationMatrix44(m2, m3dDegToRad(45.0f), 1.0f, 0.0f, 0.0f);
    
    
    • 缩放


      image.png
    
        /*
            参数1:结果矩阵
            参数2,3,4:在X,Y,Z放大、缩小的比例值
         */
        m3dScaleMatrix44(m2, 1.0f, 10.0f, 1.0f);
    
    
  • 单个顶点应用模型视图变换的矩阵方程式,是一个4*4的矩阵

    • 当发生变化时,例如旋转,将x、y、z、w每一个顶点进行矩阵相乘的出一个新的坐标值
      • 比如三角形的时候,顶点a乘3次,顶点b乘3次,顶点c乘3次,最终得出新三角形
      • w-缩放因子默认是等1.0,1.0*1.0=1.0,所以没有发生变化


        image.png
  • 在OpenGL的矩阵构造是一维数组,而不是二维数组,为什么?因为使用一维数组效率高,一个一个读取就可以了。而在开发过程中,我们经常用到的是列矩阵


    image.png

转置矩阵:将⾏矩阵A的换成同序列得到的矩阵,叫做A的转换矩阵。计为AT。
矩阵转置:其实就是⾏列互换。有很多地方都用到。⽐比如数学、程序语言、计算机数据结构中

  • 为什么要用列矩阵呢?


    image.png

因为代码看起来比较清楚,处理起来也更加方便,列矩阵每一列都清楚地显示着它的作用,x,y,z通过上图可以看到非常清楚显示着。

  • 单位矩阵
    • 将⼀个向量乘以⼀个单位矩阵得到的结果还是原来的矩阵


      image.png

你可能感兴趣的:(OpenGL学习之路(4.1) 向量的简单介绍)