SoRoMan

人若无名,便可专心练剑。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

 

 还是关于矩阵的碎碎念,接上篇:思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用问题:左乘/右乘,行优先/列优先,...

纯粹个人观点,欢迎探讨:

5。矩阵的级联顺序与坐标系的关系:

 1). 变换的时候,坐标系的选取是必需的

物体的方位都是相对的,选定参考坐标系才能描述方位。一般参考坐标系可以分为两种:1.全局/固定坐标系 2.局部坐标系/物体坐标系。故名思义,前者是固定不动的,后者是随物体方位变化而变化的。

举个例子:伸出左手,手掌水平,掌心向上,大拇指向左,其余四指向前。此时选定物体的局部坐标系(Cl(Ol,Xl,Yl,Zl))为:掌心为原点(Ol),X轴(Xl)指向四指指向,Z(Zl)轴指向大拇指指向,Y轴(Yl)指向掌心向上。全局坐标系(Cg(Og,Xg,Yg,Zg))选定为和本地坐标系重合。那么,移动你的左手,局部坐标系就会随手而动。全局坐标系还是原先的方位。为什么选定坐标系对于变换重要?因为相对于哪种坐标系做变换得出的结果是不一定相同的。

还是上面那个例子:现在开始做变换,给你个指令:沿X轴旋转手掌90度使得掌心向右,然后手掌沿Y轴向+Y方向移动10厘米。

你做完后,得出的结果可能有3种:

1. 手的位置比原先高了10厘米,这部分人居多。

2. 手的位置比原先靠右10厘米,这部分人居少。

3. 还有部分数人傻在那,变换不来,这部分人其实不傻。

其实这个变换指令没有指定参考坐标系,是变换不出来的。1类的是自己选了全局坐标系,2类是选了局部坐标系,3类的没自己选。

所以,变换的时候,坐标系的选取是必需的。

 

2). 级联顺序与坐标系选取的关系

回到矩阵变换,一般我们说的对物体X进行M1变换,即X’= X*M1 (使用Column Matrix约定),隐含了选取全局坐标系的约定。单一变换的没有级联顺序的问题。如果再进行一个M2变换,此时,X’= X*M1*M2 还是X’= X*M2*M1呢?我们可能都知道是X’= X*M1*M2。显然嘛,先做的变换先乘,但深层的原因是什么呢?答案是隐含的全局坐标系的选定,如果选定的是局部坐标系,那么X’= X*M2’*M1’。后面一个变换反而要先进行。不信,看例子:

还是手掌例子,先旋转后平移, 给你个指令:沿Xg轴旋转手掌90度使得掌心向右,然后手掌沿Yg轴向+Yg方向移动10厘米。

这下清楚不过了,完成后手掌比原先高了10厘米。此时变换公式:X’= X*R(Xg)*T(Yg)

现在,指令是参考局部坐标系,变换顺序是反向的,先平移后旋转:

手掌沿Yl轴向+Yl方向移动10厘米,然后沿Xl轴旋转手掌90度使得掌心向右。

看看完成后的结果,手是不是和上面的方位一样?此时变换公式:X’= X*T(Yl)*R(Xl)

 正序级联是相对于全局坐标系,逆序级联相对于局部坐标系,殊途同归。下次有变换矩阵需要级联的时候,先看看变换的矩阵是相对于全局还是局部的坐标系。


一般规律:假定对物体X施加M1变换和M2变换,两个变换矩阵均为相对于全局坐标系。有:

X’ = X*M1(g)*M2(g)

可以看作是将X先经过M1(g)变换,再进行M2(g)变换,得到X’

由矩阵的结合律,上面等式等价于:

X’ = X*M2(g)*(M2(g)-1*M1(g)*M2(g))     M2(g)-1M2(g)的逆矩阵)

所以,这个过程也可以这么看,先对X进行M2(g)(也即M2(l))变换(M2(g)为相对于全局坐标系,但此时全局和局部坐标系的重合,所以M2(g)=M2(l)),再对X进行M2(g)-1*M1(g)*M2(g)变换(也即M1(l)变换),这个变换实际上相当于先将物体退回到原方位(此刻局部坐标系退回到原始方位,也就是全局坐标系方位)进行M1(g)变换后,再进行M2(g)变换回来。M2(g)-1*M1(g)*M2(g)整体的效果就是相对于此时的局部坐标系的进行M1(l)变换。故:

X’ = X*M2(l)*M1(l)

即,如果将变换认为是相对于局部坐标系而进行的,那么矩阵级联顺序正好相反。

(注:上面推导有个这样的前提:即初始变换时,选定局部坐标系和全局坐标系重合。如果局部坐标系是一般选取,即局部坐标系相对于全局坐标系的变换M(l/g) != Identity呢,答案是结论一样。因为M(l/g)可以认作是对于物体的变换。将X换成X(new)=X*M(l/g)而已。)

 

3). 如何选取,如何级联

碰到的场景:

 l 人手的运动

手有很多关节,每个关节的一端可以绕着关节处运动,关节本身也可以运动,要表达手指尖相对于人体的运动,使用相对于局部坐标系(关节)的变换比选取全局坐标系(人体)的变换要简单清晰得多。

比如:一个从手臂下垂到做出向上抬手手的动作之间,现在用矩阵变换来表达手掌的变换(X->X’)。

如果你选定局部坐标系(各个关节)做变换,那么其表达就是:

上手臂绕肩关节旋转90度(M1()),下手臂绕肘关节转45度(M2()),手掌绕踝关节转30度(M3()),那么:

X’ = X*M3()*M2()*M1()

(注意和X’ = X*M1()*M2()*M3()的不同)


如果你选定全局坐标系(人体/肩关节)做变换,那么其表达就是:

上手臂绕肩关节旋转90度(M1()),下手臂绕肩关节(M2()), 手掌绕肩关节(M3())。。绕不过来了吧(M2(), M3()很难表示出来)

X’ = X*M1()*M2()*M3()

 

 

   l 矩阵分解与 级联顺序

  |R 0|

  |T 1|

  = R*T (先进行旋转变换,后进行平移变换, 基于global坐标系)
  = T*R (先进行平移变换,后进行旋转变换, 基于local坐标系)

  = R*T' (先进行旋转变换,后进行平移变换, 基于local坐标系, T'= R-1*T*R)

  = T*R' (先进行平移变换,后进行旋转变换, 基于global坐标系, R' = T-1*R*T)

 

 

 4). 结论

注意矩阵级联顺序和坐标系选取的关系。在整体/部分相对运动较多的地方,选取局部坐标系描述变换。

 

 

posted on 2009-05-15 17:47  SoRoMan  阅读(2642)  评论(0编辑  收藏  举报
free web counters
Vistaprint Discount Codes