矩阵存储与运算

 1.问题

 矩阵在计算机图形学中有着重要的地位,刚开始学习时很容易被矩阵乘法的先后顺序所困扰,因为这里存在很多因素,比如什么是列矩阵和行矩阵,两种矩阵在做变换时会有什么差别?什么是列优先和行优先?矢量左乘矩阵和右乘矩阵是怎么定义的?

 2.列矩阵和行矩阵

 列矩阵(column major)和行矩阵(row major)是数学上的概念,和电脑无关,它只是一套约定(convention),按照矢量和矩阵的乘法运算时,矢量是列矢还是行矢命名,这里只说4x4矩阵。齐次矢量可以看成是一个1x4的矩阵,就是行矢;或者4x1的矩阵,就是列矢。

 列矩阵变换矢量时,用矩阵乘以列矢量(M * v),如下。其中1、2、3为三个轴向矢量。
 | x1 x2 x3 xt |   | x |
 | y1 y2 y3 yt | * | y |
 | z1 y2 y3 zt |   | z |
 | 0  0  0  1  |   | w |
 列矩阵之间乘法组合时,组合顺序为从右到左。例如依次做放缩S、旋转R、平移T,则组合为T * R * S。
 行矩阵变换矢量时,用行矢量乘以矩阵(v * M),如下。其中1、2、3为三个轴向矢量。
               | x1 y1 z1 0 |
 | x y z w | * | x2 y2 z2 0 |
               | x3 y3 z3 0 |
               | xt yt zt 1 |
 行矩阵之间乘法组合时,组合顺序为从左到右。例如依次做放缩S、旋转R、平移T,则组合为S * R * T。

3.列矩阵和行矩阵

   列优先存储(column major storage)和行优先存储(row major storage)是计算机上的概念,指多维数组的元素在内存中的排列顺序。
   对应到矩阵上,按内存地址顺序编号,则列优先存储的顺序为
  | 1  5  9  13 |
  | 2  6  10 14 |
  | 3  7  11 15 |
  | 4  8  12 16 |
  行优先存储的顺序为
  | 1  2  3  4  |
  | 5  6  7  8  |
  | 9  10 11 12 |
  | 13 14 15 16 |

  4.左乘和右乘  

  左乘(left multiplication, pre-multication)和右乘(right multiplication, post-multication),这里的左右、pre/post,指的是矢量和矩阵相乘时,矢量的位置。对标量和矩阵相乘时,指标量的位置。

  说简单点,左乘(又称前乘)就是乘在左边(即乘号前),右乘(又称后乘)就是乘在右边(即乘号后).
  比如说,A左乘E即AE

  5.Opengl和D3D中的矩阵

  Opengl采用的是列优先,D3D采用的是行优先。

   抛开不同底层实现的差异,我们在进行模型视图变换时,一般的顺序都是先缩放,然后旋转,最后进行平移,这样才能达到正确的变换效果。因此对于opengl,V`=T*R*S*V,但是对于D3D,V`=V*S*R*T。

  6.OSG中的矩阵

  osg的底层为opengl,但是在其矩阵实现时,是按照行矩阵来实现,矩阵的内部存储使用一个二维数组,这样在glLoadMatrix访问的刚好是osg的矩阵的的转置,可以这样理解这个区别:

  对于opengl,V`=M*V,根据矩阵运算法则:V`转置 = V转置 * M转置,矢量的转置不影响我们的使用,这样我们可以在osg中把矩阵当成行矩阵对待,因此在变换顺序上为S * R * T,这样也更符合从左到右的习惯。

时间: 2024-10-15 16:59:29

矩阵存储与运算的相关文章

各语言系统或编程接口中向量与矩阵存储的差异

