判断点在平面内的方法有很多。
射线法是其中一种,它允许判断的多边形是凹多边形甚至是复合多边形。
射线法思路
判断一个点是否在多边形内部,其实只需要判断从该点沿任意方向的射线与多边形边界的交点是否是偶数就行了。
如果从该点沿任意方向的射线与多边形边界交点为偶数,则该点在多边形外。
如果从该点沿任意方向的射线与多边形边界交点为奇数,则该点在多边形内。


GLSL中的实现
这里以判断uv坐标是否在范围内为例。
其中三个传参uv表示要判断的uv坐标,roi表示存放边界顶点的texture,rect表示边界的矩形范围(用于加快计算,不在该矩形范围内,则一定不再多边形内)
其中getROIuv方法需要自己实现,getROIuv方法作用是从roi中获取指定的uv坐标。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| bool isInside(vec2 uv, sampler2D roi, vec4 rect){ bool ifInside = false; float u = uv.x; float v = uv.y; if(u >= rect.x && v >= rect.y && u <= rect.z && v <= rect.w){ vec2 sP = getROIuv(roi, 0); for (int i = 0; i < WIDTH; i++) { int nextIndex = i + 1; nextIndex = nextIndex == WIDTH ? 0 : nextIndex; vec2 eP = getROIuv(roi, nextIndex); if((sP.x == u && sP.y == v) || (eP.x == u && eP.y == v)){ return true; } else if((sP.y < v && eP.y >= v) || (sP.y >= v && eP.y < v)) { float x = sP.x + (v - sP.y) * (eP.x - sP.x) / (eP.y - sP.y); if(x == u){ return true; } else if(x > u) { ifInside = !ifInside; } } sP = eP; } } return ifInside; }
|
效果展示