OpenGL ES学习笔记(二):图形数学基础

1.矩阵

矩阵其实就是个二维数组,如下图,是个 3×3 矩阵,它有三行和三列。

OpenGL ES学习笔记(二):图形数学基础_第1张图片
1. 矩阵

顶点和向量实际由一个1×3的矩阵表示:

2. 1x3矩阵

笛卡尔坐标系的三轴正向归一向量可以用以下矩阵表示:


x轴

y轴

z轴

三轴可合成如下3x3矩阵(先x然后是y再后是z)


OpenGL ES学习笔记(二):图形数学基础_第2张图片
3. 三轴矩阵
矩阵相乘

矩阵相乘的计算规则:以结果矩阵左上角第一个数字为例,是第一个矩阵第一行的每个数字,各自乘以第二个矩阵第一列对应位置的数字,然后将乘积相加),得到结果矩阵左上角的那个值。


OpenGL ES学习笔记(二):图形数学基础_第3张图片
4. 矩阵相乘

也就是说,结果矩阵第m行与第n列交叉位置的那个值,等于第一个矩阵第m行与第二个矩阵第n列,对应位置的每个值的乘积之和。

转置矩阵

把矩阵A的行换成相应的列,得到的新矩阵称为A的转置矩阵,记作AT
A

OpenGL ES学习笔记(二):图形数学基础_第4张图片
5. 矩阵的转置

OpenGL ES学习笔记(二):图形数学基础_第5张图片
6. 矩阵转置的运算性质

一个矩阵和它的转置矩阵可以这么直观地表示出来:

OpenGL ES学习笔记(二):图形数学基础_第6张图片
7. 矩阵及其转置矩阵
逆矩阵

A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩阵B,使得: AB=BA=E。 则我们称BA的逆矩阵,而A则被称为可逆矩阵。

初等变换法求逆矩阵:将一n阶可逆矩阵A和n阶单位矩阵I写成一个nX2n的矩阵

对B施行初等行变换,即对A与I进行完全相同的若干初等行变换,目标是把A化为单位矩阵。当A化为单位矩阵I的同时,B的右一半矩阵同时化为了A。

OpenGL ES学习笔记(二):图形数学基础_第7张图片
8. 初等变换法求逆矩阵

2.四元数

复数是由实数加上虚数单位i组成,其中


相似地,四元数都是由实数加上三个元素i,j,k组成,而且它们有如下的关系:


每个四元数都是 1、i、j、k的线性组合,即是四元数一般可表示为



要把两个四元数相加只需将相类的系数加起来就可以,就像复数一样。至于乘法则可跟随以下的乘数表:

OpenGL ES学习笔记(二):图形数学基础_第8张图片
9. 四元数乘法表

相对于将欧拉角信息存储在3个GLfloats变量或一个 Vector3D 变量里来说, 使用四元数有2个优点:

1.四元数不会造成万向节死锁(gimbal lock),但是欧拉角容易造成万向节死锁,使用四元数能够让我们的3D模型能够全方位的移动。

2.相比于给每个欧拉角做矩阵旋转转换计算,使用四元数结合多角度旋转可以显著的减少计算量。

四元数结构体

从数据上看来,四元数只不过是比Vector 3D多加了一个GLfloat,经常把它当成w字段。所以对我们来说一个四元数就象这样:
typedef struct {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat w;
} Quaternion3D;

从一个四元数中创建旋转矩阵

这另外的一个方法相对简单些。并且这个基本算法来自于Matrix FAQ,虽然我需要把它转换成行优先的顺序。
static inline void Matrix3DSetUsingQuaternion3D(Matrix3D matrix, Quaternion3D quat)
{
matrix[0] = (1.0f - (2.0f * ((quat.y * quat.y) + (quat.z * quat.z))));
matrix[1] = (2.0f * ((quat.x * quat.y) - (quat.z * quat.w)));
matrix[2] = (2.0f * ((quat.x * quat.z) + (quat.y * quat.w)));
matrix[3] = 0.0f;
matrix[4] = (2.0f * ((quat.x * quat.y) + (quat.z * quat.w)));
matrix[5] = (1.0f - (2.0f * ((quat.x * quat.x) + (quat.z * quat.z))));
matrix[6] = (2.0f * ((quat.y * quat.z) - (quat.x * quat.w)));
matrix[7] = 0.0f;
matrix[8] = (2.0f * ((quat.x * quat.z) - (quat.y * quat.w)));
matrix[9] = (2.0f * ((quat.y * quat.z) + (quat.x * quat.w)));
matrix[10] = (1.0f - (2.0f * ((quat.x * quat.x) + (quat.y * quat.y))));
matrix[11] = 0.0f;
matrix[12] = 0.0f;
matrix[13] = 0.0f;
matrix[14] = 0.0f;
matrix[15] = 1.0f;
}

把一个角度和旋转轴转换成一个四元数

四元数可以做的另外一种转换是,表示成在一个Vector3D表示的轴线上进行旋转。这在骨骼动画里面是非常有用的,因为这种表现形式通过矩阵是很难做到的。创建一个基于角度和轴旋转得四元数,我们可以这样做:
static inline Quaternion3D Quaternion3DMakeWithAxisAndAngle(Vector3D axis, GLfloat angle)
{
Quaternion3D quat;
GLfloat sinAngle;

angle *= 0.5f;
Vector3DNormalize(&axis);
sinAngle = sinf(angle);
quat.x = (axis.x * sinAngle);
quat.y = (axis.y * sinAngle);
quat.z = (axis.z * sinAngle);
quat.w = cos(angle);

return quat;
}

你可能感兴趣的:(OpenGL ES学习笔记(二):图形数学基础)