判斷點與多邊形的關係(4):射線法

終極大招來了,射線法是解決這一問題的最優方法,其他方法僅具有理論意義,如果工程應用的話,知道這個方法就夠了。
射線法的思想是:以目標點爲端點引一條射線,計算這條射線和多邊形所有邊的交點數目。如果交點個數爲奇數,則點在多邊形部,反之則在多邊形外部。
圖例說明,如下圖所示:




所謂射線法,關鍵在於單向發射,爲簡化問題,以水平線爲例,程序實現中也是這麼處理的。O點向右發出射線,與多邊形的交點是B、C、D,向左發出射線,交點是A,均爲奇數個。P點在多邊形外,無論想哪方向發出攝像,都有2個交點。



對於帶內島的形狀,射線法同樣適用,如上圖所示。在實際應用中,射線法會有很多特殊情況需要討論,全部都討論會比較複雜,但結論是一樣的。這裏不做過多討論了,不過可以給大家結論:射線法適用於所有類型的多邊形進行點與多邊形關係的判斷,且實現相對簡單,速度較快,是工程應用的不二之選。要注意的是,計算中所有數值都要選擇浮點數類型,以保證計算精度。
參考代碼如下:

int InPolygon_Ray(const CZPolygon& polygon, CZPoint_t pt) {
    int itNumPt = polygon.size();
    CZPoint_t pt_1, pt_2;
    int itJunctionCount = 0;
    for (int i = 0; i < (itNumPt - 1); i++) {
        pt_1 = polygon[i];
        pt_2 = polygon[i + 1];
        if (((pt.y >= pt_1.y) && (pt.y <= pt_2.y)) || ((pt.y >= pt_2.y) && (pt.y <= pt_1.y))) {
            double duT = (pt.y - pt_1.y) / (pt_2.y - pt_1.y);
            double duXT = pt_1.x + duT * (pt_2.x - pt_1.x);
            if (pt.x == duXT)
                return ONSIDE;
            if (pt.x > duXT)
                itJunctionCount++;
        }
    }
    return itJunctionCount % 2 ? INSIDE : OUTSIDE;
}

這次要上兩張圖了,以說明射線法的有效性。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章