計算幾何--O(logN) 判斷點在凸多邊形內


二維平面內判斷點是否在一個簡單多邊形內部,在程序設計中我們一般采用射線法,或者內角和法。

如果這個簡單多邊形是一個凸多邊形,可以在logN的時間復雜度內判斷點是否在N個頂點的凸多邊形中。

 

如圖 判斷點P是否在凸多邊形內 設凸多邊形頂點保存在convex[0..n-1]中

首先必須滿足 向量convex[0]-P X convex[0]-convex[1]<0 convex[0]-P X convex[0]-convex[6]>0

X代表叉乘 如果允許點在多邊形邊上 <0 >0可以改寫為<=0 >=0

這樣確定點在角106范圍內后   二分枚舉2--6每個點x  利用叉乘可以判斷向量convex[0]-P在convex[0]-convex[x]逆時針還是順時針 如果是在逆時針 繼續向x--6尋找頂點 否則在2--x-1尋找頂點 直到尋找到最接近P且在P順時針方向的邊convex[0]--convex[x]

此時可以確定點在角x-1 o x范圍內

然后向量convex[x-1]-P X convex[x-1]-convex[x] 判斷P是否在線段x-1--x的左側 在左側點在多邊形內 否則不在

 

因為任意凸多邊形都可以按照其中一個頂點三角剖分 所以有了logN的二分高效算法

/**************************************
Author : lxglbk
Date : 2012/08/17
Function : To determine whether a point is inside of a convex polygon in 2D plane
O(logN)
*********/
double cross(cpoint p0, cpoint p1, cpoint p2)
{
	return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}

bool Compl_inside_convex(const cpoint & p,cpoint *con,int n)
{
	if(n<3) return false;
	if(cross(con[0],p,con[1])>-eps) return false;
	if(cross(con[0],p,con[n-1])<eps) return false;

	int i=2,j=n-1;
	int line=-1;

	while(i<=j)
	{
		int mid=(i+j)>>1;
		if(cross(con[0],p,con[mid])>-eps)
		{
			line=mid;
			j=mid-1;
		}
		else i=mid+1;
	}
	return cross(con[line-1],p,con[line])<-eps;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM