判断点集与多边形的位置关系

判断点集与多边形的位置关系

点集与凸多边形

点集或者是点与多边形位置关系无非就三种

  • 点在多边形的内部
  • 点在多边形的外部
  • 点在多边形上
    一般如果该多边形是凸的那么我们可以直接用面积法或者向量法来解决位置关系,如下图所示:
    在这里插入图片描述

点集与一般性多边形

但是更为一般的多边形可能有凸有凹,该方法便不再适用,如下图所示:
在这里插入图片描述
根据该思路可以使用射线法,首先看看射线法的基本操作:
从目标点引一条射线与多边形做交,当交点个数为奇数说明该点在多边形内部,若是为偶数则该点位于多边形外部,且该方法也适用于内部有封闭轮廓的多边形。

在这里插入图片描述
图中绿色点为在外部的点,蓝色为在内部和边缘的点:
具体实现代码:

返回是否在多边形内部

//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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LV小猪精

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值