判断点是否在简单多边形内常用方法

一.射线判别法:适用于所有简单多边形

简单多边形是不相邻的边不相交的多边形。判定点p是否在多边形G内部,包括边界。对于任意多边形,可以采用射线法。对于给定的点向左做一条平行x轴的射线l,求出l与多边形G的交点个数,如果个数为奇数则点在多边形内,如果交点个数为偶数则点在多边形外。具体可以归纳如下:

1.对G的水平边不做考虑

2.对l与G的顶点相交的情况,只考虑所属边纵坐标较大的顶点。

3.对于p在G边上的情况,直接判定p在G内

//0=outside ;1=inside;2=boundary
int PointInPolygon(Point cp){
	//射线法判断点是否在多边形内部
	int cnt = 0,i;
	double y1, y2,x;        P[n] = P[0];
	for (i = 0; i < n; i++){
		y1 = min(P[i].y, P[i + 1].y);
		y2 = max(P[i].y, P[i + 1].y);
		//水平不考虑
		if (RlCmp(P[i].y-P[i + 1].y) == 0)
			continue;
		//不相交或者与纵坐标低的顶点相交,不考虑
		if (RlCmp(cp.y-y1)<=0 || RlCmp(cp.y -y2)>0)
			continue;
		//计算交点横坐标
		x = P[i].x + (cp.y - P[i].y)*(P[i + 1].x - P[i].x)/(P[i + 1].y - P[i].y);
		if (RlCmp(x - cp.x) == 0)
			return 2;    //与边界相交
		if (RlCmp(x-cp.x)<0)
			cnt++;   //只记录左边的交点
	}
	return cnt & 1;
}

  二.叉积判定法:只适用于凸多边形

想像一下从多边形某一个顶点开始沿着边走一圈,如果点P在凸多边形内,那么P一定在这些边的顺时针方向(如果你选择顺时针走的话)或者逆时针方向(如果你选择逆时针方向走的话)。这样以来,该点一定在所有边同一侧。当一直多边形是凸的时候,选择此判别法速度速度快,代码精简。

//0 = outside; 1 = inside;
bool PointInPolygon(Point cp){
	//叉积判定点是否在凸多边形内
	P[n] = P[0];
	double k = Cross(P[0], P[1], cp);   //初始方向
	for (int i = 1; i < n; i++){
		if (RlCmp(k*Cross(P[i], P[i + 1], cp)) < 0)
			return false;
	}
	return true;
}

  

时间: 2025-01-12 09:49:29

判断点是否在简单多边形内常用方法的相关文章

【模板】计几 射线法判断点是否在简单多边形内

1 // 2 //线段交点个数 3 int SegCross(Segment a,Segment b){ 4 double x1 = a.s.cross(a.e,b.s); 5 double x2 = a.s.cross(a.e,b.e); 6 double x3 = b.s.cross(b.e,a.s); 7 double x4 = b.s.cross(b.e,a.e); 8 if( b.e.OnLine(a.s,a.e) && b.s.OnSeg(a.s,a.e) || 9 b.s.O

[hdu3644 A Chocolate Manufacturer&#39;s Problem]模拟退火,简单多边形内最大圆

题意:判断简单多边形内是否可以放一个半径为R的圆 思路:如果这个多边形是正多边形,令r(x,y)为圆心在(x,y)处多边形内最大圆的半径,不难发现,f(x,y)越靠近正多边形的中心,r越大,所以可以利用模拟退火法来逼近最优点.对于一般的多边形,由于可能存在多个这样的"局部最优点",所以可以选不同的点作为起点进行多若干次模拟退火即可. 模拟退火的过程:每次由原状态S生成一个新状态T,如果T比S优,那么接受这一次转移,否则以一定概率P接受这次转移,因为这样可能会跳过局部最优解而得到全局最优

判断点是否在多边形内

有一个n边形,顶点为p1,p2,...,pn;给定一个已知点p,判断p在此多边形内还是外. 预备知识: 两线段相交的定义,如果一条线段的两端分别处在另一条线段的两端,则此两线段相交 判断2点在线段的两侧可以用向量的叉乘实现! 基本步骤: 1,过p点垂直向上作一条射线 2,判断此射线与n边形n条边的交点 3,把所有交点相加,如果是奇数则说明在多边形内,否则在多边形外 思路非常的简单,另外说明一下几种特殊的情况: 1,射线与多边形的顶点相交:比如射线过多边形的Pi点,则如果Pi-1和Pi+1在此射线

C# 判断点是否在多边形内

/// <summary>/// 判断点是否在多边形内/// </summary>/// <param name="pnt">点</param>/// <param name="pntlist">区域的点集</param>/// <returns></returns>public static bool PointInFeaces(PointF pnt, List<

AE 判断点是否在面内

1 /// <summary> 2 /// 根据面要素的ID获取面,判断点是否在面内 3 /// </summary> 4 /// <param name="point">要判断的点,射线的起点</param> 5 /// <param name="ID">面的ID</param> 6 /// <param name="pFeatureLayer">面要素所在的图

百度地图 判断marker是否在多边形内

昨天画了圆形,判marker是否存在圆形内.今天来画多边形,判断marker在多边形内. 百度地图API覆盖物多边形类 http://developer.baidu.com/map/reference/index.php?title=Class:%E8%A6%86%E7%9B%96%E7%89%A9%E7%B1%BB/Polygon http://developer.baidu.com/map/reference/index.php?title=Class:%E8%A6%86%E7%9B%96%

判断对象是否在视线内

// Cast a sphere with the desired distance. Check each collider hit to see if it is within the field of view. Set objectFound // to the object that is most directly in front of the agent /// <summary> /// Withins the sight. /// </summary> ///

poj1584——判断凸包,判断点是否在多边形内

poj1584——判断凸包,判断点是否在多边形内 A Round Peg in a Ground Hole Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5441   Accepted: 1729 Description The DIY Furniture company specializes in assemble-it-yourself furniture kits. Typically, the pieces o

js 日期比较大小,js判断日期是否在区间内,js判断时间段是否在另外一个时间段内

/** * 日期解析,字符串转日期 * @param dateString 可以为2017-02-16,2017/02/16,2017.02.16 * @returns {Date} 返回对应的日期对象 */ function dateParse(dateString){ var SEPARATOR_BAR = "-"; var SEPARATOR_SLASH = "/"; var SEPARATOR_DOT = "."; var dateArr