CG中的几何学——矩阵【4】

2024-01-17 01:59
文章标签 矩阵 几何学 cg

本文主要是介绍CG中的几何学——矩阵【4】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址:http://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/matrices

如果在渲染图像的时候,所有的物体都只能够放在场景的原点,那能够制作出来的效果就很有限了。还好,我们可以用矩阵来移动场景中的物体,灯光以及摄像机,这样才能创造出令人影响深刻,匪夷所思的效果。如果您想要写一个自己的3D渲染引擎,那么矩阵是一定要弄明白的。现在,让我们开始来学习这个让人畏惧的存在吧。

矩阵:让我们的变换操作更简单

其实矩阵并不复杂,大家都怕它很有可能是完全了解矩阵代表的是什么或者不知道矩阵是怎么工作的。在3D应用里面,矩阵扮演着非常重要的角色,在代码里面我们会经常看到它们的身影。
在前面的章节中,我们学到如何用线性变换的方式来移动或者旋转一个点。比如,我们可以增加或减少一个点的坐标值来移动这个点。现在,让我们用非正式的数学定义来定义矩阵:矩阵就是融合了各种线性变换(平移,旋转,缩放)的一个结构。通过将这个结构和一个点做乘法,我们可以对这个点进行这个矩阵包含的线性变换。我们可以创建一个让点旋转90度的矩阵,一个缩放点的坐标为之前2倍的矩阵,或者创建一个移动点的坐标(-2,3,1)的矩阵。在没有使用矩阵之前,以上提到的这些操作也是可以完成的,比如像下面这样:
这里写图片描述
虽然完成了这些操作,不过这代码量可不小。现在让我们用矩阵的方式来完成同样的操作:

Matrix M(...);//这个矩阵里包含着所有的线性变换
Vec3f p = Vec3f(1,1,1);//待变换的点
Vec3f transformed = p*M;//得到变换后的点

用矩阵的话,三行代码就搞定了,我们的生活因此变的更美好,有更多的时间享受快乐时光了。现在您可能会产生一个疑问:矩阵具体是怎么做到这些变换的?请看下文分解。

什么是矩阵

矩阵到底是什么?我们现在不会给出它具体的严格的数学定义,而是给出几个矩阵的例子。然后再由对例子的剖析,反向引申出数学定义,这样理解更深刻一些。如果您已经阅读了一些有关CG的书籍,您会发现在书籍中的很多地方,矩阵通常都是由一个实数构成的二维矩阵表示的。
这里写图片描述
我们用mxn来表示一个二维的数组。其中m和n是两个代表行数和列数的数。比如一个3x5的矩阵:
这里写图片描述
矩阵通常会用一个大写字母来表示,我们通常会使用两个下标来指明矩阵中的具体的某个元素:
这里写图片描述表示矩阵中的第i行第j列的元素。
到现在为止,我们已经剔除了很大一部分矩阵相关的知识,我们只关心矩阵与CG相关的知识。在CG领域中,基本上我们只会用行和列相等的矩阵,也就是方形矩阵。尤其是3x3和4x4的矩阵。
这里写图片描述这里写图片描述
在C++里面我们可以用如下的方式来实现矩阵:

template<typename T>
class Matrix44
{
public:Matrix44(){}const T* operator[](uint8_t i)const{return m[I];}T* operator[](uint8_t i){return m[i];}//初始化矩阵为单位矩阵T m[4][4] = {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1},};
};typedef Matrix44<float> Matrix44f;

这个矩阵类实现了[]操作符的重载。现在我们如果想要使用矩阵中的某个元素可以这样写:

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

也可以这样写:

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

矩阵乘法

我们可以对矩阵执行乘法操作,而这个乘法操作就是完成向量和点线性变换的核心步骤。两个矩阵的乘积是另一个矩阵。
这里写图片描述
我们在本章的开头说过,矩阵是一种定义各种线性变换组合的一种简化形式。如何去得到线性变换的这种矩阵形式呢?我们稍后将为大家揭晓。现在我们只需要知道,我们可以把两个表示线性变换的矩阵通过乘法的方式融合到一个单独的矩阵里。比如M1表示的是一个平移变换,M2表示的是另一个平移变换,通过把它们相乘,得到的矩阵M3同时融合了M1和M2的变换。
这里写图片描述
在上图中,我们有用两种方式将一个点从A移动到点C。第一种方式的路径是A-B-C,第二种方式的路径是A-D-C。将点从A移动到B再从B移动到C需要两个包含平移变换的矩阵M1和M2;将点从A移动到D再移动到C也需要两个包含平移变换的矩阵M4和M5。那么M1*M2和M4*M5都会得到同一个直接将点从A移动到C的矩阵M3。
关于矩阵还有一个规则需要注意,虽然如果我们只使用4x4矩阵的话这条规则并不重要。这条规则就是:如果两个矩阵能做乘法,那么前提条件是第一个矩阵的列数和第二个矩阵的行数需要相等。简而言之,必须满足如下情况的两个矩阵才能做乘法:
这里写图片描述
现在让我们进一步说明要矩阵的乘法具体是个什么过程吧。简而言之,新的矩阵的第i行第j列的元素的值是有第一个矩阵的第i行构成的向量与第二个矩阵第j列构成的向量的点积(i/j为0 表示的是第一列/行)。可以用下图来表示这种计算:
这里写图片描述
我们可以用这种方式把M3的所有元素算出来。

