【图形】点在多边形内 Point In Polygon 分析

2018-07-26  本文已影响0人  Kernel32

最近研究了下测试点是否在多边形内,以下代码在网上流传很广,作者都不知道是谁。看别人的分析,还是不太明白,还是要自己画图就研究下。这主要是利用射线与多边形相交的奇偶次数判断是否在多边形内部。

int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)
{
  int i, j, c = 0;
  for (i = 0, j = nvert-1; i < nvert; j = i++) {
    if ( ((verty[i]>testy) != (verty[j]>testy)) &&
     (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
       c = !c;
  }
  return c;
}

先看看参数,nvert 是顶点数量,vertx、verty分别为x,y顶点数组,testx、testy分别为测试点x,y顶点。

i = 0, j = nvert-1; i < nvert; j = i++

再看循环,i = 0时,j = 顶点数减一,执行循环,第一轮循环结束,i 赋值给 j ,跟着 i 自增,即是

循环.png

 
接下来,主要是这个函数的核心。由两个判断组成,

((verty[i]>testy) != (verty[j]>testy))

 (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) 

 
 

1、理解 ((verty[i]>testy) != (verty[j]>testy))
条件1

将 (verty[i]>testy) 与 (verty[j]>testy) 当成两个布尔值来看待。所以只能一真一假,
((verty[i]>testy) != (verty[j]>testy)) 才返回真。那么if的第一个条件才成立。

交点

看图片,当testy同时大于一条边的两个点时,即使有交点也是在矩形外边。

2、理解 (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i])
条件2

还是看图理解吧,文字总说不清楚。

其实就是计算射线与多边形交点的x值,再比较测试点的x值是否小于交点x值。通过比值求得交点,应该是叫“相似三角形”,几何都给回老师了,哈。

【 编辑于 2018-7-26 】

上一篇下一篇

猜你喜欢

热点阅读