zoukankan      html  css  js  c++  java
  • (转)思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用问题:左乘/右乘,行优先/列优先,...

    转自:http://www.cnblogs.com/soroman/archive/2008/03/21/1115571.html

    思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用

    1。矩阵和线性变换:一一对应

    矩阵是用来表示线性变换的一种工具,它和线性变换之间是一一对应的。
    考虑线性变换:
    a11*x1 + a12*x2 + ...+a1n*xn = x1'
    a21*x1 + a22*x2 + ...+a2n*xn = x2'
    ...
    am1*x1 + am2*x2 + ...+amn*xn = xm'

    对应地,用矩阵来表示就是:
    |a11 a12 ... a1n   |   |x1|     |x1'| 
    |a21 a22 ... a2n   |   |x2|     |x2'|
    |...                      |* |...|=    |... |
    |am1 am2 ... amn |   |xn|     |xm'|

    也可以如下来表示:
                       |a11 a21 ... am1| 
                       |a12 a22 ... am2|  
    |x1 x2...xn|*|...                   |= |x1' x2'... xm'|      
                       |a1n a2n ... amn| 

    其中涉及到6个矩阵。分别为A[m*n],X[n*1],X'[m*1]以及X[1*n],A[n*m],X'[1*m]。
    可以理解成向量x(x1,x2,...,xn)经过一个变换矩阵A[m*n]或A[n*m]后变成另外一个向量x'(x1',x2',...,xm'))。

    2。矩阵的表示法:行矩阵 vs. 列矩阵


    行矩阵和列矩阵的叫法是衍生自行向量和列向量。
    其实,矩阵A[m*n]可以看成是m个n维的row vector构成的row matrix,也可看成是n个m维的column vector构成的column matrix。
    其中,X[n*1]/X'[m*1]就等价于1个n/m维的column vector。X[1*n]/X'[1*m]就等价于1个n/m维的row vector。
    Row matrix和Column matrix只是两种不同的表示法,前者表示把一个向量映射到矩阵的一行,后者表示把一个向量映射到矩阵的一列。
    本质上体现的是同一线性变换。矩阵运算规定了它们可以通过转置运算来改变这个映射关系。

    3。矩阵的相乘顺序:前乘或左乘 vs. 后乘或右乘


    需要注意的是两种不同的表示法对应不同的运算顺序:
    如果对一个column vector做变换,则变换矩阵(row matrix/vectors)必须出现在乘号的左边,即pre-multiply,又叫前乘或左乘。
    如果对一个row vector做变换,则变换矩阵(column matrix/vectors)必须出现在乘号的右边,即post-multiply,又叫后乘或右乘。
    一般不会弄错,因为矩阵乘法性质决定了相同的内维数的矩阵才能相乘。至于为什么是这个规律,为什么要row vector乘以column vector或column vector乘以row vector???想想吧。。。

    所以左乘还是右乘,跟被变换的vector的表示形式相关,而非存储顺序决定。

    4。矩阵的存储顺序:按行优先存储 vs. 按列优先存储

    涉及到在计算机中使用矩阵时,首先会碰到存储矩阵的问题。
    因为计算机存储空间是先后有序的,如何存储A[m*n]的m*n个元素是个问题,一般有两种:按行优先存储和按列优先存储。

    row-major:存成a11,a12,...,amn的顺序。
    column-major:存成a11,a21,...,amn的顺序。

    这样问题就来了,给你一个存储好的矩阵元素集合,你不知道如何读取元素组成一个矩阵,比如你不知道a12该放在几行几列上。
    所以,每个系统都有自己的规定,比如以什么规则存储的就以什么规则读取。DX使用Row-major,OGL使用Column-major.即一个相同的矩阵A[m*n]在DX和OGL中的存储序列是不一样的,这带来了系统间转换的麻烦。

    不过,一个巧合的事情是:DX中,点/向量是用Row Vector来表示的,所以对应的变换矩阵是Column Matrix/Vectors,而OGL中,点/向量是用Column Vector来表示的,所以对应的变换矩阵是Row Matrix/Vectors.所以,如果在DX中对一个向量x(x1,x2,x3,1)或点(x(x1,x2,x3,1))应用A[4*4]的矩阵变换,就是x' = x(x1,x2,x3,1) * A[4*4],由于采用Row-major,所以它的存储序列是a11,a12,...,a43,a44。在OGL中,做同样的向量或点的变换,因为其使用Row Matrix/Vectors,其应用的变换矩阵应该是A'[4*4] = A[4*4]( ' 表示Transpose/转置),就是x' = A'[4*4] * x'(x1,x2,x3,1),但是由于采用Column-major,它的存储序列正好也是a11,a12,...,a43,a44!!!
    所以实际上,对DX和OGL来讲,同一个变换,存储的矩阵元素序列是一样的.比如:都是第13,14,15个元素存储了平移变化量deltaZ,deltaY,deltaZ.

    Refs:
    http://mathworld.wolfram.com/Matrix.html
    http://www.gamedev.net/community/forums/topic.asp?topic_id=321862

  • 相关阅读:
    引擎设计跟踪(一)
    Gamebyro 加入CEGUI
    开播庆祝
    引擎设计跟踪(八) Mile stone 2 准备中
    引擎设计跟踪(六)
    编辑器框架的思考
    地形法线贴图的优化
    引擎设计跟踪(五)
    引擎设计跟踪(九.2) 3DS MAX 导出插件 继续
    引擎设计跟踪(三)
  • 原文地址:https://www.cnblogs.com/wonderKK/p/4243582.html
Copyright © 2011-2022 走看看