DirectX 9的一些数学计算函数:向量篇
首先来看看向量,向量的坐标表示对于DirectX游戏开发来说是必须的,在世界坐标系或投影坐标系下的三角形面的法线,光线的方向和观察者的方向等都是通过向量的坐标形式来准确给出的。
DirectX的头文件D3DX9Math.h给出了两个结构体来支持向量的计算:
以下整理出DirextX 9的一些向量函数,由于本人也只是初学DirectX 9,所以文章中可能蕴含着一些错误,也可能不完整,敬请指出,以后会陆续补充。
要正确运行以下的示例程序,需要在工程中包含d3dx9.lib,或者在main函数前加入
#pragma comment(lib, "d3dx9.lib")
以指示编译器链接d3dx9.lib。
向量相加: 重载的运算符 +
向量相减: 重载的运算符-
函数原型:
D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const;
D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const;
代码示例:
输出:
C2 = (6.00, 3.00) + (4.00, 2.00) = (10.00, 5.00)
C3 = (5.00, 2.60, 10.00) + (2.00, 3.40, 3.00) = (7.00, 6.00, 13.00)
D3 = (5.00, 2.60, 10.00) - (2.00, 3.40, 3.00) = (3.00, -0.80, 7.00)
向量的标量乘法: 重载的运算符 *
函数原型:
friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& );
代码示例:
输出:
B = 5.00 * (6.00, 3.00) = (30.00, 15.00)
D = 5.00 * (1.00, 2.00, 3.00) = (5.00, 10.00, 15.00)
向量长度的计算: D3DXVec3Length
函数原型:
FLOAT D3DXVec3Length ( CONST D3DXVECTOR3 *pV );
代码示例:
输出:
vector A(3.00, 5.00) length = 5.830952
vector B(23.00, 3.80, -12.30) length = 26.357731
向量的单位化: D3DXVec2Normalize, D3DXVec3Normalize
函数原型:
D3DXVECTOR2* WINAPI D3DXVec2Normalize( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV );
D3DXVECTOR3* WINAPI D3DXVec3Normalize( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV );
代码示例:
输出:
vector A(3.00, 6.00) normal = (0.447214, 0.894427)
vector B(2.50, 10.00, 8.00) normal = (0.191600, 0.766402, 0.613121)
向量的点积: D3DXVec3Dot
函数原型:
FLOAT D3DXVec3Dot ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 );
代码示例:
输出:
The angle between u and v is < 90
向量的叉积:D3DXVec3Cross
函数原型:
D3DXVECTOR3* D3DXVec3Cross
( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 );
代码示例:
输出:
ixj = (0.000000, 0.000000, 1.000000)
jxk = (1.000000, 0.000000, 0.000000)
kxi = (0.000000, 1.000000, 0.000000)
DirectX的头文件D3DX9Math.h给出了两个结构体来支持向量的计算:
typedef
struct
_D3DVECTOR {
float x;
float y;
float z;
} D3DVECTOR;
typedef struct D3DXVECTOR3 : public D3DVECTOR
{
public :
D3DXVECTOR3() {};
D3DXVECTOR3( CONST FLOAT * );
D3DXVECTOR3( CONST D3DVECTOR & );
D3DXVECTOR3( CONST D3DXFLOAT16 * );
D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z );
// casting
operator FLOAT * ();
operator CONST FLOAT * () const ;
// assignment operators
D3DXVECTOR3 & operator += ( CONST D3DXVECTOR3 & );
D3DXVECTOR3 & operator -= ( CONST D3DXVECTOR3 & );
D3DXVECTOR3 & operator *= ( FLOAT );
D3DXVECTOR3 & operator /= ( FLOAT );
// unary operators
D3DXVECTOR3 operator + () const ;
D3DXVECTOR3 operator - () const ;
// binary operators
D3DXVECTOR3 operator + ( CONST D3DXVECTOR3 & ) const ;
D3DXVECTOR3 operator - ( CONST D3DXVECTOR3 & ) const ;
D3DXVECTOR3 operator * ( FLOAT ) const ;
D3DXVECTOR3 operator / ( FLOAT ) const ;
friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3 & );
BOOL operator == ( CONST D3DXVECTOR3 & ) const ;
BOOL operator != ( CONST D3DXVECTOR3 & ) const ;
} D3DXVECTOR3, * LPD3DXVECTOR3;
float x;
float y;
float z;
} D3DVECTOR;
typedef struct D3DXVECTOR3 : public D3DVECTOR
{
public :
D3DXVECTOR3() {};
D3DXVECTOR3( CONST FLOAT * );
D3DXVECTOR3( CONST D3DVECTOR & );
D3DXVECTOR3( CONST D3DXFLOAT16 * );
D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z );
// casting
operator FLOAT * ();
operator CONST FLOAT * () const ;
// assignment operators
D3DXVECTOR3 & operator += ( CONST D3DXVECTOR3 & );
D3DXVECTOR3 & operator -= ( CONST D3DXVECTOR3 & );
D3DXVECTOR3 & operator *= ( FLOAT );
D3DXVECTOR3 & operator /= ( FLOAT );
// unary operators
D3DXVECTOR3 operator + () const ;
D3DXVECTOR3 operator - () const ;
// binary operators
D3DXVECTOR3 operator + ( CONST D3DXVECTOR3 & ) const ;
D3DXVECTOR3 operator - ( CONST D3DXVECTOR3 & ) const ;
D3DXVECTOR3 operator * ( FLOAT ) const ;
D3DXVECTOR3 operator / ( FLOAT ) const ;
friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3 & );
BOOL operator == ( CONST D3DXVECTOR3 & ) const ;
BOOL operator != ( CONST D3DXVECTOR3 & ) const ;
} D3DXVECTOR3, * LPD3DXVECTOR3;
以下整理出DirextX 9的一些向量函数,由于本人也只是初学DirectX 9,所以文章中可能蕴含着一些错误,也可能不完整,敬请指出,以后会陆续补充。
要正确运行以下的示例程序,需要在工程中包含d3dx9.lib,或者在main函数前加入
#pragma comment(lib, "d3dx9.lib")
以指示编译器链接d3dx9.lib。
向量相加: 重载的运算符 +
向量相减: 重载的运算符-
函数原型:
D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const;
D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const;
代码示例:
#include
<
stdio.h
>
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
// calculate for 2 dimension vector
D3DXVECTOR2 A2( 6.0 , 3.0 );
D3DXVECTOR2 B2( 4.0 , 2.0 );
D3DXVECTOR2 C2 = A2 + B2;
printf( " \nC2 = (%.2f, %.2f) + (%.2f, %.2f) = (%.2f, %.2f)\n " , A2.x, A2.y, B2.x, B2.y, C2.x, C2.y);
// calculate for 3 dimension vector
D3DXVECTOR3 A3( 5.0 , 2.6 , 10 );
D3DXVECTOR3 B3( 2.0 , 3.4 , 3.0 );
D3DXVECTOR3 C3 = A3 + B3;
printf( " \nC3 = (%.2f, %.2f, %.2f) + (%.2f, %.2f, %.2f) = (%.2f, %.2f, %.2f)\n " ,
A3.x, A3.y, A3.z, B3.x, B3.y, B3.z, C3.x, C3.y, C3.z);
D3DXVECTOR3 D3 = A3 - B3;
printf( " \nD3 = (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) = (%.2f, %.2f, %.2f)\n " ,
A3.x, A3.y, A3.z, B3.x, B3.y, B3.z, D3.x, D3.y, D3.z);
return 0 ;
}
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
// calculate for 2 dimension vector
D3DXVECTOR2 A2( 6.0 , 3.0 );
D3DXVECTOR2 B2( 4.0 , 2.0 );
D3DXVECTOR2 C2 = A2 + B2;
printf( " \nC2 = (%.2f, %.2f) + (%.2f, %.2f) = (%.2f, %.2f)\n " , A2.x, A2.y, B2.x, B2.y, C2.x, C2.y);
// calculate for 3 dimension vector
D3DXVECTOR3 A3( 5.0 , 2.6 , 10 );
D3DXVECTOR3 B3( 2.0 , 3.4 , 3.0 );
D3DXVECTOR3 C3 = A3 + B3;
printf( " \nC3 = (%.2f, %.2f, %.2f) + (%.2f, %.2f, %.2f) = (%.2f, %.2f, %.2f)\n " ,
A3.x, A3.y, A3.z, B3.x, B3.y, B3.z, C3.x, C3.y, C3.z);
D3DXVECTOR3 D3 = A3 - B3;
printf( " \nD3 = (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) = (%.2f, %.2f, %.2f)\n " ,
A3.x, A3.y, A3.z, B3.x, B3.y, B3.z, D3.x, D3.y, D3.z);
return 0 ;
}
输出:
C2 = (6.00, 3.00) + (4.00, 2.00) = (10.00, 5.00)
C3 = (5.00, 2.60, 10.00) + (2.00, 3.40, 3.00) = (7.00, 6.00, 13.00)
D3 = (5.00, 2.60, 10.00) - (2.00, 3.40, 3.00) = (3.00, -0.80, 7.00)
向量的标量乘法: 重载的运算符 *
函数原型:
friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& );
代码示例:
#include
<
stdio.h
>
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
// calculate for 2 dimension multiply
D3DXVECTOR2 A( 6.0 , 3.0 );
float m = 5.0 ;
D3DXVECTOR2 B = m * A;
printf( " \nB = %.2f * (%.2f, %.2f) = (%.2f, %.2f)\n " , m, A.x, A.y, B.x, B.y);
// calculate for 3 dimension multiply
D3DXVECTOR3 C( 1.0 , 2.0 , 3.0 );
D3DXVECTOR3 D = m * C;
printf( " \nD = %.2f * (%.2f, %.2f, %.2f) = (%.2f, %.2f, %.2f)\n\n " ,
m, C.x, C.y, C.z, D.x, D.y, D.z);
return 0 ;
}
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
// calculate for 2 dimension multiply
D3DXVECTOR2 A( 6.0 , 3.0 );
float m = 5.0 ;
D3DXVECTOR2 B = m * A;
printf( " \nB = %.2f * (%.2f, %.2f) = (%.2f, %.2f)\n " , m, A.x, A.y, B.x, B.y);
// calculate for 3 dimension multiply
D3DXVECTOR3 C( 1.0 , 2.0 , 3.0 );
D3DXVECTOR3 D = m * C;
printf( " \nD = %.2f * (%.2f, %.2f, %.2f) = (%.2f, %.2f, %.2f)\n\n " ,
m, C.x, C.y, C.z, D.x, D.y, D.z);
return 0 ;
}
输出:
B = 5.00 * (6.00, 3.00) = (30.00, 15.00)
D = 5.00 * (1.00, 2.00, 3.00) = (5.00, 10.00, 15.00)
向量长度的计算: D3DXVec3Length
函数原型:
FLOAT D3DXVec3Length ( CONST D3DXVECTOR3 *pV );
代码示例:
#include
<
stdio.h
>
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
// calculate vector length for 2 dimension
D3DXVECTOR2 A( 3.0 , 5.0 );
float A_len = D3DXVec2Length( & A);
printf( " \nvector A(%.2f, %.2f) length = %f\n " , A.x, A.y, A_len);
// calculate vector length for 3 dimension
D3DXVECTOR3 B( 23.0 , 3.8 , - 12.3 );
float B_len = D3DXVec3Length( & B);
printf( " \nvector B(%.2f, %.2f, %.2f) length = %f\n " , B.x, B.y, B.z, B_len);
return 0 ;
}
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
// calculate vector length for 2 dimension
D3DXVECTOR2 A( 3.0 , 5.0 );
float A_len = D3DXVec2Length( & A);
printf( " \nvector A(%.2f, %.2f) length = %f\n " , A.x, A.y, A_len);
// calculate vector length for 3 dimension
D3DXVECTOR3 B( 23.0 , 3.8 , - 12.3 );
float B_len = D3DXVec3Length( & B);
printf( " \nvector B(%.2f, %.2f, %.2f) length = %f\n " , B.x, B.y, B.z, B_len);
return 0 ;
}
输出:
vector A(3.00, 5.00) length = 5.830952
vector B(23.00, 3.80, -12.30) length = 26.357731
向量的单位化: D3DXVec2Normalize, D3DXVec3Normalize
函数原型:
D3DXVECTOR2* WINAPI D3DXVec2Normalize( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV );
D3DXVECTOR3* WINAPI D3DXVec3Normalize( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV );
代码示例:
#include
<
stdio.h
>
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
// vector normalize for 2D dimension
D3DXVECTOR2 A( 3.0 , 6.0 );
D3DXVECTOR2 A_normal;
D3DXVec2Normalize( & A_normal, & A);
printf( " vector A(%.2f, %.2f) normal = (%f, %f)\n\n " , A.x, A.y, A_normal.x, A_normal.y);
// vector normalize for 3D dimension
D3DXVECTOR3 B( 2.5 , 10.0 , 8.0 );
D3DXVECTOR3 B_normal;
D3DXVec3Normalize( & B_normal, & B);
printf( " vector B(%.2f, %.2f, %.2f) normal = (%f, %f, %f)\n\n " , B.x, B.y, B.z, B_normal.x, B_normal.y, B_normal.z);
return 0 ;
}
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
// vector normalize for 2D dimension
D3DXVECTOR2 A( 3.0 , 6.0 );
D3DXVECTOR2 A_normal;
D3DXVec2Normalize( & A_normal, & A);
printf( " vector A(%.2f, %.2f) normal = (%f, %f)\n\n " , A.x, A.y, A_normal.x, A_normal.y);
// vector normalize for 3D dimension
D3DXVECTOR3 B( 2.5 , 10.0 , 8.0 );
D3DXVECTOR3 B_normal;
D3DXVec3Normalize( & B_normal, & B);
printf( " vector B(%.2f, %.2f, %.2f) normal = (%f, %f, %f)\n\n " , B.x, B.y, B.z, B_normal.x, B_normal.y, B_normal.z);
return 0 ;
}
输出:
vector A(3.00, 6.00) normal = (0.447214, 0.894427)
vector B(2.50, 10.00, 8.00) normal = (0.191600, 0.766402, 0.613121)
向量的点积: D3DXVec3Dot
函数原型:
FLOAT D3DXVec3Dot ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 );
代码示例:
#include
<
stdio.h
>
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
D3DXVECTOR3 u( 2.0 , 3.0 , 4.0 );
D3DXVECTOR3 v( 11.0 , 5.0 , 7.0 );
float dot_value = D3DXVec3Dot( & u, & v);
if (dot_value < 0 )
printf( " The angle between u and v is > 90 " );
else if (dot_value == 0 )
printf( " The angle between u and v is = 90 " );
else
printf( " The angle between u and v is < 90 " );
printf( " \n\n " );
return 0 ;
}
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
D3DXVECTOR3 u( 2.0 , 3.0 , 4.0 );
D3DXVECTOR3 v( 11.0 , 5.0 , 7.0 );
float dot_value = D3DXVec3Dot( & u, & v);
if (dot_value < 0 )
printf( " The angle between u and v is > 90 " );
else if (dot_value == 0 )
printf( " The angle between u and v is = 90 " );
else
printf( " The angle between u and v is < 90 " );
printf( " \n\n " );
return 0 ;
}
输出:
The angle between u and v is < 90
向量的叉积:D3DXVec3Cross
函数原型:
D3DXVECTOR3* D3DXVec3Cross
( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 );
代码示例:
#include
<
stdio.h
>
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
D3DXVECTOR3 i( 1.0 , 0.0 , 0.0 );
D3DXVECTOR3 j( 0.0 , 1.0 , 0.0 );
D3DXVECTOR3 k( 0.0 , 0.0 , 1.0 );
D3DXVECTOR3 cross_vector;
D3DXVec3Cross( & cross_vector, & i, & j);
printf( " ixj = (%f, %f, %f)\n\n " , cross_vector.x, cross_vector.y, cross_vector.z);
D3DXVec3Cross( & cross_vector, & j, & k);
printf( " jxk = (%f, %f, %f)\n\n " , cross_vector.x, cross_vector.y, cross_vector.z);
D3DXVec3Cross( & cross_vector, & k, & i);
printf( " kxi = (%f, %f, %f)\n\n " , cross_vector.x, cross_vector.y, cross_vector.z);
return 0 ;
}
#include < D3DX9Math.h >
#pragma warning(disable : 4305 )
int main()
{
D3DXVECTOR3 i( 1.0 , 0.0 , 0.0 );
D3DXVECTOR3 j( 0.0 , 1.0 , 0.0 );
D3DXVECTOR3 k( 0.0 , 0.0 , 1.0 );
D3DXVECTOR3 cross_vector;
D3DXVec3Cross( & cross_vector, & i, & j);
printf( " ixj = (%f, %f, %f)\n\n " , cross_vector.x, cross_vector.y, cross_vector.z);
D3DXVec3Cross( & cross_vector, & j, & k);
printf( " jxk = (%f, %f, %f)\n\n " , cross_vector.x, cross_vector.y, cross_vector.z);
D3DXVec3Cross( & cross_vector, & k, & i);
printf( " kxi = (%f, %f, %f)\n\n " , cross_vector.x, cross_vector.y, cross_vector.z);
return 0 ;
}
输出:
ixj = (0.000000, 0.000000, 1.000000)
jxk = (1.000000, 0.000000, 0.000000)
kxi = (0.000000, 1.000000, 0.000000)