现在用C++的方式来实现这种矩阵的乘法吧。

Matrix44 operator* (const Matrix44& rhs) const
{Matrix44 mult;for(uint8_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;
}

最后,矩阵的乘法顺序是不能交换的,交换运算次序会得到截然不同的结果。

总结

我们并没有说明矩阵是怎样和为什么能够融合各种变换,我们会在下一章里说明。通过本部分的介绍,我们只需记住矩阵其实就是二维数组。我们还需要知道矩阵是如何书写的,矩阵中各个元素可以用何种方法访问,以及矩阵的乘法是如何进行的。

这篇关于CG中的几何学——矩阵【4】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/614594

相关文章

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

线性代数|机器学习-P35距离矩阵和普鲁克问题

文章目录 1. 距离矩阵2. 正交普鲁克问题3. 实例说明 1. 距离矩阵 假设有三个点 x 1 , x 2 , x 3 x_1,x_2,x_3 x1​,x2​,x3​,三个点距离如下: ∣ ∣ x 1 − x 2 ∣ ∣ 2 = 1 , ∣ ∣ x 2 − x 3 ∣ ∣ 2 = 1 , ∣ ∣ x 1 − x 3 ∣ ∣ 2 = 6 \begin{equation} ||x

【线性代数】正定矩阵,二次型函数

本文主要介绍正定矩阵,二次型函数,及其相关的解析证明过程和各个过程的可视化几何解释(深蓝色字体)。 非常喜欢清华大学张颢老师说过的一段话:如果你不能用可视化的方式看到事情的结果,那么你就很难对这个事情有认知,认知就是直觉,解析的东西可以让你理解,但未必能让你形成直觉,因为他太反直觉了。 正定矩阵 定义 给定一个大小为 n×n 的实对称矩阵 A ,若对于任意长度为 n 的非零向量 ,有 恒成

python科学计算:NumPy 线性代数与矩阵操作

1 NumPy 中的矩阵与数组 在 NumPy 中,矩阵实际上是一种特殊的二维数组,因此几乎所有数组的操作都可以应用到矩阵上。不过,矩阵运算与一般的数组运算存在一定的区别,尤其是在点积、乘法等操作中。 1.1 创建矩阵 矩阵可以通过 NumPy 的 array() 函数创建。矩阵的形状可以通过 shape 属性来访问。 import numpy as np# 创建一个 2x3 矩阵mat

【UVA】10003-Cutting Sticks(动态规划、矩阵链乘)

一道动态规划题,不过似乎可以用回溯水过去,回溯的话效率很烂的。 13988658 10003 Cutting Sticks Accepted C++ 1.882 2014-08-04 09:26:49 AC代码: #include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include

算法练习题17——leetcode54螺旋矩阵

题目描述 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。  代码 import java.util.*;class Solution {public List<Integer> spiralOrder(int[][] matrix) {// 用于存储螺旋顺序遍历的结果List<Integer> result = new ArrayList

线性代数 第六讲 特征值和特征向量_相似对角化_实对称矩阵_重点题型总结详细解析

文章目录 1.特征值和特征向量1.1 特征值和特征向量的定义1.2 特征值和特征向量的求法1.3 特征值特征向量的主要结论 2.相似2.1 相似的定义2.2 相似的性质2.3 相似的结论 3.相似对角化4.实对称矩阵4.1 实对称矩阵的基本性质4.2 施密特正交化 5.重难点题型总结5.1 判断矩阵能否相似对角化5.2 已知两个矩阵相似,求某个矩阵中的未知参数5.3 相似时,求可逆矩阵P,使

《黑神话:悟空》专题合集MOD/修改器/壁纸/音乐/CG剧情

《黑神话:悟空》专题合集」 链接:https://pan.quark.cn/s/d67857f4e308 包含内容: 《黑神话:悟空》MOD合集 《黑神话:悟空》修改器(风灵月影) 《黑神话:悟空》壁纸合集 《黑神话:悟空》3小时CG完整剧情合集 4K120帧最高画质!国语 简中字幕 附:4K 结尾动画合集 ​​​国语 简中字幕 《黑神话:悟空》主题曲 《黑神话

最大子矩阵和问题归纳总结

一,最大子矩阵问题: 给定一个n*n(0< n <=100)的矩阵,请找到此矩阵的一个子矩阵,并且此子矩阵的各个元素的和最大,输出这个最大的值。 Example: 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 其中左上角的子矩阵: 9 2 -4 1 -1 8 此子矩阵的值为9+2+(-4)+1+(-1)+8=15。 二,分析 子矩阵是在矩阵