来自个人百度空间的文章---2012.2.19
一、基本知识
以该点为起点,做平行于X轴的,向X轴的正方向的射线,计算该射线与多边形的边相交的次数,如果是奇数则在多边形的里面,否则反之。
然后需要考虑边界问题:1、如果点在多边形的边上则认为是多边形里面,这条在实际应用中可忽略,因为在图形上多边形的边是一个像素宽度的,很难点到那里,2、射线和多边形的一条边重合,则会造成相交无数个点,所以直接忽略这条边。
二、C++代码
bool FuncPntOPolygon(IAction* acc)
{
//多边形的点集合
size=acc->moveList.size()-1;
//循环该多边形的边
for(UINT i=0;imoveList[i].y>p.y)&&(acc->moveList[i+1].ymoveList[i].ymoveList[i+1].y>p.y)))
{
//若该多边形的线段是平行的,则忽略,因为有可能造成,除法后为无穷大
if (abs(acc->moveList[i].y-acc->moveList[i+1].y)<0.0001) continue;
//使用线段的公式,算出射线相交线段上的x值
x0=acc->moveList[i].x+(p.y-acc->moveList[i].y)*(acc->moveList[i].x-acc->moveList[i+1].x)/
(acc->moveList[i].y-acc->moveList[i+1].y);
//向右射,所以这么判断
if (x0>=p.x) num++;
}
}
//奇数则点在多边形里面
if (num%2!=0) return true;
else return false;
}
moveList[i].y>p.y)&&(acc->moveList[i+1].ymoveList[i].ymoveList[i+1].y>p.y)))
{
//若该多边形的线段是平行的,则忽略,因为有可能造成,除法后为无穷大
if (abs(acc->moveList[i].y-acc->moveList[i+1].y)<0.0001) continue;
//使用线段的公式,算出射线相交线段上的x值
x0=acc->moveList[i].x+(p.y-acc->moveList[i].y)*(acc->moveList[i].x-acc->moveList[i+1].x)/
(acc->moveList[i].y-acc->moveList[i+1].y);
//向右射,所以这么判断
if (x0>=p.x) num++;
}
}
//奇数则点在多边形里面
if (num%2!=0) return true;
else return false;
}