好的,所以我知道当我调用glRotatef()时它会这样做,
C = C * M
其中“C”是堆栈上的当前矩阵,“M”是由glRotatef()计算的矩阵。但是,这会导致对象围绕其局部轴旋转。 如果我想围绕其全局轴旋转对象,我必须做
C = M * C
所以例如,如果我想围绕全局x旋转,然后是全局y,那么全局z。它会是
C = Mz * My * Mx * C
我测试了它并且它有效。我想知道为什么我们必须预乘全球轮换,反之亦然。
我的案例中的“C”是模型视图矩阵。 注意我不是在谈论预先乘以矩阵与向量。我知道所有的专栏 - 主要的主要内容。我想知道前/后将转换乘以另一个矩阵4x4的后果。
答案 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 * M
,I
的输入空间是特定的模型空间。您现在正在为此添加一个新的转换,它有自己的输入和输出空间。通过将它们相乘以形成单个转换,您将声明一些内容:
C
,Mo
的输出空间,相同的空间,M
,Ci
的输入空间。因此,我们现在处理三个空格:C
,Mi
和Mo/Ci
。
但是,Co
是这些转换的组合。它从空间D
到空间Mi
;我们从未见过Co
。 Mo/Ci
和C
之间的差异是它们的输入空格。
这就是:空间D
,Co
的输出空间?它有一个特定的名称:世界空间。
因此,C
与D
一样进入与完全相同的世界空间。因此,正确倍增不会引起围绕世界空间的旋转也就不足为奇了。
让我们来看看:C
。在这里,我们有不同的情况。 E = M * C
与E
具有相同的输入空间(模型空间),但它现在具有不同的输出空间。也就是说,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
转换
注意到我为列 - 市长命令写了矩阵运算。