哈羅出行演算法崗筆試題

chc960609發表於2020-10-12

1.判斷一個座標點是否在不規則多邊形內部的演算法

具體思路:射線法。在給定一個測試點,水平向右畫一條射線,判斷有幾個交點,若交點的個數為偶數則在多邊形外部,為奇數則在多邊形內部。

這裡寫圖片描述

程式碼如下:

    public static boolean isInsidePolygon (double[] point, double[][] polygon) {
        // write code here
    	//找到二維陣列每列的最大值與最小值
    	double xMin = Double.MAX_VALUE;
    	double xMax = Double.MIN_VALUE;
    	double yMin = Double.MAX_VALUE;
    	double yMax = Double.MIN_VALUE;
    	for(int i=0;i<polygon.length;i++) {
    		if(polygon[i][0]<xMin) {
    			xMin=polygon[i][0];
    		}
    		if(polygon[i][0]>xMax) {
    			xMax=polygon[i][0];
    		}
    		if(polygon[i][1]<yMin) {
    			yMin=polygon[i][1];
    		}
    		if(polygon[i][1]>yMax) {
    			yMax=polygon[i][1];
    		}
    	}
    	double x=point[0],y=point[1];
    	if(x>xMax||x<xMin||y>yMax||y<yMin) {  //如果該點超出所有點圍成的矩形範圍 則返回不在矩形內
    		return false;
    	}
    	boolean contained = false; // 點是否包含在多邊形內
        // 核心演算法部分    右水平射線   然後數與多邊形的交點
        int N = polygon.length;
        for (int i = 0, j = N - 1; i < N; j = i++) {  //這意思是沿著邊  遍歷多面體的一圈
        	if (((polygon[j][1] > y) != (polygon[i][1] > y))
        			&&x<(polygon[j][0]-polygon[i][0])*(y-polygon[i][1])/(polygon[j][1]-polygon[i][1])+polygon[i][0]) {
        		
        		contained = !contained;
        	}
        	
        }
        return true;
    }

程式碼思想:

就是在測試點水平向右發出射線,統計右射線與多邊形相交的交點個數。對多邊形每條邊進行判斷時(1)對於某些不相交的邊,可以採用 (polygon[j][1] > y) != (polygon[i][1] > y)進行排除,該含義是該測試點的縱座標不位於判斷的邊線段之間時,該點直接跳過判斷,因為不可能產生交點。(2)若條件一滿足,進一步進行判斷該水平的右射線與該邊有無交點,位於該測試點左邊的多邊形的邊都不會滿足這個條件。即代入測試點y的座標在(polygon[j][0]-polygon[i][0])*(y-polygon[i][1])/(polygon[j][1]-polygon[i][1])+polygon[i][0]該式子中,就能得出射線與該邊相交處的橫座標x',若x'大於測試點的橫座標x,說明該邊在右邊與該射線有交點,若x'小於x,說明相交的點在x左邊,不屬於右射線的範圍,因此不把該邊納入計數範圍。按照這兩個條件就能統計出右水平射線與該多邊形的交點數。

該演算法非常巧妙能處理一些特殊情況:

1點在多邊形的邊上

前面我們講到,射線法的主要思路就是計算射線穿越多邊形邊界的次數。那麼對於點在多邊形的邊上這種特殊情況,射線出發的這一次,是否應該算作穿越呢?

enter image description here

邊(P1,P2)的上面 目前有問題https://blog.csdn.net/okvee/article/details/5643407?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight

2點和多邊形的頂點重合

enter image description here

這其實是第一種情況的一個特例。

3射線經過多邊形頂點

射線剛好經過多邊形頂點的時候,應該算一次還是兩次穿越?這種情況比前兩種複雜,也是實現中的難點,後面會講解它的解決方案。

enter image description here

該情況第一條線左線右線都滿足第一條件與第二條件,都各穿一次,為2。

第二條線上線滿足第一條件和第二條件,但下線不滿足第一條件,因此為1。

4射線剛好經過多邊形的一條邊

這是上一種情況的特例,也就是說,射線連續經過了多邊形的兩個相鄰頂點。

enter image description here

 

該情況1+1=2,左邊穿一次,中線重合不滿足第一條件,然後右邊穿一次。

在該演算法中,穿越頂點也計入次數,好處就在於第二個條件排除了三、四兩種情況

相關文章