通过射线法判断点和多边形的位置关系.适用于任意多边形.
射线法:从目标点引出一条射线,查看和多边形有多少个交点.如果交点是奇数个,说明在多边形内部,否则在多边形外部.(在多边形上的情况,在计算中可以算出来,这里不说明这种情况.)
图中,假设黑色为引出的射线.(因为在给出坐标的情况下,使用x=x0或y=y0的射线便于计算交点)其它线段是多边形的边和射线的可能位置情况.(还有两点都在射线的上方或者下方,只需要判断)
1. AB:两点都在射线起始点的左侧.这种情况下,射线一定不会和这条边有交点
2. AC,AD:A在射线起始位置左侧下方,C在射线起始位置右侧上方
3. DE:均在射线起始点右侧,一个在上方,一个在下方.
4. FG,HI:特殊情况,多边形的顶点在射线上.
5. 其它情况:射线起始点在多边形边上/顶点上;多边形的边和射线平行/多边形的点全部在射线的一侧.
这里使用y=y0的射线对各种情况的判断进行说明.
1.判断给出的多边形两点的x坐标如果都在射线顶点左侧,不计数,直接判断下一条边.
2.这种情况不能仅根据坐标本身判断边是否和射线相交.这种情况下,列出直线方程进行计算.
如果:
交点比射线起点x坐标大,说明有交点.
交点和起点x坐标相等,说明起点在多边形上
交点比射线起点x坐标小,说明没有交点
3.判断边的y坐标在射线两侧,x坐标都比射线起点大,直接进行计数,不再求交点
4.这种情况特殊.
针对FG,HI.它们的下一条边的情况可能是虚线的两种.这里认定在射线上的点均为在射线上方.(当然也可以认定为在射线下方,不过只需认定一种情况) 这样的话,对于FG,是与射线相交的,HI是与射线不相交的.
进行这样认定的原因,可以分析一下它下一条边的情况.针对FG.认定了G在射线上方.那么下一条边如果是下方的虚线,那么这条边会被判断为不在射线上;如果是上方的虚线,则可以判断为在射线上.--------认定G在射线下方,仍然能够得出相同结论:如果下一条边是上方虚线,可以判断多边形和射线有交点;是下方虚线,可以判断为多边形和射线没有交点.
5.这种情况均不进行交点计数.
总结:判断边上的点的y坐标是否在射线两侧,如果在射线两侧:
判断交点和射线起始点的x0的大小.(实际上可以将一些情况区分出来,不计算交点,不过使用方程计算交点,就不需要考虑很多情况了)
伪代码:
(x0,y0),<(x1,y1),(x2,y2)>
cnt=0;
graphArray
for(graphArray){
if(y1<=y0&&y2>y0 || y1>y0&&y2<=y0){//这里是上面描述的第四种情况里的HI情况.
int crossX = 0;
if(x1 == x2){
crossX = x1;
}
else{
crossX = line(point1,point2,y0)//point1,point2组成的直线和射线y0的交点
}
if(crossX>x0){
cnt++;
}
}
}
if(cnt%2 == 1){
点在多边形内
}
参考代码: