判断点在多边形内部
項目的需要,需要判斷點在多邊形的內部,是整個算法必要的步驟,查了一些資料,中文很少,英文資料已經介紹的很清楚了,這里只是總結一下。
問題的完整描述是判斷平面上一點在多邊形的內部、外部或者邊界上。
有兩種解決方法:光線投射算法,環繞數法。
光線投射算法:
一個簡單的判斷方法是從該點想任意固定方向發送射線,求射線于多邊形邊的交點的個數。如果交點的個數是偶數個,則該點在多邊形的外部,如果是交點的個數是奇數,則該點在多邊形的外部。這種方法不能判斷在多邊形上的情況。
要注意兩個問題:
第一個是當要判斷的點離邊界太近時,由于浮點數計算的不精確,會造成近似誤差。可以通過設置一個點到點斷的最小距離來解決這個問題。但是,當算法的速度要求大于精度要求時,這種情況不用考慮。
另一個問題是在有一些應用中,需要依次判斷射線于各個面的交點,用一張圖來描述這個問題。這種情況下有一個必須要考慮的問題是,當射線直接穿過多邊形的一個頂點,將會與兩個線段相交于兩個端點。當頂點是最上邊的頂點時沒有問題,但是如果是最右邊的頂點,就需要記錄一個交點。
?
這種問題的解決方法:如果射線的交點已經在多邊形的頂點,只有當第二個交點位于位于射線的另一側時才能夠計數。等同于判斷頂點是否在射線的兩側或者同側。
一種光線投射算法實現:
bool PixelInsidePolygon(float x, float y, int* polygonPoints, int count) {// RayCasting method shooting the ray along the x axis, using floatbool inside = false;float xintersection;for (int i = 0; i < count; i += 2){float p1X = polygonPoints[i];float p1Y = polygonPoints[i + 1];float p2X = polygonPoints[(i + 2) % count];float p2Y = polygonPoints[(i + 3) % count];if (y > std::min(p1Y, p2Y) && y <= std::max(p1Y, p2Y) && p1Y != p2Y){if (x <= std::max(p1X, p2X)){xintersection = (y - p1Y)*(p2X - p1X) / (p2Y - p1Y) + p1X;if (p1X == p2X || x <= xintersection){// each time intersect, toggle insideinside = !inside;}}}}return inside; }環繞數算法:
另一種算法是計算給定頂點相對于多邊形的環繞數。如果環繞數非零,則位于多邊形的內部。計算環繞數的方法是多邊形中每條邊的包角(Subtended angle)累加和。但是,這種方法會引入反三角函數,會使算法的效率很慢。因為所有角度相加是0或者,實際上反三角函數不用計算。
有一種改進的環繞數算法,給予從左到右或者從右到左的方式計算環繞數,可以在不計算角度的情況下得到正確的結果,速度和光線投射算法相當切可以處理復雜多邊形的情況。
?
轉載于:https://www.cnblogs.com/xuhui24/p/6204056.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
- 上一篇: display inline-block
- 下一篇: 201621123003《Java程序设