矩阵代表什么?


19

我最近开始学习OpenGL,但在可视化矩阵及其在计算机图形学中的作用时遇到了问题。给定这样的4x4矩阵模板:

在此处输入图片说明

我假设像这样的每个矩阵都是世界空间中顶点的坐标。然后将它们中的几个放在一起并加阴影给一个对象?

但是为什么会有a Xx,a Xy和an Xz?我读到它的轴是不同的(上,左,前),但仍然无法使意义变得有意义。

Answers:


19

计算机图形学中的矩阵是赋予模型中每个坐标的变换。每个矩阵都是应用于坐标(3空间中的一个点)的多个变换的组合。

构建变换基于以下三种变换类型之一:平移,旋转和缩放。

翻译矩阵类似于:

翻译矩阵

和比例矩阵: 比例矩阵

旋转矩阵如下所示:

在此处输入图片说明

要组合这些矩阵中的任何一个,只需将它们相乘即可。要将变换应​​用于顶点,只需将其乘以该顶点(如翻译图中所示)。


4
O矩阵不代表点。我现在很尴尬
Sad CRUD开发人员

很多时候,它们被应用于整个对象或视口(这就是您获得正交视图还是透视视图的方式)
Alex Shepard 2014年

3
@BDillan:不,但是它们肯定可以包含点。例如,ModelView矩阵的最后一列(GL / column-major)定义了原点的翻译方式。或者换种说法,它定义了眼睛在世界空间中的位置,并且可以单独用作一个点。
Andon M. Coleman 2014年

您的座标为3元组。为什么矩阵不是3乘以3?假设能够将三种类型的转换组合到一个矩阵中并且仍然有足够的空间,那么右下角在做什么,看起来总是1?
n611x007

第四行/列专门用于翻译。矩阵数学的最佳功能之一是,我可以将要完成的所有平移和旋转合并到一个矩阵中。这意味着可以将非常非常复杂的转换集(理论上无限)压缩为1个矩阵。是的,最后一个单元格仍为1,但它允许我们进行其余的数学运算。
Alex Shepard

10

在计算机图形学中,我们使用矩阵对变换进行编码。

仅包含平移,旋转或缩放变换的矩阵具有一种常用的解释:矩阵的左上3x3仅包含旋转或缩放数据,下一行或右列包含平移数据。这不是一般性,但对于人们使用它的计算机图形表示的转换子集而言,经常足够适用。

类似地,在矩阵的值和矩阵表示的相应坐标系之间存在一种关系(我不应该总是注意​​到它总是“世界空间”)。左上的3x3列(或行)代表坐标系的X,Y和Z轴。

行是否表示轴还是列确实取决于您是否使用乘以as row vector * matrix或的约定matrix * column vector。在执行矩阵乘法时,两个矩阵的内部维数必须一致,因此将矢量表示为行矩阵还是列矩阵都会影响选择(OpenGL和传统数学方法倾向于使用列向量)。

我建议读一本关于线性代数的好书,或者至少看看Matrix和Quaternion FAQ以及这篇有关DirectX和OpenGL中矩阵布局的文章。


关于线性代数,有很多“好书”,我什至已经阅读和理解。事实是,这没有什么帮助,不是我也没有理解我的意思。我觉得您的最后建议是在回答错误的假设。
n611x007

9

什么是矩阵?

具有m列和n行的矩阵表示一个函数,该函数使用带有元素(或坐标)的向量*m并生成带有n元素的向量。

从中可以看出,当且仅当矩阵为正方形时,向量的维数才会改变。例如。您可以通过转换3D矢量,从2D转换2D等获得3D矢量。

*:在物理学中,矢量通常用于表示“移动”事物(例如速度或加速度)的力或其他“影响”。但是,没有什么可以阻止您使用向量来表示点或任何数字数组(某些库和编程语言甚至使用“向量”来表示“一维数组”)。对于与矩阵一起使用,任何东西都可以是向量的元素(甚至是字符串或颜色),只要您具有将它们与矩阵元素相乘,相减和相乘的方法即可。因此,名称vector,意思是“载体”-它为您携带保存值。

乘以矩阵是什么意思?

那么,如果矩阵是一个函数,那么什么样的函数呢?该功能做什么?它的配方由矩阵的元素定义。让我们将其称为input u,output v,矩阵MM*u=v然后乘积与相同f(u)=v),并u(i)给出的ith个元素u(例如,第二个元素是y坐标)。对于矩阵,M(i,j)表示row i,column j

element的构造(v(1)结果中的第一个)由矩阵的第一行描述。u(1)M(1,1)u(2)多次M(1,2),... u(i)M(1,i)。矩阵有点像一种非常简单的编程语言,仅适用于编程功能,这些功能可以通过对输入进行混洗,将其添加到自身等来工作。**

