(注意,由于格式问题,文中如p-c、c-p、c、p这类的为矢量的下标,-1、T为矩阵的上标)
假设现在有一个父坐标空间以及一个子坐标空间,已知父级坐标空间中子级坐标空间的原点位置以及3个单位坐标轴,此时一般由两种需求:一种是将子坐标空间下表示的点或矢量Ac转换到父坐标空间下的表示Ap;另一种需求是反过来,即把父坐标空间下表示的点或矢量Bp转换到子坐标空间下的表示Bc。可以使用下面的两个公式来表示这两种需求:
Ap = Mc-p Ac
Bc = Mp-c Bp
其中Mc-p表示从子坐标空间变换到父坐标空间的变换矩阵,而Mp-c是其逆矩阵(即反向变换)。此时,只需求解出其中一个矩阵,另一个通过求逆矩阵的方法来得到。
当给定一个坐标空间以及其中的一点(a, b, c)时,可以通过4个步骤来确定它的位置:
1.从坐标轴的原点开始;
2.向x轴方向移动a个单位;
3.向y轴方向移动b个单位;
4.向z轴方向移动c个单位。
此时已知子坐标空间C的3个坐标轴在父坐标空间P下的表示Xc,Yc,Zc,以及其原点位置Oc。当给定一个子坐标空间中的一个点Ac = (a,b,c),使用上述的4步来确定点Ac在父坐标空间下的位置Ap:
1.从坐标空间的原点开始:
已知子坐标空间的原点位置Oc;
2.向x轴方向移动a个单位
Oc + aXc
3.向y轴方向移动b个单位
Oc + aXc + bYc
4.向z轴方向移动c个单位
Oc + aXc + bYc + cZc
此时得到公式:
Ap = Oc + aXc + bYc + cZc (将所有矢量展开)
其中“|”符号表示按列展开,最后还可以加上加法表达式即平移变换,此时需要将上面公式中的3x3矩阵扩展到齐次坐标空间中,得到
此时,可得Mc-p 矩阵为
一旦求出Mc-p矩阵后,Mp-c矩阵可以通过求逆矩阵的方法得到。
由矩阵结果可以看出,变换矩阵Mc-p实际上可以通过坐标空间C在坐标空间P中的原点和坐标轴的矢量表示来构建的:把3个坐标轴一次放入矩阵的前3列,把原点矢量放到最后一列,再用0和1填充最后一行即可。
需要注意的是,并不需要要求3个坐标轴Xc,Yc,Zc是单位矢量,实际上如果存在缩放的话,这3个矢量很可能不是单位矢量。
使用反向思维,可以从这个变换矩阵反推来获得子坐标空间的原点与坐标轴方向。例如,已知从模型空间到世界空间的一个4x4的变换矩阵,可以提取它的第一列再进行归一化后(为了消除缩放的影响)来得到模型空间的x轴再世界空间下的单位矢量表示。同样的方法可以提取y轴和z轴。
从另一个角度来理解这个提取过程,因为矩阵Mc-p可以把一个方向矢量从坐标空间C变换到坐标空间P中,那么只需要用这个矩阵来变换坐标空间C的x轴(1,0,0,0),即使用矩阵乘法 Mc-p[1,0,0,0]T,得到的结果正是Mc-p矩阵的第一列。
由于对方向矢量进行的坐标空间变换是可以忽略位置变换(平移)的,所以对方向矢量的坐标空间变换可以使用3x3矩阵,即
Mc-p =
再Shader中,常常截取变换矩阵的前3行与前3列来对法线方向、光照方向进行空间变换。
前面提过Mc-p表示从子坐标空间变换到父坐标空间的变换矩阵,而Mp-c是其逆矩阵(即反向变换由父坐标空间变换到子坐标空间),但是当Mc-p为正交矩阵时,矩阵的逆矩阵等于它的转置矩阵,即Mc-p-1 = Mc-pT,所以
此时,不仅可以通过变换矩阵Mc-p反推出子坐标空间的坐标轴方向再父坐标空间中的表示Xc,Yc,Zc,还可以反推出父坐标空间的坐标轴方向再子坐标空间中的表示Xp,Yp,Zp,这些坐标轴对应的就是变换矩阵Mc-p的每一行。
也就是说,若坐标空间变换矩阵Ma-b是一个正交矩阵,那么就可以提取其第一列来得到坐标空间a的x轴在坐标空间b下的表示,还可以提取其第一行来得到坐标空间b的x轴在坐标空间a下的表示。反过来,如果知道坐标空间b的x,y,z轴(必须是单位矢量,否则构建出来的就不是正交矩阵了)在坐标空间a下的表示,就可以将它们依次放在矩阵的每一行来得到坐标空间a到坐标空间b的变换矩阵了。