判断一个点是否在凸多边形中--C++

判断一点是否在凸多边形中


判断点是否在一个凸多边形内部的方法有很多,有几何法和向量法等。
几何法,需要太多精巧的设计,太过繁琐;向量法比较统一,所以,今天介绍一下向量法。

原理

  二维向量叉乘,最终会得到一个(0,0,z)的向量,z的正负方向符合右手定则。已知凸多边形质心在多边形内,如果一点在凸多边形内部,则这个点一定属于质心与多边形边的内部;反之,点拘于图形外。
如图,做点至多边形顶点构成多条向量,按照某个方向(顺时针/逆时针),则必然存在相邻向量的向量积彼此反向,即点在图形外,如 p b pb pbX p c pc pc p c pc pcX p d pd pd,根据右手定则,知叉乘结果必然相反。
上图:
点在图形内点在多边形外

方法

  由上面原理分析,可知,只要凸多边形与此点构成的向量,按照顺时针/逆时针,相邻向量做叉乘,得到的相邻结果里面有异号的,即为外点。

code

  既然原理和方法都分析清楚,代码就是基本功了。

#include <iostream>
#include <array>
#include <vector>

using namespace std;
using vector2d = array<double, 2>;

//向量积
double crossProduct(vector2d &p1, vector2d &p2)
{
    return (p1[0]*p2[1]-p2[0]*p1[1]);
}

//判定点在凸多边形内 
bool pointInConvexPolygon(vector2d p, vector<vector2d>& polygon)
{
	int i, iNext, i2Next;
	double preCross, nextCross;
	vector2d v1, v2, v3;
	int polySize= polygon.size();
	
	if(polySize < 3)
	{
		return false;
	}
	for(i = 0; i < polySize; i++)
	{
		iNext = (i + 1) %  polySize;
		i2Next = (iNext + 1) % polySize;
	    
	    //注意v1, v2, v3最好归一化一下,防止图像坐标过大,导致叉乘结果溢出
		v1={polygon[i][0]-p[0], polygon[i][1]-p[1]};
		v2={polygon[iNext][0]-p[0], polygon[iNext][1]-p[1]};
		preCross = crossProduct(v1,v2);
		
		v3={polygon[i2Next][0]-p[0], polygon[i2Next][1]-p[1]};
		nextCross = crossProduct(v2,v3);
		
		if(preCross * nextCross < 0)
		{
			return false;
		}
	}
	
	return true;
}
    
int main()
{
	vector<vector2d> poly{{0,0}, {0, 2}, {2, 0}};
	vector2d p{4, 4};
	
	if(pointInConvexPolygon(p, poly))
	{
		cout<<"this point is in the polygon.\n";
	}
	else
	{
		cout<<"this point is not in the polygon.\n";
	}
	
	return 0;
}

运行结果:运行结果

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值