向量可以用来表示力,位移,速度等等物理量。此外,还可以用向量来表示方向,例如3d物体的朝向,射线射向的方向等等。向量有这样的特点,判断两个向量相等的条件是大小和方向相等,与位置无关。如u向量和v向量便是相等向量。
三条两两垂直的坐标轴,提供一个基准点,将向量起点都移动到原点处便于各种计算。在DirectX3D中使用的是左手坐标系,左手坐标系判断方法可以通过左手四指从x轴旋向y轴,这时候大拇指指向的方向就是z轴方向。
向量支持加减,展缩和复制运算。如:
u+v=(1,3,5)+(2,4,6)=(3,7,11)
u-v=(1,3,5)-(2,4,6)=(-1,-1,-1)
2u=2(1,3,5)=(2,6,10)
u=v
标准化后的向量长度为1,如果只关心向量的方向,某些应用下可以使用标准化向量。
向量 u=(x,y,z)
向量的模 |u|=(x^2+y^2+z^2)^(1/2)
标准化向量 v=u*(1/|u|)=(x/|u|,y/|u|,z/|u|)
u=(x,y,z) v=(i,j,k)
u·v=x*i+y*j+z*k=|u|*|v|*cosα(α为为两个向量之间的夹角)
将一组向量通过运算使得组内任一个向量与其他向量垂直,然后对组内的向量进行标准化。
u=(ux,uy,uz) v=(vx,vy,vz)
w=u ×v=(uy*vz-uz*vy,uz*vx-ux*vz,ux*vy-uy*vx)
用左手法则可以判断w向量的方向,即左手四指从u的方向绕向v的方向,拇指指向的方向即是w向量的方向。如果w1=v×u,w1方向与w方向相反。
1、在DirectX11使用的XNA数学库来进行数学运算。XNA中利用了硬件中的特殊寄存器,在Windows操作系统下,使用SSE2指令集可以用更少的指令完成运算,如执行四维向量的加法只要一条SIMD指令即可完成。
在XNA数学库中,向量的类型是XMVECTOR,如果支持SSE2,它是这么定义的
typedef __m128 XMVECTOR
XMVECTOR需要占用128位,全局变量和局部变量使用XMVECTOR类型,建议用XMFLOAT2 、XMFLOAT3、 XMFLOAT4代替XMVECTOR 声明类的成员变量,但是如果直接用它们来计算就不能用到SIMD,如果要用SIMD就要使用loading函数转换类型XMFLOAT*到XMVECTOR,计算完成后,再用storage函数转换回XMFLOAT *。
2、为了更好地利用SIMD,在传递参数的时候,有些需要遵守的规则。这些规则根据平台的不同而不同。在传入XMVECTOR参数时,前三个XMVECTOR的类型是FXMVECTOR,其余的参数类型是CXMVECTOR。
3、常向量应该是XMVECTORF32类型的。常量数据是整数类型时使用XMVECTORU32。
4、XMVECTOR对加法,减法,展缩运算进行了操作符重载。可以通过XM_NO_OPERATOR_OVERLOADS定义来关闭操作符重载,这样可以提高性能,原因是函数操作在复杂的表达式中运行效率更高。
测试代码: //xnamath.h已经改成DirectXMath.h #include <iostream> #include <windows.h> #include <DirectXMath.h> using namespace std; using namespace DirectX; //操作符重载 ostream& operator<<(ostream& os, FXMVECTOR v) { XMFLOAT3 dest; XMStoreFloat3(&dest, v); os << "(" << dest.x << "," << dest.y << "," << dest.z << ")"; return os; } int main() { cout.setf(ios_base::boolalpha); if (!XMVerifyCPUSupport()) { cout << "不支持xna math" << endl; return 0; } XMVECTOR p = XMVectorZero(); XMVECTOR q = XMVectorSplatOne(); XMVECTOR u = XMVectorSet(1.0f, 2.0, 3.0f,0.0f); XMVECTOR v = XMVectorReplicate(-2.0f); XMVECTOR w = XMVectorSplatZ(u); cout << "p=" << p << endl; cout << "q=" << q << endl; cout << "u=" << u << endl; cout << "v=" << v << endl; cout << "w=" << w << endl; return 0; }