想象一下您一次处理一个输出元素是很有帮助的,因此,您一次只使用矩阵的一行。您u水平书写。您将其写在M下面的第i行。您乘以上面/下面的每对,并在下面写下乘积,然后将乘积相加。对每一行重复操作以获取的每个元素v。(现在您了解了为什么mby n矩阵必须对m向量进行运算并产生n向量。)

考虑这种情况的另一种方式-假设我们正在执行3D到3D转换,因此3x3矩阵(或通常称为3D转换,因为您可以假装此“功能”正在“移动” 3D点,即使实际上是只是改变数字)。假设第一行是[1 2 0]。这意味着,要获取x的结果,请获取输入x的1,输入y的2和输入z的0。所以这真的是一个食谱。

**:如果矩阵是一种编程语言,那么它甚至不是图灵完整的。

两个矩阵相乘是什么意思?

如果它们都是适当大小的矩阵,则A*B表示“先应用函数,B然后应用A”。您会看到为什么存在对乘法大小的约束,因为大小决定了输入和输出大小,而一个矩阵消耗了另一个矩阵的输出。为什么乘法意味着合并函数?更容易注意到它必须是。If A*uf(u)B*u相同,g(u)f(g(u))与和f(B*u)相同A*(B*u)

同样,重复使用同一功能可以表示为幂,因为这A*A*A意味着应用A代表三次的功能。

矩阵有什么用?

进行类似的转换有什么好处new_x = 1*x+2*y+0*z(如果第一行是[1 2 0])?这不是很明显,但是让我们采用另一个2D矩阵对此进行解释。矩阵为:

[ 0 1
  1 0 ]

[0 1; 1 0]使用方便的Matlab表示法。这个矩阵做什么?它将像这样转换2D向量:对于结果的x,取输入y的1。对于结果y,取输入x的1。我们只是交换了输入的x和y坐标-这个矩阵反映了关于x = y线的点。这很有用!通过扩展,您会看到沿SW - NE线的所有矩阵均为1的情况都将反射。您还可以看到为什么身份矩阵给您输入(对于x输出,取x输入;对于y输出,取y输入...)。

现在您了解为什么符号是例如。XxYx-他们的意思是多少投入XY等进入输出x

矩阵还有什么用?

您还可以进行哪些其他转换?您可以通过采用一个单位矩阵来调整大小,但沿对角线的数字不能为1。例如,[2.5 0; 0 22.5]将输入的每个坐标乘以2.5,如果将此矩阵应用于图片中的每个点,则图片的大小将为2.5。如果仅将2.5放在一行([2.5 0; 0 1])中,则将仅乘以x坐标,因此只能沿x拉伸。

其他矩阵可以进行其他转换,例如“倾斜”,这些转换具有不同程度的有用性。就个人而言,偏斜是我最不喜欢的,因为矩阵看起来很简单,但变换本身几乎不做任何事情,只需要弄乱图片即可。一个有用的是“旋转”-如何旋转一个点?绕原点逆时针(x, y)旋转角度后,尝试计算出点的位置theta。您会发现,新的x和y坐标都是通过将旧的x和y乘以theta的某些正弦和余弦得出的。您应该能够使用与该函数相对应的正弦和余弦轻松编写旋转矩阵。

使用非平方矩阵,您还可以更改输入的维数。将2D输入转换为3D并不是很有用,因为很难“制造”要放入新坐标的东西,但是将3D转换为2D非常有用。别的不说,这是你的电脑是如何知道项目*** 3D场景到2D图像绘制在显示器上。

由于向量可以容纳不同的事物,因此您甚至可以描述一个矩阵,该矩阵一次将字符串n个字符改组或将它们“相乘”或“相乘”(您必须提供乘法/加法函数)。

***投影时,您将3D对象像雕塑一样,在其上照亮灯光,然后查看在墙壁上滴下什么样的2D阴影。

矩阵的局限性是什么?

矩阵可以执行所有功能吗?不。以图形方式思考时,很难想象矩阵无法做到的事情(但它确实存在:例如,“漩涡”效果无法实现)。但是,这里有一个简单的例子:假设功能f是这样的,f(u)让你回来u 与方形的每一个元素。您将看到,您无法为此编写矩阵:使用矩阵,只有一种工具可以描述将坐标乘以常数的配方,而不能表达其他类似幂的函数。

****:这也是为什么它被称为线性代数的原因-幂函数是非线性的,绘制时不会形成直线。

在4D矩阵中奇怪的额外行

