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