美文网首页
OpenGL 向量和矩阵简介

OpenGL 向量和矩阵简介

作者: AndyGF | 来源:发表于2020-07-17 16:35 被阅读0次

一. 向量 Vector

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

提到向量就不得不说标量, 我们来看一下二者的区别 :

标量: 只有大小, 如 1, 5 , 12 这样的表示数量的.
向量: 既有大小又有方向, 如 速度 , 力 , 位移.

单位向量

长度为 1 的向量就是单位向量

向量⻓度(向量的模)计算公式:

假如, 原点 O(0, 0, ) , 顶点 A(x, y, z), 那么向量OA 的长度计算如下图:


向量长度计算公式.png
将任意非零向量转化成单位向量 >> 单位化向量

如果⼀个非零向量不是单位向量, ⽽我们把它缩放到1, 这个过程叫做标准化. 将⼀个向量进⾏标准化就是将它长度缩为1; 也叫做单位化向量.

  • 将向量OA单位化,
    向量的模不方便用符号表示, 此处假设向量OA的模是 L, 那么单位化之后就得到方向相同的单位向量 OA', 顶点A' 的坐标是 (x/L, y/L, z/L),
向量点乘 ( dot product )

向量可以进行 加法, 减法 计算. 但是向量里有一个在开发中使用价值⾮常⾼的操作, 叫做
“点乘” .

2个(三维向量)单元向量 之间进行点乘运算将得到一个标量(不是三维向量,是⼀个标量).
它表示两个向量之间的夹角的余弦值 ;

  • 前提 : 2个向量必须为单位向量;
  • 动作 : 2个三维向量之间进行点乘;
  • 结果 : 返回⼀个[-1,1]范围的值. 这个值其实就是两个向量夹⻆的 cos值(余弦值);

注意 : 点乘只能发生在 2 个向量之间进行.

向量点乘.png
向量叉乘 ( cross product )

向量之间的叉乘也是在业务开发里非常有⽤的⼀个计算方式; 2个向量之间叉乘就可以得到另外⼀个向量, 新的向量会与原来2个向量定义的平面垂直. 进行叉乘两个向量不必为单位向量;

  • 前提: 2个普通向量;
  • 动作: 向量与向量叉乘;
  • 结果: 向量 (垂直于原来2个向量定义的平面的向量);
向量叉乘.png

OpenGL中如何定义向量

math3d 库,有2个数据类型,能够表示一个三维或者四维向量.

  • M3DVector3f 表示⼀个三维向量 (x,y,z)
  typedef float M3DVector3f[3];  // Vector of three floats (x, y, z)
  typedef double    M3DVector3d[3];  // Vector of three doubles (x, y, z)
  • M3DVector4f 表示一个四维向量(x,y,z,w).
  typedef float M3DVector4f[4];  // Lesser used... Do we really need these?
  typedef double M3DVector4d[4];  // Yes, occasionaly we do need a trailing w component

w 是缩放因子, 在典型情况下,w 坐标设为1.0。x,y,z值通过除以 w,来进⾏缩放。⽽除以1.0则本质上不改 变 x,y,z 值。

OpenGL中对 点乘 和 叉乘 都提供了相关 API.

  1. 获得2个向量之间的点乘结果,即余弦值
    float  m3dDotProduct3(const M3DVector3f u, const M3DVector3f v)

    double m3dDotProduct3(const M3DVector3d u, const M3DVector3d v)
  1. 获取2个向量之间夹⻆的弧度值
    float m3dGetAngleBetweenVectors3(const M3DVector3f u, const M3DVector3f v)

    double m3dGetAngleBetweenVectors3(const M3DVector3d u, const M3DVector3d v)
  1. 获得2个向量之间的叉乘结果得到⼀个新的向量, 结果话 result 中
    void m3dCrossProduct3(M3DVector3f result, const M3DVector3f u, const M3DVector3f v)

    void m3dCrossProduct3(M3DVector3d result, const M3DVector3d u, const M3DVector3d v)

举例说明 :

    //声明一个四维向量并初始化
    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
    };

二. 矩阵 Matrix

在数学中, 矩阵是一个按照长方阵列排列的复数或者实数集合.矩阵是高等代数学中的常见工具,计算机科学中, 三维动画制作也需要用到矩阵. 所以在 OpenGL 里也是必不可少的.

假设, 在空间有⼀个点.使用 xyz 描述它的位置. 此时让其围绕任意位置旋转一定角度
后. 我们需要知道这个点的新的位置. 此时需要通过矩阵进⾏计算;

为什么?
因为新的位置的 x 不单纯与原来的 x有关, 还和旋转的参数有关. 甚⾄与 y 和 z 坐标有关;

三个矩阵.png

