2013年9月25日星期三(demo5_2点法式平面)

 

所谓点法式,就是

a(x-x0)+b*(y-y0)+c*(z-z0)   =0;

点为直线上一点(x0,y0,z0)

法线为(a,b,c)

初步运行EXE,发现是判断点在平面的哪个区间。

先定义一个3D向量结构体

//3d点和向量

typedef struct VECTOR3D_TYP

{

    union

    {

        float M[3];

        struct

        {

            float x, y, z;

        };

    };

}VECTOR3D ,POINT3D, * VECTOR3D_PTR, * POINT3D_PTR;

 

并定义了2个变量

 

    VECTOR3D        plane_n;        //平面法向量

    POINT3D         plane_p;        //在平面上的点

                      

设定了一个点法式平面结构体

//点法式平面

typedef struct PLANE3D_TYP

{

    POINT3D         p0;     //平面上的点

    VECTOR3D        n;      //平面上的法线

}PLANE3D, * PLANE3D_PTR;

设定了平面

PLANE3D                     plane;

先输入平面法线

 

    printf( "\n输入平面的法线:nx,ny,nz:\n");

    scanf( "%f,%f,%f", &plane_n.x, & plane_n.y, &plane_n.z );

再输入平面上的点的坐标

    printf( "\n输入平面上的点:x,y,z\n");

    scanf( "%f,%f,%f", &plane_p.x, & plane_p.y, &plane_p.z );

3d点拷贝

 

void ddraw_math::POINT3D_COPY( POINT3D_PTR vdst, POINT3D_PTR vsrc )

{

    vdst->x                     = vsrc->x;

    vdst->y                     = vsrc->x;

    vdst->z                     = vsrc->z;

}

 

向量拷贝

 

void ddraw_math::VECTOR3D_COPY( VECTOR3D_PTR vdst, VECTOR3D_PTR vsrc  )

{

    vdst->x                     = vsrc->x;

    vdst->y                     = vsrc->y;

    vdst->z                     = vsrc->z;

}

 

//设为0向量

void ddraw_math::VECTOR3D_ZERO( VECTOR3D_PTR v )

{

    v->x                        = 0;

    v->y                        = 0;

    v->z                        = 0;

}

 

//向量归一化,va发生变化

void ddraw_math::VECTOR3D_Normalize( VECTOR3D_PTR va )

{

    float length                = sqrtf( va->x * va->x + va->y * va->y + va->z * va->z );

    if ( length < EPSILON_E5 )

    {

        return;

    }

 

    float length_inv            = 1 / length;

 

    va->x                       *= length_inv;

    va->y                       *= length_inv;

    va->z                       *= length_inv;

}

 

//归一化,向量存储在vn中

 

void ddraw_math::VECTOR3D_Normalize( VECTOR3D_PTR va,VECTOR3D_PTR vn )

{

    VECTOR3D_ZERO( vn );

    float length                = sqrtf( va->x * va->x + va->y * va->y + va->z * va->z );

    if ( length < EPSILON_E5 )

    {

        return;

    }

 

    float length_inv            = 1 / length;

 

    va->x                       *= length_inv;

    va->y                       *= length_inv;

    va->z                       *= length_inv;

}

 

给定点法式确定平面,并且,若normalize为TRUE,则normalize归一化。

void ddraw_math::PLANE3D_Init( PLANE3D_PTR plane, POINT3D_PTR p0, VECTOR3D_PTR normal, int normalize = 0 )

{

    POINT3D_COPY( & plane->p0, p0 );

 

    if ( !normalize )

    {

        VECTOR3D_COPY( & plane->p0, p0 );

    }

    else

    {

        VECTOR3D_Normalize( normal, & plane->n );

    }

}

确定点在平面的正面(平面法线的一侧),反面(法线的另一侧),还是平面上,

a(x-x0)*b(y-y0)*c(z-z0)>0->正面

a(x-x0)*b(y-y0)*c(z-z0)<0->反面

a(x-x0)*b(y-y0)*c(z-z0)=0->平面上

 

float ddraw_math::Compute_Point_In_Plane3D( POINT3D_PTR pt, PLANE3D_PTR plane )

{

    float hs                    =   plane->n.x * ( pt->x - plane->p0.x ) +

                                    plane->n.y * ( pt->y - plane->p0.y ) +

                                    plane->n.z * ( pt->z - plane->p0.z );

 

    return hs;

 

}

用几个数字检验,OK了

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值