问题:已知点P,平面三角形ABC,判断点P是否在三角形内部。
计算某个点是否在三角形内(平面),有很多种方法,在这我记录两种简单实用的方法,供大家参考。
一、使用叉乘,点乘:
1,先求出三个向量PA,PB,PC.
2,计算PA x PB,PB x PC,PC x PA 。(x表叉乘)
3,利用点乘:如果此三组的向量叉乘的结果都是同号的(或都正,或都负),即方向相同的,
则说明点P在三角形每条边的同侧,即在三角形内部,否则必在外部!
代码如下:举例: p (2,3,0),a (1,1,0),b (2,4,0),c (4,-1,0).
bool Isinside(Vector3 point,Vector3 a,Vector3 b,Vector3 c)
{
Vector3 pa = a - point;
Vector3 pb = b - point;
Vector3 pc = c - point;
Vector3 pab = Vector3.Cross(pa,pb);
Vector3 pbc = Vector3.Cross(pb, pc);
Vector3 pca = Vector3.Cross(pc, pa);
float d1 = Vector3.Dot(pab, pbc);
float d2 = Vector3.Dot(pab, pca);
float d3 = Vector3.Dot(pbc, pca);
if (d1 > 0 && d2 > 0 && d3 > 0) return true;
return false;
}
二、面积法:
点P分别与点A,B,C连接,构成四个三角形,即三角形ABC,三角形PAB,三角形PAC,三角形PBC,
只要求得:三角形ABC面积 = 三角形PAB面积 + 三角形PAC面积 + 三角形PBC面积.
注意:需先考虑点P在边界上的情况(此时其中一个三角形面积为0,但相加面积仍然相等)。
代码如下:
bool Isinside2(Vector3 point, Vector3 a, Vector3 b, Vector3 c)
{
float s1 = Area(a,b,c);
float s2 = Area(point, a, b);
float s3 = Area(point, a, c);
float s4 = Area(point, b, c);
//需考虑边界情况
if (s2 == 0 || s3 == 0 || s4 == 0) return false;
//不能用“==”判断两个浮点类型的值是否相等,可使用如下,差小于等于某个精度值即可。
if (s1 - (s2+s3+s4)<= 0.00001f) return true;
return false;
}
float Area(Vector3 a, Vector3 b, Vector3 c)//计算三角形面积
{
//海伦公式:p=(a+b+c)/2; S = √[p(p-a)(p-b)(p-c)] //这里a,b,c代表边长
float dab = Vector3.Distance(a, b);
float dac = Vector3.Distance(a, c);
float dbc = Vector3.Distance(b, c);
float half = (dab + dac + dbc) / 2;
return Mathf.Sqrt(half * (half - dab) * (half - dac) * (half - dbc));
}