天行健 君子当自强而不息

DirectX 9的一些数学计算函数:平面


平面

将三维物体表面剖分为一系列的三角形面,物体的光照亮度处理就转化为对这些平面三角形的照明处理,从而可简单地通过平面三角形的法向量与光的入射方向的夹角,来确定各种入射光对平面上每一点所贡献的亮度值。

对于三角形3个顶点p0,p1,p2构成的平面,选取一个垂直于该平面的法向量n。假设点p为平面上的任意一点,由于n . (p - p0) = 0,从而n . p - n . p0 = 0,由此展开向量的点积运算可知,平面方程具有如下的一般形式:ax+by+cz+d=0。如果要具体求出平面的方程,可取n=(p1-p0) x (p2 - p0)计算出来。

因为平面的方程式由4个系数a, b, c, d就可确定,因此,DirectX提供了如下的D3DXPLANE结构体保存方程式的4个系数,当然结构体还提供了基于方程式系数的加减乘除等运算。
 
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;

    
// assignment operators
    D3DXPLANE& operator *= ( FLOAT );
    D3DXPLANE& 
operator /= ( FLOAT );

    
// unary operators
    D3DXPLANE operator + () const;
    D3DXPLANE 
operator - () const;

    
// binary operators
    D3DXPLANE operator * ( FLOAT ) const;
    D3DXPLANE 
operator / ( FLOAT ) const;

    friend D3DXPLANE 
operator * ( FLOAT, CONST D3DXPLANE& );

    BOOL 
operator == ( CONST D3DXPLANE& ) const;
    BOOL 
operator != ( CONST D3DXPLANE& ) const;

#endif //__cplusplus
    FLOAT a, b, c, d;
} D3DXPLANE, *LPD3DXPLANE;

DirectX还提供了基于三点的向量求平面的 D3DXPlaneFromPoints函数以及基于一点和一个法向量求平面的D3DXPlaneFromPointNormal函数。

Constructs a plane from three points.

D3DXPLANE * D3DXPlaneFromPoints(
D3DXPLANE * pOut,
CONST D3DXVECTOR3 * pV1,
CONST D3DXVECTOR3 * pV2,
CONST D3DXVECTOR3 * pV3
);

Parameters

pOut
[in, out] Pointer to the D3DXPLANE structure that is the result of the operation.
pV1
[in] Pointer to a D3DXVECTOR3 structure, defining one of the points used to construct the plane.
pV2
[in] Pointer to a D3DXVECTOR3 structure, defining one of the points used to construct the plane.
pV3
[in] Pointer to a D3DXVECTOR3 structure, defining one of the points used to construct the plane.

Return Values

Pointer to the D3DXPLANE structure constructed from the given points.

Remarks

The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXPlaneFromPoints function can be used as a parameter for another function.

 

Constructs a plane from a point and a normal.

D3DXPLANE * D3DXPlaneFromPointNormal(
D3DXPLANE * pOut,
CONST D3DXVECTOR3 * pPoint,
CONST D3DXVECTOR3 * pNormal
);

Parameters

pOut
[in, out] Pointer to the D3DXPLANE structure that is the result of the operation.
pPoint
[in] Pointer to a D3DXVECTOR3 structure, defining the point used to construct the plane.
pNormal
[in] Pointer to a D3DXVECTOR3 structure, defining the normal used to construct the plane.

Return Values

Pointer to the D3DXPLANE structure constructed from the point and the normal.

Remarks

The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXPlaneFromPointNormal function can be used as a parameter for another function.


要正确运行以下的示例程序,需要在工程中包含d3dx9.lib,或者在main函数前加入

#pragma comment(lib, "d3dx9.lib")

以指示编译器链接d3dx9.lib。

代码示例:

#include <stdio.h>
#include <D3DX9Math.h>

#pragma warning(disable : 4305)

int main()
{
    D3DXVECTOR3 P0(8.0,  -3.0, 6.0);
    D3DXVECTOR3 P1(2.0,  -3.0, -5.0);
    D3DXVECTOR3 P2(-1.0, -3.0, 10.0);

    D3DXPLANE plane;

    D3DXPlaneFromPoints(&plane, &P0, &P1, &P2);

    printf("Plane equation: %fx + %fy + %fz + %f = 0", plane.a, plane.b, plane.c, plane.d);
    printf("\n\n\n");

    
return 0;
}

结果输出:

Plane equation: 0.000000x + 1.000000y + 0.000000z + 3.000000 = 0



直线与平面的交点

Finds the intersection between a plane and a line.

D3DXVECTOR3 * D3DXPlaneIntersectLine(
D3DXVECTOR3 * pOut,
CONST D3DXPLANE * pP,
CONST D3DXVECTOR3 * pV1,
CONST D3DXVECTOR3 * pV2
);

Parameters

pOut
[in, out] Pointer to a D3DXVECTOR3 structure, identifying the intersection between the specified plane and line.
pP
[in] Pointer to the source D3DXPLANE structure.
pV1
[in] Pointer to a source D3DXVECTOR3 structure, defining a line starting point.
pV2
[in] Pointer to a source D3DXVECTOR3 structure, defining a line ending point.

Return Values

Pointer to a D3DXVECTOR3 structure that is the intersection between the specified plane and line.

Remarks

If the line is parallel to the plane, NULL is returned.

The return value for this function is the same value returned in the pOut parameter. In this way, the D3DXPlaneIntersectLine function can be used as a parameter for another function.


代码示例
 
#include <stdio.h>
#include <D3DX9Math.h>

#pragma comment(lib, "d3dx9.lib")
#pragma warning(disable : 4305)

