转自: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

(转)思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用问题:左乘/右乘,行优先/列优先,...的更多相关文章

  1. 矩阵-DirectX与OpenGL的不同

    http://www.cnblogs.com/graphics/archive/2012/08/02/2616017.html 矩阵是三维图形学中不可或缺的部分,几乎所有和变换相关的操作都涉及矩阵,世 ...

  2. HihoCoder 1480:矩阵填数 (杨氏矩阵 || 钩子公式 + 筛逆元)

    描述 小Hi在玩一个游戏,他需要把1, 2, 3, ... NM填入一个N行M列的矩阵中,使得矩阵每一行从左到右.每一列从上到下都是递增的. 例如如下是3x3的一种填法: 136 247 589 给定 ...

  3. Real-Time Rendering (2) - 变换和矩阵(Transforms and Matrics)

    http://blog.csdn.net/silangquan/article/details/9970673 提要 在图形的计算中,比如旋转.缩放.平移.投影等操作,矩阵都扮演着极其重要的角色,它是 ...

  4. YTU 2418: C语言习题 矩阵元素变换

    2418: C语言习题 矩阵元素变换 时间限制: 1 Sec  内存限制: 128 MB 提交: 293  解决: 155 题目描述 将一个n×n(2<n<10,n为奇数)的矩阵中最大的元 ...

  5. OpenGL入门1.5:矩阵与变换

    每一个小步骤的源码都放在了Github 的内容为插入注释,可以先跳过 前言 在阅读本篇博客之前,你必须对向量和矩阵有基本的认识,并且能熟练进行向量和矩阵的运算 我们已经知道了如何创建一个物体.着色.加 ...

  6. 关于opengl中的矩阵平移,矩阵旋转,推导过程理解 OpenGL计算机图形学的一些必要矩阵运算知识

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12166896.html 为什么引入齐次坐标的变换矩阵可以表示平移呢? - Yu Mao的回答 ...

  7. Opengl中矩阵和perspective/ortho的相互转换

    Opengl中矩阵和perspective/ortho的相互转换 定义矩阵 Opengl变换需要用四维矩阵.我们来定义这样的矩阵. +BIT祝威+悄悄在此留下版了个权的信息说: 四维向量 首先,我们定 ...

  8. OpenGL中投影矩阵的推导

    本文主要是对红宝书(第八版)第五章中给出的透视投影矩阵和正交投影矩阵做一个简单推导.投影矩阵的目的是:原始点P(x,y,z)对应后投影点P'(x',y',z')满足x',y',z'∈[-1,1]. 一 ...

  9. OpenGL中glRotatef()函数究竟对矩阵做了什么

    OpenGL中glRotatef()函数究竟对矩阵做了什么 我们知道OpenGL中维持着两套矩阵,一个是模型视图矩阵(model view matrix),另一个是投影矩阵(projection ma ...

随机推荐

  1. 巧用CSS3 :target 伪类制作Dropdown下拉菜单(无JS)

    :target 是CSS3 中新增的一个伪类,用以匹配当前页面的URI中某个标志符的目标元素(比如说当前页面URL下添加#comment就会定位到id=“comment”的位置,俗称锚).CSS3 为 ...

  2. 《Go语言实战》摘录:6.1 并发 - 并行 与 并发

    6.1 并行 与 并发

  3. .Net 垃圾回收和大对象处理 内存碎片整理

    CLR垃圾回收器根据所占空间大小划分对象.大对象和小对象的处理方式有很大区别.比如内存碎片整理 —— 在内存中移动大对象的成本是昂贵的,让我们研究一下垃圾回收器是如何处理大对象的,大对象对程序性能有哪 ...

  4. Unity3D实践系列01,创建项目

    下载并安装Unity5软件客户端. 打开软件,注册Unity帐号,并用注册帐号登录. 点击"创建Project"按钮. 把项目命名为"My First Unity Pro ...

  5. 在ASP.NET MVC下通过短信验证码注册

    以前发短信使用过短信猫,现在,更多地是使用第三方API.大致过程是: → 用户在页面输入手机号码→ 用户点击"获取验证码"按钮,把手机号码发送给服务端,服务端产生几位数的随机码,并 ...

  6. 测试RemObjects Pascal Script

    unit Unit1; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...

  7. HelloWorld 之JasperReports初步

    在企业应用系统中,经常要输出各种格式的数据报表. 著名的开源项目<JasperReports可以很好的解决这个问题. 使用JasperReports可以在预先设定好格式的报表基础上进行数据的填充 ...

  8. WordPress主题开发:WP_Query常用参数

    常用参数 用途 调用文章或页面 s 查询和某个关键词相关的所有的文章/页面信息 p 文章或页面id post__in 多篇id post__not_in 多篇id以外 post_type 查询的信息类 ...

  9. .NET:如何并行的从集合中返还元素?

    实现代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sys ...

  10. python测试开发django-22.admin首页和title修改

    前言 django的admin首页默认显示的"Django 管理",title显示的是"Django 站点管理员",这里的文案内容可以修改成自己项目的后台页面内 ...