判斷乙個點是否在多邊形內部 2 射線法實現

2021-07-23 03:01:13 字數 1519 閱讀 4512

原文出處:

看過上一次的思路講解後,不知道大家思考得怎麼樣,有沒有遇到一些不好處理的特殊情況。今天就來講講射線法在實際應用中的一些問題和解決方案。

點在多邊形的邊上

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

看了上面的圖就會發現,不管算不算穿越,都會陷入兩難的境地——同樣落在多邊形邊上的點,可能會得到相反的結果。這顯然是不正確的,因此對這種特殊情況需要特殊處理。

點和多邊形的頂點重合

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

射線經過多邊形頂點

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

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

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

解決方案:

點和多邊形頂點重合的情況更簡單,直接比較點的座標就行了。

頂點穿越看似棘手,其實我們換乙個角度,思路會大不相同。先來回答乙個問題,射線穿越一條線段需要什麼前提條件?沒錯,就是線段兩個端點分別在射線兩側。只要想通這一點,頂點穿越就迎刃而解了。這樣一來,我們只需要規定被射線穿越的點都算作其中一側。

如上圖,假如我們規定射線經過的點都屬於射線以上的一側,顯然點d和發生頂點穿越的點c都位於射線y的同一側,所以射線y其實並沒有穿越cd這條邊。而點c和點b則分別位於射線y的兩側,所以射線y和bc發生了穿越,由此我們可以斷定點y在多邊形內。同理,射線x分別與ad和cd都發生了穿越,因此點x在多邊形外,而射線z沒有和多邊形發生穿越,點z位於多邊形外。

解決了第三點,這一點就毫無難度了。根據上面的假設,射線連續經過的兩個頂點顯然都位於射線以上的一側,因此這種情況看作沒有發生穿越就可以了。由於第三點的解決方案實際上已經覆蓋到這種特例,因此不需要再做特別的處理。

問題都解決了,其實並不複雜,不是嗎?啥也不說了,上**。

/**

* @description 射線法判斷點是否在多邊形內部

* @param p 待判斷的點,格式:

* @param poly 多邊形頂點,陣列成員的格式同 p

* @return 點 p 和多邊形 poly 的幾何關係

*/function

raycasting(

p, poly)

// 判斷線段兩端點是否在射線兩側if(

(sy < py && ty >= py)

||(sy >= py && ty < py)

)// 射線穿過多邊形的邊界

if(x > px)}}

// 射線穿過多邊形邊界的次數為奇數時點在多邊形內

return flag ?

'in'

:'out'

}

– p.s. –

本系列共三篇:

射線法思路

射線法實現

迴轉數法

– 完 –

判斷乙個點是否在多邊形內部

判斷乙個點是否在多邊形內部 三角形的有向面積 我們先判斷乙個點是否在乙個三角形內部。乙個三角形在乙個座標系 譬如由a b c三點組成 中,我們可以通過計算它的有向面積來判斷a b c三點在座標系中的順逆。當然,在此之前我們必須先訂立一套計算面積的規則。比如,在笛卡爾座標系中,我們利用 s a.x b...

判斷乙個點是否在多邊形中

例項 1 圖 1是乙個典型的14邊形,紅點為測試點,判斷該紅點是否在14邊形中。解決方法 穿過紅點,做一條平行於x軸的水平線,於14邊形共有8個交點,如果,在紅點的左右兩邊各有奇數個交點,那麼在多邊形中 如果,左右兩邊各有偶數個交點,那麼不在多邊形中 圖 2 例項 2 多邊形是交叉的且封閉的。如圖二...

判斷乙個點是否在多邊形內

演算法 如果是凸多邊形,我覺得這樣很方便 1 在多邊形內任取一點a 比如是某對角線的中點,如果是三角形則取某中線的中點 2 判斷未知點 設為b 與a是否在任何一條邊的同側。方法簡單有效 設任一邊的直線方程為 y ax b 令f x ax b y 只需判斷f a f b 0 a,b同側 0 在邊上 0...