矩阵基础

计算机图形学数学基础译自 ScratchaPixel 网站,数学基础部分共八篇,本篇为第二篇,感兴趣的同学可以参考我的 GitBook 镜像。

矩阵简介 Intro to Matrices

矩阵(Matrix) 在图形处理方面扮演着极为重要的角色,我们将经常在3D程序中看到它的身影。

在之前的章节我们指出通过线性操作可以对点进行 平移(translation)或者 旋转(rotation)。例如我们可以通过增加坐标的值来移动一个点,或者使用 三角函数(trigonometric function)对一个向量进行旋转。现在(并不是矩阵定义),矩阵是一种可以集合上述所有转换(平移、旋转或伸缩)的结构。用点或向量乘以矩阵可以得到转换后的点或矩阵。集合所有转换的意思是指对于平移,旋转或伸缩可以组合在一起,如创建一个矩阵(1,1,1),先沿X轴旋转90度,再沿Z轴放大2倍(1,1,2),然后再平移(-2,3,1)。我们可以将一个点按这种顺序操作,不过需要较多的代码:

Vec3f translate(Vec3f P, Vec3f translateValue) {...}
Vec3f scale(Vec3f P, Vec3f scaleValue) {...}
Vec3f rotate(Vec3f P, Vec3f axis, float angle) {...}
...
Vec3f P = Vec3f(1,1,1);
Vec3f translateVal(-1, 2, 4);
Vec3f scaleVal(1,1,2);
Vec3f axis(1,0,0);
float angle = 90;
Vec3f Pt;
Pt = translate(P, translateVal); // translate P
Pt = scale(Pt, scaleVal); // then scale the result
Pt = rotateValue(Pt, axis, angle); // finally rotate the point

但如果是矩阵的话可以这样写:

Matrix4f M(...); // st the matrix for translation, rotation, scale
Vec3f P = Vec3f(1,1,1);
Vec3f Ptransformed = P * M; // do everything at once,translate, rotate, scale

将点P和矩阵M相乘可以得到与只对P处理相同的结果,这里主要展示矩阵在图形处理的应用以及使用矩阵的优点。

矩阵是什么 Matrices,What are they?

矩阵是什么?我们先从一个矩阵的例子说起,如果你阅读过计算机图形学的书,你会发现它们常常定义2维数组。为了定义一个2维数组,我们通常使用 m x n 这种形式。m和n分别代表矩阵的行和列。下列是一个3 x 5的矩阵:

我们通常使用i,j表示矩阵中的特定位置的系数。
中,i表示行,j表示列。通常情况,在计算机图形学中,我们比较关注3 x 34 x 4方阵(square matrices) ,下面是4 x 4方阵在c++中的实现:

template<typename T>
class Matrix44 {
public:
  Matrix44() {}
  const T* operator[] (uint8_t i) const {return m[i];}
  T* operator[] (unit*_t i) {return m[i];}
  // initialize the coefficients of the matrix with the coefficients of the identity matrix
  T m[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}};
};
typedef Matrix44<float> Matrix44f;

上述代码中有两行操作:

const T* operator [] (unit8_t i) const {return m[i];}
T* operator [] (unit8_t i) {return m[i];}

这些操作被称为 访问操作符(access operator) ,它们被用于通过提供明确的成员变量来访问矩阵的系数。在没有定义访问操作符时,我们需要:

Matrix44f mat;
mat.m[0][3] = 1.f;

在定义访问操作符后:

Matrix44f mat;
mat[0][3] = 1.f;

矩阵乘法 Matrix Multiplication

矩阵的乘法是点-矩阵或向量-矩阵转换的核心。矩阵的乘积是另一个矩阵:

之前的部分我们简单说过矩阵可以以一种简单的方式,处理点或向量的组合线性变换。它们是如何工作的,比较重要的一点是,我们需要理解,矩阵的乘法(matrix multiplication) 代表的是另外两个矩阵组合的结果。换句话说,对点或向量的组合变换需要执行的矩阵M1和M2,可以组合成一个矩阵M3。假设一个点由A到B需要利用矩阵M1,然后转换B到C需要利用矩阵M2,用M1乘以M2得到的M3可以直接完成从A到C的转换。需要指出的如果你有另外两个矩阵M4和M5,完成A到D到C的转换,用M4乘以M5同样会得到M3。

multiple

矩阵的乘法的成立有一条很重要规则:M1的列数必须等于M2的行数。换言之,两个相乘的矩阵必须是m x pp x n
的形式:

下面来看如何得出新类、矩阵的系数,我们使用下标i和j表示行和列的索引。
表示矩阵M3中i行和j列的系数的值,假设i=1j=2(对应C++中M1的第2行和M2的第3列,因为数组的起始下标是0)。可以得到如下公式:

matrix

在C++中的表示:

Matrix44 operator * (const Matrix44& rhs) const {
  Matrix44 mult;
  for (unit8_t i = 0; i< 4; ++i) {
    for (uint8_t j = 0; j< 4; ++j) {
      mult[i][j] = m[i][0] * rhs[0][j] +
                   m[i][1] * rhs[1][j] +
                   m[i][2] * rhs[2][j] +
                   m[i][3] * rhs[3][j];
    }
  }
  return mult;
}

需要指出的是矩阵的乘法不满足 交换率(commutative)M1 * M2的结果和M2 * M1的不同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值