原文出處:
看過上一次的思路講解後,不知道大家思考得怎麼樣,有沒有遇到一些不好處理的特殊情況。今天就來講講射線法在實際應用中的一些問題和解決方案。
點在多邊形的邊上
前面我們講到,射線法的主要思路就是計算射線穿越多邊形邊界的次數。那麼對於點在多邊形的邊上這種特殊情況,射線出發的這一次,是否應該算作穿越呢?
看了上面的圖就會發現,不管算不算穿越,都會陷入兩難的境地——同樣落在多邊形邊上的點,可能會得到相反的結果。這顯然是不正確的,因此對這種特殊情況需要特殊處理。
點和多邊形的頂點重合
這其實是第一種情況的乙個特例。
射線經過多邊形頂點
射線剛好經過多邊形頂點的時候,應該算一次還是兩次穿越?這種情況比前兩種複雜,也是實現中的難點,後面會講解它的解決方案。
射線剛好經過多邊形的一條邊
這是上一種情況的特例,也就是說,射線連續經過了多邊形的兩個相鄰頂點。
解決方案:
點和多邊形頂點重合的情況更簡單,直接比較點的座標就行了。
頂點穿越看似棘手,其實我們換乙個角度,思路會大不相同。先來回答乙個問題,射線穿越一條線段需要什麼前提條件?沒錯,就是線段兩個端點分別在射線兩側。只要想通這一點,頂點穿越就迎刃而解了。這樣一來,我們只需要規定被射線穿越的點都算作其中一側。
如上圖,假如我們規定射線經過的點都屬於射線以上的一側,顯然點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...