对于一个三角平面P1P2P3,假如一个点Px在三角平面内,则有:从一个顶点出发的边向量1与边向量2的向量积 与 该顶点出发的边向量1与该顶点指向Px的向量的向量积 同向。
如下图所示:
如图(1)P1P2与P1P3的向量积为红色向量,P1P2与该平面内哪些向量的向量积 会得到与红色向量同向的向量呢?即向量P1P2右侧的向量。
同理,如图(2)向量P2P3右侧的向量,如图(3)向量P3P1右侧的向量。那么,同时满足(1)(2)(3)的向量即在三角平面内(不包含边界的内部)。
基于此,判断某点是否在三角平面内。
代码如下:
bool IsPtInTri(double x1,double y1,double z1,double x2,double y2,double z2,double x3,double y3,double z3,double ptx,double pty,double ptz)
{
double p1p2[3]={x2-x1,y2-y1,z2-z1};
double p1px[3]={ptx-x1,pty-y1,ptz-z1};
double p1p3[3]={x3-x1,y3-y1,z3-z1};
double tn11[3]={0.0,0.0,0.0};
double tn12[3]={0.0,0.0,0.0};
double n11[3]={0.0,0.0,0.0};
double n12[3]={0.0,0.0,0.0};
cross(p1p2[0],p1p2[1],p1p2[2],p1p3[0],p1p3[1],p1p3[2],tn11[0],tn11[1],tn11[2]);
normalize(tn11[0],tn11[1],tn11[2],n11[0],n11[1],n11[2]);
cross(p1p2[0],p1p2[1],p1p2[2],p1px[0],p1px[1],p1px[2],tn12[0],tn12[1],tn12[2]);
normalize(tn12[0],tn12[1],tn12[2],n12[0],n12[1],n12[2]);
double r1=dot(n11[0],n11[1],n11[2],n12[0],n12[1],n12[2]);
//
double p2p3[3]={x3-x2,y3-y2,z3-z2};
double p2p1[3]={x1-x2,y1-y2,z1-z2};
double p2px[3]={ptx-x2,pty-y2,ptz-z2};
double tn21[3]={0.0,0.0,0.0};
double tn22[3]={0.0,0.0,0.0};
double n21[3]={0.0,0.0,0.0};
double n22[3]={0.0,0.0,0.0};
cross(p2p3[0],p2p3[1],p2p3[2],p2p1[0],p2p1[1],p2p1[2],tn21[0],tn21[1],tn21[2]);
normalize(tn21[0],tn21[1],tn21[2],n21[0],n21[1],n21[2]);
cross(p2p3[0],p2p3[1],p2p3[2],p2px[0],p2px[1],p2px[2],tn22[0],tn22[1],tn22[2]);
normalize(tn22[0],tn22[1],tn22[2],n22[0],n22[1],n22[2]);
double r2=dot(n21[0],n21[1],n21[2],n22[0],n22[1],n22[2]);
//
double p3p1[3]={x1-x3,y1-y3,z1-z3};
double p3p2[3]={x2-x3,y2-y3,z2-z3};
double p3px[3]={ptx-x3,pty-y3,ptz-z3};
double tn31[3]={0.0,0.0,0.0};
double tn32[3]={0.0,0.0,0.0};
double n31[3]={0.0,0.0,0.0};
double n32[3]={0.0,0.0,0.0};
cross(p3p1[0],p3p1[1],p3p1[2],p3p2[0],p3p2[1],p3p2[2],tn31[0],tn31[1],tn31[2]);
normalize(tn31[0],tn31[1],tn31[2],n31[0],n31[1],n31[2]);
cross(p3p1[0],p3p1[1],p3p1[2],p3px[0],p3px[1],p3px[2],tn32[0],tn32[1],tn32[2]);
normalize(tn32[0],tn32[1],tn32[2],n32[0],n32[1],n32[2]);
double r3=dot(n31[0],n31[1],n31[2],n32[0],n32[1],n32[2]);
//精确点说,如果pt是在三角面内,r1,r2,r3应该是为1的
if (r1>0&&r2>0&&r3>0)
{
if ( (
(r1-1)>-MYFLOAT0&&(r1-1)<MYFLOAT0&&
(r2-1)>-MYFLOAT0&&(r2-1)<MYFLOAT0&&
(r3-1)>-MYFLOAT0&&(r3-1)<MYFLOAT0
)
)
{
return true;
}
}
return false;
}
cross,normalize,dot 函数的定义见上篇文章,不再赘述。