现在,为什么您的示例中的矩阵是4×4?这不是4维空间吗?我们没有4D电脑,那为什么呢?对于与先前关于线性运算的观点有关的矩阵,这实际上是一个有趣的技巧。

关于不能使用矩阵完成哪些功能:将2D点向右移动2个单位的矩阵是什么(产生点(x+2, y)?再次,我们陷入了困境。有一种方法可以使输入相乘,但无法相加对于2D工作,诀窍是假装您实际上不在2D空间中,而是在3D空间中,除了所有东西的高度(z坐标或第3个元素)始终为1(有点像2D宇宙如何)只是一个沿着3D宇宙的地板平放的“盘子”(在这种情况下,第三个坐标始终为0)。因此,您可以将此不可思议的最后一个坐标用作常数,因为您知道每个输入的坐标始终为1。

同样,要移动3D点,您需要4D坐标。这就是为什么您看到的所有3D转换矩阵都将[0 0 0 1]作为最后一行的原因-您绝不能更改第4维,否则结果将太复杂而无法在3D中表示!


那么如何做加法矩阵呢?比如说一行是Xx Yx Zx Tx...,而最后一行实际上0t 0t 0t 1t是从中替换的Xt Yt Zt Tt。为了(x+2, y)(x, y)你可以去1x 0y 0z 2t,会给你1*x + 0*y + 0*z + 2*1因为t=1对不对?几乎等于x + 2。哦,亲爱的,现在您可以用有趣的T值弄乱渲染了,不是吗?-grin-(长读,仍然是最佳价值,thx)
n611x007

2

那是一个4x4的列主矩阵,从它的外观看,就是一个视图矩阵。

前三列定义基本矢量的方向(如您所称的那样向上,向左,向前),最后一列定义视点的平移。将它们放在一起,您可以描述相机的方向,更重要的是,您可以使用此矩阵将点转换为坐标空间,称为“眼睛空间”,“视图空间”或“相机空间”。

这些都是相同坐标空间的同义词。不幸的是,在处理计算机图形时,您必须学习所有同义词,因为不同的书籍和人们会用不同的名称来称呼它们。大多数坐标空间都有多个名称。

顺便说一句,视图矩阵中的三列通常是正交的,即它们彼此成直角。这不是必需的,但是在构造传统相机时这是非常常见的属性。


1

TL; DR版本:

[x y z]每行中的前三个元素表示变换后的坐标系的单个基本向量。最后一个元素w是翻译组件。

长版

如果您需要一个矩阵,当该矩阵应用于顶点时,可以使顶点绕原点旋转例如45度,则可以用代表变换轴的三个向量填充矩阵:

  • 的点i上的x[1 0 0],但旋转了45度。这很简单[i_x i_y i_z],其中i_xi_y是与X轴成45度内角的三角形的边:[cos(45) sin(45) 0]
  • jy轴上的点[0 1 0],但从该轴旋转了45度。将其草绘在一张纸上,您会看到,逆时针旋转时,组件变为[-sin(45) cos(45) 0]
  • 的点k上的z轴。在此示例中,z由于我们在(屏幕对齐)xy平面中旋转,因此不会受到影响

因此,我们有了三个新向量:i,j,k。可视化此方法的简单方法是仅使用X和Y轴并旋转整个十字排列。

我们如何将它们放在矩阵中?

i_x i_y i_z
j_x j_y j_z
k_x k_y k_z

要么

 cos(45)  sin(45)    0
-sin(45)  cos(45)    0
    0        0       1

如果将任何顶点乘以该矩阵,您将得到

v1_x = v_x cos(Θ)     - v_y sin(Θ) + v_z * 0
V1_y = v_x*sin(Θ)    + v_y cos(Θ) + v_Z * 0
V1_z = v_x * 0        + v_y * 0    + v_z * 1

v = [1 0 0]Θ = 90°,这成为v1 = [0 1 0]

对于翻译,我们添加第四行和第四列,并将翻译组件放在最后一列中。我们向顶点添加第四个分量,w通常为1。这样,当我们将顶点乘以矩阵时,w分量会导致将最后一列添加到输入顶点,因此将移动或平移顶点。我们称这些为“均匀坐标”。(出于我们的目的,“同质”仅表示w每个向量中都有第4个分量,我们使用4x4矩阵而不是3x3。通常,您会看到使用4x3矩阵的着色器以避免发送几乎无用的第4行到GPU,这会消耗宝贵的内存和带宽。透视投影需要第4行,但不需要太多。)

希望这可以帮助。


2
那一刻,当您意识到自己刚刚回答了三年前的一个已经回答的问题时……
3Dave

:P在回答之前,请务必先查看问题日期...
HolyBlackCat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.