一.射线判别法:适用于所有简单多边形
简单多边形是不相邻的边不相交的多边形。判定点p是否在多边形G内部,包括边界。对于任意多边形,可以采用射线法。对于给定的点向左做一条平行x轴的射线l,求出l与多边形G的交点个数,如果个数为奇数则点在多边形内,如果交点个数为偶数则点在多边形外。具体可以归纳如下:
1.对G的水平边不做考虑
2.对l与G的顶点相交的情况,只考虑所属边纵坐标较大的顶点。
3.对于p在G边上的情况,直接判定p在G内
//0=outside ;1=inside;2=boundary int PointInPolygon(Point cp){ //射线法判断点是否在多边形内部 int cnt = 0,i; double y1, y2,x; P[n] = P[0]; for (i = 0; i < n; i++){ y1 = min(P[i].y, P[i + 1].y); y2 = max(P[i].y, P[i + 1].y); //水平不考虑 if (RlCmp(P[i].y-P[i + 1].y) == 0) continue; //不相交或者与纵坐标低的顶点相交,不考虑 if (RlCmp(cp.y-y1)<=0 || RlCmp(cp.y -y2)>0) continue; //计算交点横坐标 x = P[i].x + (cp.y - P[i].y)*(P[i + 1].x - P[i].x)/(P[i + 1].y - P[i].y); if (RlCmp(x - cp.x) == 0) return 2; //与边界相交 if (RlCmp(x-cp.x)<0) cnt++; //只记录左边的交点 } return cnt & 1; }
二.叉积判定法:只适用于凸多边形
想像一下从多边形某一个顶点开始沿着边走一圈,如果点P在凸多边形内,那么P一定在这些边的顺时针方向(如果你选择顺时针走的话)或者逆时针方向(如果你选择逆时针方向走的话)。这样以来,该点一定在所有边同一侧。当一直多边形是凸的时候,选择此判别法速度速度快,代码精简。
//0 = outside; 1 = inside; bool PointInPolygon(Point cp){ //叉积判定点是否在凸多边形内 P[n] = P[0]; double k = Cross(P[0], P[1], cp); //初始方向 for (int i = 1; i < n; i++){ if (RlCmp(k*Cross(P[i], P[i + 1], cp)) < 0) return false; } return true; }
时间: 2025-01-12 09:49:29