*********文中用到的transpose()代表矩阵转置函数,mul()代表矩阵乘法. 本文试图解释DX,HLSL,CG,OpengGL,GLSL中关于矩阵运算及存储的一些模糊概念. 0,先弄清楚,用矩阵来变换行/列向量时,怎样的矩阵才是预期的. 假设有行向量p,列向量q,一个给定的[非对称矩阵]A可以用来变换p可以表示为mul(p,A)(这叫post-multiply),也可以用来变换q,表示为mul(A,q)(这叫pre-multiply). 但A通常只能代表一个预期的变换(比如旋转平

1.2 eigen中矩阵和向量的运算

1.2 矩阵和向量的运算 1.介绍 eigen给矩阵和向量的算术运算提供重载的c++算术运算符例如+,-,*或这一些点乘dot(),叉乘cross()等等.对于矩阵类(矩阵和向量,之后统称为矩阵类),算术运算只重载线性代数的运算.例如matrix1*matrix2表示矩阵的乘法,同时向量+标量是不允许的!如果你想进行所有的数组算术运算,请看下一节! 2.加减法 因为eigen库无法自动进行类型转换,因此矩阵类的加减法必须是两个同类型同维度的矩阵类相加减. 这些运算有: 双目运算符:+,a+b 双

计算密集型分布式内存存储和运算平台架构

避嫌声明:所有图文都是根据自己的理解原创,且已离开这家公司三年以上,不存在保密协议,写此文只是用来分享知识.探究不足. 牢骚:本来想弄个ppt交互展示的,不过我的js权限还没批... 1. 相关概念 1.1 内存数据库 关系型数据库处理永久.稳定的数据,内存数据库就是将其数据放在内存中,活动事务只与内存数据打交道,重新设计了体系结构并且在数据缓存.快速算法.并行操作方面也进行了相应的改进,所以数据处理速度比磁盘数据库要快很多,一般都在10倍以上.但它不容易恢复,可能暂时不一致或非绝对正确的,要求

整数在计算中的存储和运算

整数的第一位表示符号位. 1 正整数 正整数在计算机中直接用它的二进制存储,例如: short s = 3; 3 = 2^1 + 2^0 短整型一般为2个字节,即16位,它的对应的存储方式为: 0 000 0011 所以,短整型的表示范围为:-2^15  ~ +2^15 0是个特例,它有两种表示方式: 1 000 0000 0 000 0000 所以,短整型一共只有2^16 - 1 个数. 再看整型,整型的存储为4个字节,32位 int i = 7; 7 = 2^2 + 2^1 + 2^0 即:

对矩阵进行转置运算

package lianxi; public class juzhen { public static void main(String[] args) { // TODO 自动生成的方法存根 int arr[][]=new int[][]{{1,2,3},{4,5,6},{7,8,9}}; //创建二维数组 System.out.println("转置前的的矩阵是:"); printArray(arr); //输出二维数组 int arr2[][]=new int[arr.lengt

4.7矩阵的转置运算

#include<iostream> #include<cstdio> using namespace std; void InputMatrix(int (*a)[4],int n,int m) { for(int i=0;i<n;i++) for(int j=0;j<m;j++) printf("%d",*(a+i)+j); } void OutputMatrix(int (*b)[4],int n,int m) { for(int i=0;i&

各种图的创建以及广度,深度优先遍历(临接矩阵存储)

#include <stdio.h> #include <iostream> #include <limits.h> #include <queue> #define INFINTY INT_MAX //最大值 #define MaxVertexNum 100 //最大顶点数 using namespace std; typedef enum{DG,UDG,DN,UDN} GraphKind; //图的种类(有向图.无向图,又向网,无向网) typedef

Matlab矩阵基本操作(定义,运算)

转自:http://blog.csdn.net/perfumekristy/article/details/8119861 一.矩阵的表示在MATLAB中创建矩阵有以下规则: a.矩阵元素必须在”[ ]”内: b.矩阵的同行元素之间用空格(或”,”)隔开: c.矩阵的行与行之间用”;”(或回车符)隔开: d.矩阵的元素可以是数值.变量.表达式或函数: e.矩阵的尺寸不必预先定义. 二,矩阵的创建: 1.直接输入法 最简单的建立矩阵的方法是从键盘直接输入矩阵的元素,输入的方法按照上面的规则.建立向

C++ 开源矩阵 运算工具——Eigen

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 这几天,一直忙着帮学院一个老师做一个软件的功能模块, 模块要求是 矩阵的一系列运算, 本来是要自己写的,后来,发现有现成的工具,很多,我最后选择了Eigen, 因为它方便啊~  只需要把文件夹放到include文件夹下,就可以用了,打包什么也方便. 而且,跟别的