点集与凸多边形
点集或者是点与多边形位置关系无非就三种
- 点在多边形的内部
- 点在多边形的外部
- 点在多边形上
一般如果该多边形是凸的那么我们可以直接用面积法或者向量法来解决位置关系,如下图所示:
点集与一般性多边形
但是更为一般的多边形可能有凸有凹,该方法便不再适用,如下图所示:
根据该思路可以使用射线法,首先看看射线法的基本操作:
从目标点引一条射线与多边形做交,当交点个数为奇数说明该点在多边形内部,若是为偶数则该点位于多边形外部,且该方法也适用于内部有封闭轮廓的多边形。
图中绿色点为在外部的点,蓝色为在内部和边缘的点:
具体实现代码:
返回是否在多边形内部
//border 为轮廓点集, test1为测试点集
bool IsinPolygon(Border &border, vector<vec2>&test1)
{
//射线法求点在多边形内部
int numcrossline = 0;
int numvecpol = border.p.size();
for (int n = 0; n < test1.size(); n++)
{
for (int i = 0; i < numvecpol; ++i)
{
int j = (i + 1) % numvecpol;
if ((((border.p[i][1] > test1[n][1]) != (border.p[j][1] > test1[n][1])) &&
(test1[n][0] < (border.p[j][0] - border.p[i][0])*(test1[n][1] - border.p[i][1]) / (border.p[j][1] - border.p[i][1]) + border.p[i][0])))
// &&(((border2.p[i][1] > pp[n][1]) != (border2.p[j][1] > pp[n][1])) &&
// (pp[n][0] < (border2.p[j][0] - border2.p[i][0])*(pp[n][1] - border2.p[i][1]) / (border2.p[j][1] - border2.p[i][1]) + border2.p[i][0])))
{
numcrossline = numcrossline + 1;
}
}
if (numcrossline % 2 == 0)
{
test1.erase(test1.begin() + n);
}
else
{
return false;
numcrossline = 0;
}
}
return true;
}
返回结果为在内部的点
vector<vec2> IsinPolygon(Border &border, vector<vec2>&test1)
{
//射线法求点在多边形内部
int numcrossline = 0;
int numvecpol = border.p.size();
for (int n = 0; n < test1.size(); n++)
{
for (int i = 0; i < numvecpol; ++i)
{
int j = (i + 1) % numvecpol;
if ((((border.p[i][1] > test1[n][1]) != (border.p[j][1] > test1[n][1])) &&
(test1[n][0] < (border.p[j][0] - border.p[i][0])*(test1[n][1] - border.p[i][1]) / (border.p[j][1] - border.p[i][1]) + border.p[i][0])))
// &&(((border2.p[i][1] > pp[n][1]) != (border2.p[j][1] > pp[n][1])) &&
// (pp[n][0] < (border2.p[j][0] - border2.p[i][0])*(pp[n][1] - border2.p[i][1]) / (border2.p[j][1] - border2.p[i][1]) + border2.p[i][0])))
{
numcrossline = numcrossline + 1;
}
}
if (numcrossline % 2 == 0)
{
}
else
{
test1.erase(test1.begin() + n);
n--;//n--2020.3.13
numcrossline = 0;
}
}
return test1;
}