Opengl为什么在全球空间旋转时预乘矩阵?

时间:2017-08-15 08:07:27

标签: c++ opengl matrix rotation

好的,所以我知道当我调用glRotatef()时它会这样做,

C = C * M

其中“C”是堆栈上的当前矩阵,“M”是由glRotatef()计算的矩阵。但是,这会导致对象围绕其局部轴旋转。 如果我想围绕其全局轴旋转对象,我必须做

 C = M * C

所以例如,如果我想围绕全局x旋转,然后是全局y,那么全局z。它会是

C = Mz * My * Mx * C

我测试了它并且它有效。我想知道为什么我们必须预乘全球轮换,反之亦然。

我的案例中的“C”是模型视图矩阵。 注意我不是在谈论预先乘以矩阵与向量。我知道所有的专栏 - 主要的主要内容。我想知道前/后将转换乘以另一个矩阵4x4的后果。

2 个答案:

答案 0 :(得分:2)

转换矩阵的核心是将位置/方向从空间I转换为空间O:输入到输出的函数。因此,转换的行为很像功能组合。 f(g(X))g(f(X))之间存在差异。

所以你从一个矩阵C开始,给定一个位于空间Vi的顶点I,这将是真的:Vo = C * Vi,其中{{1} }}是空间Vo中的顶点。

所以,让我们回到原来的例子:O。为了减少混淆(我需要谈论原始的C = C * M和输出),我将给新矩阵一个特定的名称:C

空间D = C * MI的输入空间是特定的模型空间。您现在正在为此添加一个新的转换,它有自己的输入和输出空间。通过将它们相乘以形成单个转换,您将声明一些内容:

CMo的输出空间,相同的空间MCi的输入空间。因此,我们现在处理三个空格:CMiMo/Ci

但是,Co是这些转换的组合。它从空间D到空间Mi;我们从未见过CoMo/CiC之间的差异是它们的输入空格。

这就是:空间DCo的输出空间?它有一个特定的名称:世界空间

因此,CD一样进入与完全相同的世界空间。因此,正确倍增不会引起围绕世界空间的旋转也就不足为奇了。

让我们来看看:C。在这里,我们有不同的情况。 E = M * CE具有相同的输入空间(模型空间),但它现在具有不同的输出空间。也就是说,C转化为的世界空间与E转化为的世界空间不同。

如果你想旋转相对于世界空间的东西,那就是你想要的。您正在更改该对象的世界空间。

如果更改变换的模型空间,则相对于模型空间进行变换。如果更改变换的世界空间,则相对于世界空间进行变换。

答案 1 :(得分:1)

让我们从全球坐标系开始。您在第一个系统中有一个点V(x,y,z,w)

接下来,您可以在轴上进行旋转。旋转以矩阵M1定义。想想旋转轴,而不是点。现在可以在此新坐标系中将同一点V表示为V'(x', y', z', w')。我们知道我们可以得到这些新的坐标
V' = M1·V使用col-mayor顺序并且V是4x1矩阵。

接下来,我们希望围绕可能的其他轴进行第二次旋转。 M2是旋转矩阵。但是等等,我们是要将相对轮换到第二个系统还是第一个系统?

V" = M2·V

V" = M2·V'

“不”,你说,“相对于第二个已旋转的坐标系。”
确定。所以你有:

V" = M2·V'  = M2·(M1·V) = (M2·M1)·V  but **NOT=** (M1·M2)·V

关键是您将转换矩阵应用于以前的系统。您应用多个转换的顺序不是可交换的。例如,尝试'先翻译然后旋转'与'先旋转然后翻译'。

以角度alpha旋转一个点或用相反的-alpha旋转轴会产生相同的最终坐标。换句话说,您执行相同的矩阵运算。

然后用你的C,M命名法,让我们得到C·M和M·C之间的区别
V1 = C·V0本地对象轴转换为全局轴
V2 = M·V0在局部对象轴上旋转(变换) 在{em>转换为全局后,V3 = M·V1 = M·C·V0旋转,这是在全局轴上 在在本地中旋转后,V4 = C·V2 = C·M·V0转换

注意到我为列 - 市长命令写了矩阵运算。