在图形学中判断一个点是否在多边形内,若多边形不是自相交的,那么可以简单的判断这个点在多边形内部还是外部;若多边形是自相交的,那么就需要根据非零环绕数规则和奇-偶规则判断。
判断多边形是否是自相交的:多边形在平面内除顶点外还有其他公共点
内-外测试
不自交的多边形:多边形仅在顶点处连接,而在平面内没有其他公共点,此时可以直接划分内-外部分。
自相交的多边形:多边形在平面内除顶点外还有其他公共点,此时划分内-外部分需要采用以下的方法。
(1)奇-偶规则(Odd-even Rule):奇数表示在多边形内,偶数表示在多边形外
从任意位置p作一条射线,若与该射线相交的多边形边的数目为奇数,则p是多边形内部点,否则是外部点。
(2)非零环绕数规则(Nonzero Winding Number Rule):若环绕数为0表示在多边形内,非零表示在多边形外
首先使多边形的边变为矢量。将环绕数初始化为零。再从任意位置p作一条射线。当从p点沿射线方向移动时,对在每个方向上穿过射线的边计数,每当多边形的边从右到左穿过射线时,环绕数加1,从左到右时,环绕数减1。处理完多边形的所有相关边之后,若环绕数为非零,则p为内部点,否则,p是外部点。
参考[1]中例子如下,
判断点p是否在多边形内,从点p向外做一条射线(可以任意方向),多边形的边从左到右经过射线时环数减1,多边形的边从右往左经过射线时环数加1,最后环数不为0,即表示在多边形内部
http://www.zhihu.com/question/26551754 如何判定一点是否在给定顶点的不规则封闭区域内?
这个问题是Point in polygon测试[1]。
其中一个方法是计算射线与多边形边界相交的次数。
任一射线穿过多边形,奇数段位于多边形之内,偶数段位于多边形之外。
检查一点是否在多边形之内,可以作一射线从该点往任意方向投射,若让射线与多边形边的相交次数为奇,则点位于多边形之内。为了简化计算,一般会往水平或垂直方向投射。另外要考虑边与射线平行及顶点与射线相交的情况,题目中的实现不正确。
另一个方法使用winding number [2],可避免除数,也更准确。请参考Inclusion of a Point in a Polygon。
bool pointInRegion(cocos2d::CCPoint pt,vector<cocos2d::CCPoint> plist) { int nCross = 0; for (int i = 0; i < plist.size(); i++) { cocos2d::CCPoint p1; cocos2d::CCPoint p2; p1 = plist[i]; p2 = plist[(i+1)%plist.size()]; if ( p1.y == p2.y ) continue; if ( pt.y < min(p1.y, p2.y)) continue; if ( pt.y >= max(p1.y, p2.y)) continue; double x = (double)(pt.y - p1.y) * (double)(p2.x - p1.x) / (double)(p2.y - p1.y) + p1.x; if ( x > pt.x ) nCross++; } if (nCross % 2 == 1) { return true; } else { return false; } }
南来地,北往的,上班的,下岗的,走过路过不要错过!
======================个性签名=====================
之前认为Apple 的iOS 设计的要比 Android 稳定,我错了吗?
下载的许多客户端程序/游戏程序,经常会Crash,是程序写的不好(内存泄漏?刚启动也会吗?)还是iOS本身的不稳定!!!
如果在Android手机中可以简单联接到ddms,就可以查看系统log,很容易看到程序为什么出错,在iPhone中如何得知呢?试试Organizer吧,分析一下Device logs,也许有用.