判断空间点是否在三角平面内

对于一个三角平面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 函数的定义见上篇文章,不再赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值