1.使用射线法
从点的位置向右发射射线
如果射线命中多边形的次数为奇数,则在多边形内;
如果射线命中多边形的次数为偶数,则不在多边形内 如下图所示
代码实现:
先将多边形放在一个矩形区域内,首先判断点是不是在矩形区域,如果不在则直接返回
public bool IsInPoly(Vector3[] vertices, Vector3 point)
{
//先将多边形放置在矩形区域
Vector3 polyMin = vertices[0];
Vector3 polyMax = vertices[0];
for(int i = 0; i < vertices.Length; i++)
{
if(vertices[i].x < polyMin.x)
{
polyMin.x = vertices[i].x;
}
if(vertices[i].z < polyMin.z)
{
polyMin.z = vertices[i].z;
}
if(vertices[i].x > polyMax.x)
{
polyMax.x = vertices[i].x;
}
if(vertices[i].z > polyMax.z)
{
polyMax.z = vertices[i].z;
}
}
//不在矩形区域内
if(point.x < polyMin.x || point.x > polyMax.x || point.z < polyMin.z || point.z > polyMax.z)
{
return false;
}
bool isInPoly = false;
for(int i = 0; i < vertices.Length; i++)
{
int nextVert = (i + 1) % vertices.Length;
//根据插值公式计算出直线上与point.z相同的z值 z=(1-t)*z0+t*z1,然后带入x方程
float t = (point.z - vertices[i].z) / (vertices[nextVert].z - vertices[i].z);
float x = (1 - t) * vertices[i].x + t * vertices[nextVert].x;
//向右发射线,打中一次反转一次bool值,射中次数为奇数,则在四边形内;射中次数为0或者偶数,则不在四边形内
if (point.x <= x)
{
isInPoly = !isInPoly;
}
}
return isInPoly;
}
t的计算是为了得出跟点point等高的坐标,判断point<=x,这个操作就相当于point往右发射射线