矩阵只有⼀行或者⼀列都是合理的. 只有一行或者一列数字的矩阵可以称为向量. 也可以称为矩阵;

OpenGL 中是如何定义矩阵的

  • 矩阵的定义
    // 三维矩阵的声明
    typedef float M3DMatrix33f[9];
    //四维矩阵的声明
    typedef float M3DMatrix44f[16];

OpenGL的约定里,更多倾向使⽤一维数组; 这样做的原因是: OpenGL 使⽤的是 Column-Major(以列为主)矩阵排序的约定, 这个在数学叫 转置矩阵.

矩阵排序方式.png
OpenGL 矩阵图解
矩阵图解.png

一个 4*4 矩阵是如何在3D空间中表示一个位置和方向的, 列向量进行了特别的标注: 矩阵的最后⼀行都为 0,只有最后⼀个元素为 1.

OpenGL中矩阵相关的 API

单元矩阵初始化⽅式, 共三种 :
  • 方式一
    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, 矩阵的第四列
    };

  • 方式二
    M3DMatrix44f m = {
        1,0,0,0, //X Column
        0,1,0,0, //Y Column
        0,0,1,0, //Z Column
        0,0,0,1 // Translation
    };
  • 方式三
    // API
    void m3dLoadIdentity33(M3DMatrix33f m);
    void m3dLoadIdentity33(M3DMatrix33d m);
    void m3dLoadIdentity44(M3DMatrix44f m);
    void m3dLoadIdentity44(M3DMatrix44d m);

    // 使用
    M3DMatrix44f m;
    m3dLoadIdentity44(m);

将⼀个向量 ✖ 单元矩阵, 就相当于⼀个量 ✖ 1. 不会发⽣任何改变;
矩阵叉乘不满足交换潜法则, A * B != B * A

  • 在线性代数学的维度, 为了便于书写. 所以坐标计算. 都是从左往右顺序, 进行计算. 如下列公式:
    变换后顶点向量 = V_local * M_model * M_view * M_pro
    变换后顶点向量 = 顶点 ✖ 模型矩阵 ✖ 观察矩阵 ✖ 投影矩阵
线性代数矩阵相乘.png
  • 在OpenGL 的维度. 如下列公式:
    变换顶点向量 = M_pro * M_view * M_model * V_local
    变换顶点向量 = 投影矩阵 ✖ 视图变换矩阵 ✖ 模型矩阵 ✖ 顶点
OpenGL 矩阵相乘.png
矩阵左乘
矩阵左乘.png
  1. 从栈顶获取栈顶矩阵 复制到 mTemp
  2. 将栈顶矩阵 mTemp 左乘 mMatrix
  3. 将结果放回栈顶空间里;

相关文章

  • OpenGL 向量和矩阵简介

    一. 向量 Vector 在 3D 笛卡尔坐标系, 基本上,⼀个顶点就是 XYZ 坐标空间上的一个位置. 而在空间...

  • OpenGL入门(八)-- OpenGL向量和矩阵简介

    在前面,我们对OpenGL中绘图做了简单的介绍,还想继续深入OpenGL的后面的内容,就需要熟悉OpenGL中涉及...

  • OpenGL--向量和矩阵

    在我们OpenGL中涉及到图形变换的时候经常会运用到向量/矩阵的运算。今天我们就来了解下OpenGL中的向量、矩阵...

  • OpenGL 向量、矩阵

    向量 在坐标系上,一个顶点就是X,Y,Z坐标空间的一个位置。由一个单独的XYZ定义的这样就是向量。 单位向量 向量...

  • OpenGL向量、矩阵

    向量 在 3D 笛卡尔坐标系, 基本上一个顶点就是XYZ 坐标空间上的⼀个位置。而在空间中给定的一个位置恰是由一个...

  • OpenGL 向量/矩阵

    向量 什么是向量 在3D笛卡坐标系中,基本上,一个顶点就是XYZ坐标空间上的一个位置。而在空间中给定的一个位置,恰...

  • OpenGL 的向量和矩阵

    GLTools库中有一个组件叫Math3d,其中包含了大量好用的OpenGl含有3d数学和数据类型。在开发过程中我...

  • OpenGL 矩阵基础变化

    OpenGL⾥的矩阵/向量 向量:3个值(x、y、z)组合起来表示2个重要的值,⽅向和数量. 矩阵: 在OPenG...

  • 3d开发之opengl着色语言

    opengl着色语言基于c++,又完美的支持向量和矩阵的各种操作,拥有大量的内置函数来提供丰富的功能,opengl...

  • 006---OpenGL基础变化

    [toc] OpenGL 矩阵向量 向量 一个顶点同时也是一个向量. 方向 数量 长度或模为1的 当前这个顶点为 ...

网友评论

      本文标题:OpenGL 向量和矩阵简介

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