判断一个点是否在一个复杂的多边形中

       图形1

图形1示范了一个典型的有十四条边的凹的多边形。其中红点就是需要去测试的,去判断他是不是在这个多边形中。

 

当前的解决方法是和测试点比较任何一个边的Y坐标,和编译一系列的节点,这些节点的任何一边的点穿过测试点的Y开端。在这个例子中,一共有多边形的8条边穿过这个Y开端。另外的6条边没有。然后,如果那里有奇数目的节点在测试点的任何一边,则这个测试点就在这个多边形中。如果在测试点的任何一边有偶数目的测试点,则这个测试点就在这个多边形之外。在我们的这个例子中,有5个节点在测试点的左边,有三个点在测试点的右边,因此这个点在多边形之中。

(注意:这个算法并不在意多边形是否是顺时针还是逆时针的方向)

    图形2

图形2示范了当一个穿过自己的多边形,在这个例子中,一个十条边的多边形他的边互相穿越。这个效果很像“exclusive or”,或者是XOR对于一个汇编语言的程序员。这个多边形的的一部分被其他消除了。因此,这个测试点是在多边形之外,如同上面验证的,在点的任何一边只有偶数目的节点。

  图形3

在图形3中,这是一个六条边有互相穿越的连线但是并不删除自己的多边形。这个不是问题,

上述的算仍然适用。

 

 

图形4

图形4演示的问题是当一个顶点直接落在测试点的Y开端。因为a边和b边同时和开端

接触,他们能同时产生一个节点吗?不能,因为如果这样一来的话在测试点的两边就有两个节点,测试点就应该在多边形之外,然而事实恰好相反。

这个解决方案非常简单,如果那些正好在Y端的点必需考虑属于哪一条边,让我们武断的说这个点是属于上面条边的。

 图形5

图形5演示的是一个整条边都放置在开端上的例子,简单的根据图形4的规则来考虑。

Side c有一个交点,side d不产生任何的交点。Side e 也不产生节点。

 

最后的笔记

 如果这个点是在这个多边形的边界上,这个算法会发送一个不可预知的结果,例如这个结果可能是“inside” 或者 “outside” 根据系统的坐标。

 

Code Sample


// Globals which should be set before calling this function:
//
// int    polySides  =  how many corners the polygon has
// float  polyX[]    =  horizontal coordinates of corners
// float  polyY[]    =  vertical coordinates of corners
// float  x, y       =  point to be tested
//
// (Globals are used in this example for purposes of speed.
// Change as desired.)
//
// The function will return TRUE if the point x,y is inside the
// polygon, or FALSE if it is not. If the point x,y is exactly on
// the edge of the polygon, then the function may return TRUE or
// FALSE.
//
// Note that division by zero is avoided because the division is
// protected by the "if" clause which surrounds it.

boolean pointInPolygon() {

  int      i, j=0         ;
  boolean  oddNODES=FALSE ;

  for (i=0; i<polySides; i++) {
    j++; if (j==polySides) j=0;
    if (polyY[i]<y && polyY[j]>=y
    ||  polyY[j]<y && polyY[i]>=y) {
      if (polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x) {
        oddNODES=!oddNODES; }}}

  return oddNODES; }

posted @ 2005-07-13 18:20  wanghualiang  阅读(1210)  评论(1编辑  收藏  举报