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

本文介绍了在三维空间中如何处理平面,包括如何通过三个点构造平面、确定点与平面的位置关系、计算平面与直线的交点等内容,并展示了如何使用DirectX进行相关计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文链接:http://www.cppblog.com/lovedday/archive/2007/05/04/23388.html

平面

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

对于三角形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个系数,当然结构体还提供了基于方程式系数的加减乘除等运算。

t ypedef  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)

内容概要:本文详细介绍了如何使用Matlab对地表水源热泵系统进行建模,并采用粒子群算法来优化每小时的制冷量和制热量。首先,文章解释了地表水源热泵的工作原理及其重要性,随后展示了如何设定基本参数并构建热泵机组的基础模型。接着,文章深入探讨了粒子群算法的具体实现步骤,包括参数设置、粒子初始化、适应度评估以及粒子位置和速度的更新规则。为了确保优化的有效性和实用性,文中还讨论了如何处理实际应用中的约束条件,如设备的最大能力和制冷/制热模式之间的互斥关系。此外,作者分享了一些实用技巧,例如引入混合优化方法以加快收敛速度,以及在目标函数中加入额外的惩罚项来减少不必要的模式切换。最终,通过对优化结果的可视化分析,验证了所提出的方法能够显著降低能耗并提高系统的运行效率。 适用人群:从事暖通空调系统设计、优化及相关领域的工程师和技术人员,尤其是那些希望深入了解地表水源热泵系统特性和优化方法的专业人士。 使用场景及目标:适用于需要对地表水源热泵系统进行精确建模和优化的情景,旨在找到既满足建筑负荷需求又能使机组运行在最高效率点的制冷/制热量组合。主要目标是在保证室内舒适度的前提下,最大限度地节约能源并延长设备使用寿命。 其他说明:文中提供的Matlab代码片段可以帮助读者更好地理解和复现整个建模和优化过程。同时,作者强调了在实际工程项目中灵活调整相关参数的重要性,以便获得更好的优化效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值