理解OpenGL中的翻译矩阵

时间:2016-12-27 23:46:04

标签: opengl

假设我们要将带有p(1, 2, 3, w=1)向量的点v(a, b, c, w=0)转换为新点p'

注意:w=0代表一个向量,而w=1代表OpenGL中的一个点,如果我错了,请纠正我。

在仿射变换定义中,我们有:

p + v = p'

=> p(1, 2, 3, 1) + v(a, b, c, 0) = p(1 + a, 2 + b, 3 + c, 1)

=> point + vector = point (everything works as expected)

在OpenGL中,翻译矩阵如下:

1 0 0 a
0 1 0 b
0 0 1 c
0 0 0 1

我认为(a, b, c, 1)是来自仿射变换定义的向量 为什么我们有w=1,而不是w=0,例如

1 0 0 a
0 1 0 b
0 0 1 c
0 0 0 0

2 个答案:

答案 0 :(得分:2)

  

注意:w=0代表一个向量,而w=1代表OpenGL中的一个点,如果我错了,请纠正我。

你错了。首先,这与OpenGL没有任何关系。这大约是homogenous coordinates,这是一个纯粹的数学概念。它通过将n维向量空间嵌入到n + 1维向量空间中来工作。在3D情况下,我们使用4D同质坐标,定义为同质向量(x, y, z, w)表示笛卡尔坐标中的3D点(x/w, y/w, z/w)

因此,对于任何w != 0,您都会获得某个有限点;对于w = 0,您将描述一个无限远的点到特定方向。这意味着同质坐标更强大,因为它们实际上可以用有限坐标描述无限远点(这对于透视变换非常方便,其中无限远点被映射到有限点,反之亦然)。

作为一种捷径,您可以将(x,y,z,0)想象成一些方向向量。但有一点,它不只是w=1,而是任何 w值不等于0.从概念上讲,这意味着任何笛卡尔3D点都由线表示在同质空间中(我们确实上升到了一个维度,所以这实际上是有意义的)。

  

我假设(a,b,c,1)是来自仿射变换定义的向量,为什么我们有w = 1,但不是w = 0?

你的假设是错误的。关于同质坐标的一点是我们不在4D空间中应用平移。我们通过在4D空间中实际进行剪切操作来获得3D空间中的平移效果

所以我们在同质空间中真正想做的是

(x + w *a, y + w*b, z+ w*c, w)

因为结果矢量的3D解释将是

(x + w*a) / w  == x/w + a
(y + w*b) / w  == y/w + b
(z + w*c) / w  == z/w + c

代表我们追求的翻译。

所以试着让这个更清楚:

您在问题中所写的内容:

p(1, 2, 3, 1) + v(a, b, c, 0) = p(1 + a, 2 + b, 3 + c, 1)

显然我们想做什么。你描述的是关于4D向量空间的仿射变换。

但我们真正想要的是3D笛卡尔坐标中的平移,所以

 (1, 2, 3) + (a, b, c) = (1 + a, 2 + b, 3 + c)

应用你的公式实际上意味着在同质空间中进行翻译,这会产生由w坐标进行缩放的翻译效果,而我给出的公式将始终将点转换为{ {1}},无论我们选择哪个(a,b,c)

如果我们选择w,那当然不是这样。然后,我们将完全没有变化,这也是正确的,因为翻译永远不会改变方向 - 你的公式会改变方向。您的公式仅适用于w=0,这只是一个特殊情况。但这里的关键点是我们毕竟不是做矢量加法,而是矩阵*向量乘法。同质坐标只允许我们(以及更强大的东西)通过矩阵乘法来表示平移。但这并不意味着我们可以将最后一列解释为翻译向量,就好像我们做了向量加法一样。

答案 1 :(得分:1)

简单回答

原因是矩阵乘法的工作方式。如果将矩阵乘以向量,则结果的w分量是矩阵的第4行与向量的内积。应用变换后,点仍然应该是一个点,方向应该是一个方向。如果将其设置为0向量,则结果将始终为0,因此,结果向量将从位置(w = 1)更改为方向(w = 0)。

更详细的回答

仿射变换的定义是:

  x'      A | t       x 
[   ] = [   |   ] * [   ]
  1       0 | 1       1

其中,A是线性地图,是翻译。传统上,线性地图由数学家以矩阵形式编写。注意,这里的t与x类似,是一个三维向量。如果我们总是必须处理线性映射矩阵和平移向量,那么它现在将是繁琐的(并且不太通用,考虑投影映射)。这可以通过向映射引入附加维度来解决,即所谓的齐次坐标,其允许我们将线性映射以及平移向量存储在组合的4×4矩阵中。这被称为增强矩阵,根据定义,

@foreach ($sallary as $emp)
<p>Name: {{ $emp->employee['name'] }} :: Value: {{ $emp['value'] }}</p>
@endforeach

还应该注意,现在可以通过将增广矩阵相乘来非常容易地组合仿射变换,这在矩阵加矢量符号中很难做到。

还应该注意,右下角1不是平移向量的一部分,它仍然是三维的,但是矩阵增强。

您可能还想在此处阅读有关“增强矩阵”的部分:https://en.wikipedia.org/wiki/Affine_transformation#Augmented_matrix