|

楼主 |
发表于 2007-11-7 21:30:00
|
显示全部楼层
Re:欲做4d引擎。
instemast 4D engine (I4D) 使用简介
1.坐标
1.1 普通坐标
1.1.1 应用于3维空间的普通坐标
叫做3维普通坐标。表示为由3个元素(x,y,z)组成的向量。
3维普通坐标在i3dx.h中定义如下:
typedef union
{
struct{
float x,y,z;
};
struct{
float x1,x2,x3;
};
}I3DXVEC3;
1.1.2 应用于4维空间的普通坐标
叫做4维普通坐标。表示为由4个元素(x,y,z,w)组成的向量。
4维普通坐标在i4dx.h中定义如下:
typedef union
{
struct{
float x1,x2,x3,x4;
};
struct{
float x,y,z,u;
};
}I4DXVEC4;
1.2 齐次坐标
1.2.1 应用于3维空间的齐次坐标
在3维空间中,普通的坐标是我们熟知的3维坐标,比如,点A(x1,y1,z1).点B(x2,y2,z2)
在3维空间中,为了更好的变换,引进了4维齐次坐标。
一个4维齐次坐标,由4个数字组成,比如 点P(x,y,z, w )。
虽然有“4维”(或者说有4个元素),但是,它所表示的,却只不过是3维空间中的一个点。
反过来,一个3维空间的点,用齐次坐标表示,需要4个数。
3D引擎例如microsoft(r) Direct3D在绘制的时候,最终,要把4维齐次坐标转换成3维齐次坐标。
具体的转换方式很简单,如果点P的4维齐次坐标是(x,y,z,w),
那么,点P的3维普通坐标是(x/w, y/w, z/w).
反过来,把一个点的3维普通坐标转换成4维齐次坐标,由无数种结果,
一般把w设为1。比如点Q(x0,y0,z0),则4维齐次坐标为(x0,y0,z0,1)
4维齐次坐标类型(4个元素的向量)在i3dx.h中的定义是:
typedef union
{
struct{
float x,y,z,w;
};
struct{
float x1,x2,x3,x4;
};
}I3DXVEC4;
1.2.2 应用于4维空间的齐次坐标
在4维空间中,有4个方向,一个点的普通坐标,需要用4个数来表示,
比如,点M(x,y,z,u).这叫做4维普通坐标,表示4维空间的点。
习惯上用u来表示第4维。(u应该是ultra“超,超级”的首字母)
4维的点,类似地,也有齐次坐标。4维点的齐次坐标,显然,需要5个数字。
比如,点N(x,y,z,u, w ).那么,点N的普通坐标就是(x/w, y/w, z/w, u/w).
注意,请千万不要混淆4维齐次坐标和4维普通坐标!
4维齐次坐标表示3维空间的点。
4维普通坐标表示4维空间的点。
5维齐次坐标类型(5个元素的向量)在i4dx.h中的定义是:
typedef union
{
struct{
float x1,x2,x3,x4,x5;
};
struct{
float x,y,z,u,w;
};
}I4DXVEC5;
2.变换矩阵
2.1 应用于3维空间的变换矩阵
4d图形将被投影到3维空间进行观察,然后,为了观察3维世界,你需要设置3d变换。
引擎完成所有变换,需要使用4维齐次坐标和4x4的变换矩阵进行变换。
一般,你不必要使用齐次坐标,只需要使用3维普通坐标即可,引擎会帮你转换成4维齐次坐标进行变换。
在数学中,一般用矩阵左乘一个向量进行变换计算。
但注意,在microsoft(r) Direct3D中,使用矩阵又乘一个向量的进行变换计算。
而I4D引擎按照通常的数学习惯,使用矩阵左乘一个向量进行变换计算。
2.1.1 矩阵和矩阵运算
一个矩阵就是一个2维数组。它有m行n列。在数学中用大写字母表示。例如A。程序例如float mat[m][n];
矩阵的元素用小写字母表示,比如a ij(下标)。程序例如mat[i-1][j-1]=0;
(注意:数学中矩阵元素的编号是从1开始的,而c++的数组则从0开始)
一个n行n列矩阵叫做n阶方阵,简称方阵。
2.1.1.1 矩阵的转置
把矩阵的行和列交换,就得到了矩阵的转置。用写在右上角的T表示。例如:A T(上标)。
程序例如:
float A[m][n];
float A_T[n][m];
for(int i=0;i<=m-1;i++)
for(int j=0;j<=n-1;j++)
A_T[j] = A[j];
2.1.1.2 矩阵的乘法
矩阵的乘法用程序表达出来就是像这样的:
float A[m];
float B[n];
float C[m][n];
ZeroMemory(&C,m*n*sizeof(float));
for(int i=0;i<=m-1;i++)
for(int j=0;j<=n-1;j++)
for(int k=0;k<=s-1;k++)
C[j] = A[k] * B[k][j];
两个矩阵相乘,必须满足条件:第一个矩阵的列数等于第二个矩阵的行数。
所得的结果矩阵的行数等于第一个矩阵的行数,列数等于第二个矩阵的列数。
即,一个m*s矩阵和一个s*n矩阵才可以相乘,所的结果是一个m*n矩阵。
矩阵的乘法满足结合率。即(A*B)*C == A*(B*C)。
矩阵的乘法一般不满足交换率。即A*B != B*A。
所以,一般在说矩阵乘法的时候,需要说明方向,例如A*B读作:A左乘B,或B右乘A。
但是,矩阵的乘法,和矩阵的转置,有这样的性质:
(A * B)T == (B T * A T)
就是说,(A*B)的转置,等于B的转置左乘A的转置。
2.1.1.3 向量的矩阵表示
在矩阵代数里,一个N维向量,可以写成一列数字(构成一个N列1行的“列矩阵”或称“列向量”),
也可以写成一行数字(构成一个1行N列的“行矩阵”或称“行向量”)。
在线性代数中,默认的向量,就是列矩阵。但是在microsoft(r) Direct3D中,向量一律是行矩阵。
显然,一个列向量的转置,是行向量;一个行向量的转置,是列向量。
为了书写方便,列向量可以用行向量的转置来表示,例如:a = [x,y,z]T 。
数学中如用到行向量时,常用列向量(是默认的向量)的转制来表示,例如:b T ,表示行向量。
但是,在microsoft(r) Direct3D中,向量一律是行向量(行矩阵)。
2.1.1.4 矩阵和向量相乘
需要首先将向量用矩阵表示出来。即写成列矩阵或行矩阵的形式。
例如,列向量[x1,y1,z1,w1]T ("T"表示转置)。行向量[x2,y2,z2,w2]。
下面以4个元素的向量,和4x4矩阵为例进行说明:
4x4矩阵左乘4x1的列向量,得到的结果是一个4x1的列向量;
数学上利用矩阵乘法,对向量进行变换。
一般的数学标准是,把向量写成列矩阵的形式。然后使用一个n*n的矩阵左乘它。例如:b T = M * a。
这个n*n矩阵M,叫做“变换矩阵”。
根据1.1.1.2中的公式 (A * B)T == (B T * A T)。((A*B)的转置,等于B的转置左乘A的转置)。
可以得到:(M * a)T == (a T * M T),即,b T = (a T * M T)。
其中,
a T,也就是列向量a的转置,是一个行向量;
b T,也就是列向量b的转置,是一个行向量;
M T,是变换矩阵M的转置。
请注意!在microsoft(r) Direct3D中,参与变换的向量是行向量,
所以,它当中的变换矩阵,实际上是变换矩阵的转置。
即,microsoft(r) Direct3D是按照这个式子来进行变换的:b T = (a T * M T)。
通俗地说,microsoft(r) Direct3D中的诸如平移,旋转等变换矩阵,与通常数学书中的变换矩阵是行列颠倒的。
2.1.1.5 通过平移矩阵说明数学习惯和microsoft(r) Direct3D的区别
设有4个元素的向量a,b,和4x4矩阵M。并且b = M * a。那么也就是(矩阵乘法法则):
b1 = m11*a1 + m12*a2 + m13*a3 + m14*a4
b2 = m21*a1 + m22*a2 + m23*a3 + m24*a4
b3 = m31*a1 + m32*a2 + m33*a3 + m34*a4
b4 = m41*a1 + m42*a2 + m43*a3 + m44*a4
反过来,上面四个式子可以写成矩阵形式b = M * a
注意,在进行变换的时候,坐标是转换为齐次坐标的!
设你想要变换的向量a=(a1,a2,a3,1),结果向量为b=(b1,b2,b3,1)。
完成一个平移变换,(设位移为x,y,z)需要这样计算,
b1 = a1 + x
b2 = a2 + y
b3 = a3 + z
b4 = 1
可以这样写:
b1 = a1*1 + a2*0 + a3*0 + 1*x
b2 = a1*0 + a2*1 + a3*0 + 1*y
b3 = a1*0 + a2*0 + a3*1 + 1*z
b4 = a1*0 + a2*0 + a3*0 + 1*1
反过来写成矩阵就是 b = M * a,其中,
|1 0 0 x|
M=|0 1 0 y|
|0 0 1 z|
|0 0 0 1|
由于在microsoft(r) Direct3D中,向量是行矩阵,所以,也就是,b T = a T * M T,其中,
|1 0 0 0|
M T(M的转置)=|0 1 0 0|
|0 0 1 0|
|x y z 1|
这就是D3DXMatrixTranslation()函数计算出的平移变换矩阵。
但是,在I4D中,按照数学习惯,使用矩阵M,而不是M的转置。
2.1.2 应用于3维空间的变换矩阵类型
4x4变换矩阵在i3dx.h中的定义如下:
typedef union
{
struct{
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
};
float m[4][4];
}I3DXMAT44;
2.2 应用于4维空间的变换矩阵
4维的点的变换,需要使用齐次坐标和5x5矩阵来完成。
5x5矩阵在i4dx.h中定义如下:
typedef union
{
struct{
float _11, _12, _13, _14, _15;
float _21, _22, _23, _24, _25;
float _31, _32, _33, _34, _35;
float _41, _42, _43, _44, _45;
float _51, _52, _53, _54, _55;
};
float m[5][5];
}I4DXMAT55;
|
|