空间平面方程 java,D3D编程必备的数学知识(5)

a24e1656d2c86abca51637ee7aa32639.png

在代码中描述一个平面:仅仅需要一个法向量n和常数d就可以了。因此我们就使用一个4D向量(我们记录成(n, d))来实现它。D3DX库中用如下的结构来定义一个平面:

typedef struct D3DXPLANE

{

#ifdef __cplusplus

public:

D3DXPLANE() {}

D3DXPLANE( CONST FLOAT* );

D3DXPLANE( CONST D3DXFLOAT16* );

D3DXPLANE( FLOAT a, FLOAT b, FLOAT c, FLOAT d );

// casting

operator FLOAT* ();

operator CONST FLOAT* () const;

// unary operators

D3DXPLANE operator + () const;

D3DXPLANE operator - () const;

// binary operators

BOOL operator == ( CONST D3DXPLANE& ) const;

BOOL operator != ( CONST D3DXPLANE& ) const;

#endif //__cplusplus

FLOAT a, b, c, d;

} D3DXPLANE, *LPD3DXPLANE;

对照等式(8)可知:这里a, b和c是平面法向量n的成员,d就是那个常数。

我们判定点和平面的关系主要是利用等式(8)来实现。例如,假设平面(n, d),我们能判定点p和平面的关系:

假如n·p+ d= 0,那么点p与平面共面。

假如n·p+ d>0,那么点p在平面的前面且在平面的正半空间里。

假如n·p+ d<0,那么点p在平面的背面且在平面的负半空间里。

下边的D3DX函数就是利用n·p+ d来判定点和平面的关系的函数:

FLOAT D3DXPlaneDotCoord(

CONST D3DXPLANE *pP, // 平面

CONST D3DXVECTOR3 *pV // 点

);

// 测试点相对于平面的位置

D3DXPLANE p(0.0f, 1.0f, 0.0f, 0.0f);

D3DXVECTOR3 v(3.0f, 5.0f, 2.0f);

float x = D3DXPlaneDotCoord( &p, &v );

if( x approximately equals 0.0f ) // v在平面.上

if( x > 0 ) // v在正半空间

if( x < 0 ) // v在负半空间

我们能通过两种方法创建平面。

第一种方法,直接用指定法线和点创建平面。假设法线n和在平面上的已知点p0,我们就能求出d:

n·p0+ d = 0

n·p0 = -d

-n·p0 = d

D3DX库提供如下函数来完成创建平面的任务:

D3DXPLANE *D3DXPlaneFromPointNormal(

D3DXPLANE* pOut, // Result.

CONST D3DXVECTOR3* pPoint, // Point on the plane.

CONST D3DXVECTOR3* pNormal // The normal of the plane.

);

第二种方法,我们能通过在平面上的3个点创立一个平面。

假如有点p0, p1, p2,那么我们就能得到平面上的两个向量:

u = p1 - p0

v = p2 - p0

因此我们能通过把平面上的两个向量进行叉乘得到平面的法线。回忆左手坐标系。

n = u × v

Then, -(n · p0) = d.

D3DX库提供如下函数来完成通过同一平面上的3个点确定一个平面:

D3DXPLANE *D3DXPlaneFromPoints(

D3DXPLANE* pOut, // Result.

CONST D3DXVECTOR3* pV1, // Point 1 on the plane.

CONST D3DXVECTOR3* pV2, // Point 2 on the plane.

CONST D3DXVECTOR3* pV3 // Point 3 on the plane.

);

398aa7c816e85b49c804a5c04509a547.png

我们能够通过如下处理来变换一个面(n, d),就象一个4D向量通过乘以它所期望的变换矩阵的逆矩阵一样来达到变换目的。注意平面的法向量必须首先被标准化。

我们能用下面的D3DX函数来完成操作:

D3DXPLANE *D3DXPlaneTransform(

D3DXPLANE *pOut, // Result

CONST D3DXPLANE *pP, // Input plane.

CONST D3DXMATRIX *pM // Transformation matrix.

);

示例代码:

D3DXMATRIX T(...); // Init. T to a desired transformation.

D3DXMATRIX inverseOfT;

D3DXMATRIX inverseTransposeOfT;

D3DXMatrixInverse( &inverseOfT, 0, &T );

D3DXMatrixTranspose( &inverseTransposeOfT, &inverseOfT );

D3DXPLANE p(...); // Init. Plane.

D3DXPlaneNormalize( &p, &p ); // make sure normal is normalized.

D3DXPlaneTransform( &p, &p, &inverseTransposeOfT );

d837aafa74e6794b25b7b46beb7567e0.png

设想在游戏中的一个玩家,正用他的枪射击敌人。我们怎么判断子弹是否从一个位置击中另一个位置的目标?一个方法是用一条射线模拟子弹,用一个球体模型模拟敌人。(球体模型只是一个球体,它紧紧的围绕一个物体,从而粗略地表示它的大小。球体模型将在第11章中做更详细的介绍。)那么通过计算我们就能够判定是否射中球体。在这部分我们学习射线的数学模型。

一条射线能用一个起点和方向来描述。射线的参数方程是:

ca6fbab65749a3098b3edcedcd7b0b20.png

假设一条射线p(t) = p0 + tu和 一个平面n·p+ d= 0,我们想知道射线是否与平面相交,以及相交的交点信息(如果相交的话)。照这样做,我们把射线代入平面方程并且求满足平面方程的参数t,解答出来的参数就是相交的点。

把等式(9)代入平面方程:

98b53e8c058e43cc6325e427cbc51d37.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值