所谓点法式,就是
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了