判断一个点是否在一个复杂的多边形中
图形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; }