int main()
{
    D3DXVECTOR3 A(0, 0, 0);
    D3DXVECTOR3 B(5, 5, 5);

    D3DXPLANE plane(0, 1, 0, -1);   
// equation: x = 1

    D3DXVECTOR3 intersect_point;

    D3DXPlaneIntersectLine(&intersect_point, &plane, &A, &B);

    
// intersect point must be: (1, 1, 1)
    printf("Intersect point: (%f, %f, %f)\n\n", intersect_point.x, intersect_point.y, intersect_point.z);

    
return 0;
}

输出:

Intersect point: (1.000000, 1.000000, 1.000000)



点和平面的位置关系

对于1个给定了法向量n和内部一点p0的平面,任意1点p与该平面的位置关系可用两向量的点积n . (p - p0) 进行判断,分为如下的3种情形:
(1) 点p在法向量n的同一侧,即n . (p - p0) > 0
(2) 点p在平面上,即n . (p - p0) = 0
(3) 点p在法向量n的反侧,即n . (p - p0) < 0

对于以方程式ax+by+cz+d=0给出的平面,由系数a, b和c构成的向量(a, b, c)必然是1个垂直于该平面的向量法向量。

(证明如下:设平面上任意两个点(x1,y1,z1), (x2,y2,z2),代入方程:
  ax1+by1+cz1+d=0;     ax2+by2+cz2+d=0 ;
  ====>
  a(x1-x2)+b(y1-y2)+c(z1-z2)=0
  ====>
  (a,b,c)(x1-x2, y1-y2, z1-z2)=0

即点积为0,因为两点是任意的,所以具有一般性,即向量垂直与平面内任意一条直线。)
称向量(a, b, c)为平面ax + by + cz +d = 0的默认法向量。

判断一点p(x0, y0, z0)与ax+by+z+d=0平面的位置关系,可以直接利用ax0+by0+cz0+d的符号来决定。
 ax0 +by0+cz0+d > 0表示点p在默认法向量的一侧,也可以说是位于平面的前方。
 ax0+by0+cz0+d = 0表示点p在平面上。
 ax0+by0+cz0+d < 0表示点p在默认法向量的另一侧,也可以说是位于平面的后方。

平面(a, b, c, d)与任意点(x0, y0, z0)的ax0 + by0 + cz0值,可用DirectX提供的D3DXPlaneDotCoord函数计算出来,利用该函数返回值的符号可决定点在平面的那一侧。

Computes the dot product of a plane and a 3D vector. The w parameter of the vector is assumed to be 1.

FLOAT D3DXPlaneDotCoord(
CONST D3DXPLANE * pP,
CONST D3DXVECTOR3 * pV
);

Parameters

pP
[in] Pointer to a source D3DXPLANE structure.
pV
[in] Pointer to a source D3DXVECTOR3 structure.

Return Values

The dot product of the plane and 3D vector.

Remarks

Given a plane (a, b, c, d) and a 3D vector (x, y, z) the return value of this function is a*x + b*y + c*z + d*1. The D3DXPlaneDotCoord function is useful for determining the plane's relationship with a coordinate in 3D space.


如果要计算平面法线和另一法线的夹角,可使用D3DXPlaneDotNormal。

Computes the dot product of a plane and a 3D vector. The w parameter of the vector is assumed to be 0.

FLOAT D3DXPlaneDotNormal(
CONST D3DXPLANE * pP,
CONST D3DXVECTOR3 * pV
);

Parameters

pP
[in] Pointer to a source D3DXPLANE structure.
pV
[in] Pointer to a source D3DXVECTOR3 structure.

Return Values

The dot product of the plane and 3D vector.

Remarks

Given a plane (a, b, c, d) and a 3D vector (x, y, z) the return value of this function is a*x + b*y + c*z + d*0. The D3DXPlaneDotNormal function is useful for calculating the angle between the normal of the plane, and another normal.


平面单位化:

如果平面ax+by+cz+d=0的默认法向量n =(a,b,c)为单位向量,那么该平面称为单位化平面。

Normalizes the plane coefficients so that the plane normal has unit length.

D3DXPLANE * D3DXPlaneNormalize(
D3DXPLANE * pOut,
CONST D3DXPLANE * pP
);

Parameters

pOut
[in, out] Pointer to the D3DXPLANE structure that is the result of the operation.
pP
[in] Pointer to the source D3DXPLANE structure.

Return Values

Pointer to a D3DXPLANE structure that represents the normal of the plane.

Remarks

This function normalizes a plane so that |a,b,c| == 1.

The return value for this function is the same value returned in the pOut parameter. In this way, this function can be used as a parameter for another function.


代码示例:

#include <stdio.h>
#include <D3DX9Math.h>

#pragma warning(disable : 4305)

int main()
{
    D3DXPLANE plane(1, 0, 0, -1);

    D3DXVECTOR3 p(5, 0, 0);

    
float dot = D3DXPlaneDotCoord(&plane, &p);
    printf("dot = %f\n\n", dot);

    dot = D3DXPlaneDotNormal(&plane, &p);
    printf("dot = %f\n\n", dot);

    D3DXPLANE plane2(3, 4, 0, 0);
    D3DXPlaneNormalize(&plane2, &plane2);
    printf("After normalize: (%f, %f, %f, %f)\n\n", plane2.a, plane2.b, plane2.c, plane2.d);

    
return 0;
}

输出:

dot = 4.000000

dot = 5.000000

After normalize: (0.600000, 0.800000, 0.000000, 0.000000)

posted on 2007-05-04 01:18 lovedday 阅读(1884) 评论(1)  编辑 收藏 引用 所属分类: ■ DirectX 9 Program

评论

# re: DirectX 9的一些数学计算函数:平面 2008-11-19 05:42 Z. Yao

平面与平面的交线怎么计算  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论