1. 向量
1.1 向量基本介绍
说道这里就涉及到一些数学知识了,不要害怕,我会结合实际的空间来说,高等数学中关于向量和矩阵的知识并不是那么的难。实际上作为开发者的我们也只要掌握一些基础的便足够。
3D 笛卡尔坐标系中的一个点,是通过三个值如(x,y,z)来表示的。这三个值组合起来实际上表示两个重要的值:方向和数量。如下图所示的(X,Y,Z)实际上表示了一个方向,方向是朝箭头方向。一个向量的数量就是这个向量的长度。对于 x 轴向量(1,0,0)来说,向量长度是 1。我们把长度为 1 的向量称为单位向量。
image.pngOpenGL 中的 math3d 库有这样的两个数据类型M3DVector3f 和 M3DVector4f 。前者是一个三维向量(x,y,z);后者是一个四维向量(x,y,z,w),典型情况下 w 值为 1.0 ,x、y、z 值通过除以 w 进行缩放。明明就是 3D 图形学,又不是 4D 图像学,为何要使用 4 个分量来表示一个向量 ?之所以这样做是因为 3D 顶点变化是要乘以一个 4 4 的变换矩阵。有个规则是必须用一个四分量向量乘以一个 4 4 的矩阵,后面讲到矩阵时会详细说明。
1.2 向量的运算
向量可以进行加法、减法运算,也可以简单的通过减法、减法进行缩放。然而这里主要说关于向量有趣的两个运算: 点乘和叉乘。
- 点乘
两个三分量之间的点乘运算将得到一个标量(只有一个值),它表示两个向量之间夹角对应的三角函数 Cos 值。 - 叉乘
两个向量之间叉乘所得的结果是另外一个向量,这个新向量与原来两个向量定义的平面垂直。和点乘不同,在进行叉乘运算的时候向量的顺序非常重要,不同的叉乘顺序会得到两个方向相反的向量。
2. 矩阵及其空间变化
2.1 理解场景变化
2.1.1 视觉坐标
视觉坐标是相对于观察则而言的,无论进行何种变换,都可以将它视为绝对的屏幕坐标。这样,视觉坐标就表示一个虚拟固定的坐标系,通常作为参考坐标系使用。
2.1.2 两种变换
在说矩阵之前,先来说一下3D场景中的一些变化。关于变化,主要有两种变换视图变换和模型变换。
- 视图变换
所谓的视图就是观察者或相机的位置。视图变换允许我们把观察点放置在任何希望的位置,允许在任何方向上观察。确定视图变换就像在场景中放置照相机并让它指定某个方向。
总的来说在任何其他模型变换之前,必须先进行视图变换。这是因为对视觉坐标系而言,视图变化就移动了当前的工作坐标系,后续的一切变换随后都是基于新调整的坐标系进行的。 - 模型变化
模型变换用于操作模型和其中的特定的对象。模型变换通常是现将模型对象移动到需要的位置上,然后再对他们进行旋转和移动。就拿先旋转后平移和先平移后旋转来说得到的是两种不同情况。如下图所示,无论是先执行旋转还是平移,后一个操作(旋转或平移)都是基于第一个操作结果产生的坐标系进行下一步操作。
2.2 模型视图矩阵
与其说矩阵的几何意义这么生涩难懂,不如说的是矩阵在几何中到底是有什么作用呢?一般来说,方阵可以描述任意的线性变换。也就说,在几何当中,我们用矩阵表示几何体的空间变换。比如我们在程序中常用的平移、旋转、缩放等等。
模型视图矩阵是一个 4 * 4 矩阵,它表示一个变化后的坐标系,可以用来放置对象和确定对象的位置。顶点作为一个单列矩阵(也就是一个响亮)的形式来表示,并乘以一个模型视图矩阵来获得一个相对视觉坐标系的经过变换的新坐标。
如下代码所形成的矩阵计算所示,一个包含单个顶点数据的矩阵乘以模型视图矩阵后得到新的视觉坐标。顶点数据实际是4个数据,其中包含一个附加值 w ,它表示一个缩放因子,默认情况下是 1.0 ,一般情况下很少去改动。
[x] [a b c d] [x0]
[y] [a b c d] [y0]
[z] * [a b c d] = [z0]
[w] [a b c d] [w0]
接下来我们就来详细说明,上面是矩阵计算是怎么做到:将一个顶点乘以一个矩阵来对它进行变换。
2.2.1 矩阵构造
矩阵的前三列的前三个元素只是方向向量,表示空间上 x y z 轴上的方向(在这里用向量来表示一个方向)。一般情况下这三个向量之前总是成 90 度夹角,并且通常为单位长度。数学书中中称之为标准正交(向量为单位长度)和正交(向量不是单位长度)。如下图对矩阵进行了标注。另外要注意下图的矩阵最后一行都为 0 ,只有一个元素为 1。
image.png如果有一个包含不同坐标系的位置和方向的 4 4 矩阵,然后用一个表示原来坐标系的向量(表示为一个矩阵或向量)乘以这个矩阵,得到的结果是一个转换到新坐标系下的新向量。这就意味着,空间中任何位置和方向都可以由一个 4 4矩阵唯一确定。如果一个对象的所有向量乘以这个矩阵,那么我们将得到整个对象变换到的空间中的位置和方向。
2.2.2 单位矩阵
在讲矩阵的变化之前,先简单说下单位矩阵的概念。将一个向量乘以一个单位矩阵,就相当于用这个向量乘以 1 ,不会发生任何变化。单位矩阵中除了一条对角线上的元素为 1,其他元素全为 0 。
image.png2.3 矩阵变化操作
矩阵的变化操作主要分为缩放、平移、旋转。为了更好的理解矩阵的变化操作,以及矩阵是怎么形成的,笔者就直接从缩放讲起。把缩放讲清除,之后的平移以及旋转都是按照同样的套路进行推导。
2.3.1 缩放
为了更好的理解缩放,我先从 2D 环境说起,之后在延伸到3D环境。
image.png如果沿着坐标轴进行缩放,那么每一个坐标轴都有缩放因子,所以2D环境下有两个缩放因子Kx和Ky,那么基向量p和q根据缩放因子的影响,我们可以得到下面公式。
image.png根据变化,可以得到在2D环境下的缩放矩阵。如下所示:
image.png同理,通过2D环境下的缩放矩阵,我们可以得到3D环境下的缩放矩阵。
image.png2.3.2 平移
一个平移矩阵仅仅是将顶点沿着 3 个左边轴中的一个或者多个进行移动。这个应该是很好理解的,这里就不做过多解释。列如在 OpenGL的 math3d 库中,我们就可以通过m3dTranslationMatrix44 函数使用矩阵直接做平移操作。
2.3.3 旋转
关于旋转操作的矩阵实际上推导起来稍稍有些麻烦,需要通过大量的图解和注释来说明。笔者感觉没必要进行详细的推导,毕竟我们不是专业研究数学的,只要知旋转矩阵形成过程和缩放以及平移的原理是一样,只是推到起来会更麻烦些。这里我就简单的列出一些推到结果。当然,有兴趣的同学可以自行研究下。
image.png image.png image.png image.png image.png
网友评论