判斷某一點是否在幾何圖形內部


 

  公司項目,要實現用戶在矩形的紅外圖像上圈一塊區域,計算該區域內部的平均溫度、最大、最小溫度,圈的區域有可能是矩形、橢圓、或者任意由多條線段構成的多邊形,實現這個需求可以轉換為求一個點是否在該幾何圖形內部,下面總結一下各種幾何圖形的判斷方法。

1.矩形

判斷點是否在矩形內,只要確定點的坐標在矩形四個頂點限定范圍內即可

如上圖,滿足x<=x2&&x>x1&&y>y1&&y<y即可

2.橢圓

判斷點是否在橢圓內,可以根據橢圓表達式求得

如上圖,如果a>b,即焦點在x軸上,則滿足(x*x/a/a+y*y/b/b < 1)的點在橢圓內,如果a<b,即焦點在y軸上,則滿足(y*y/a/a+x*x/b/b<1)的點在橢圓內

3.由多個點構成的不規則圖形

對於不規則圖形,可以通過射線法判斷,即計算射線與多邊形各邊的交點,如果是偶數,則點在多邊形外,否則在多邊形內

算法代碼如下:

public bool Contains(Point test)
        {
            int i;
            int j;
            bool result = false;
            for (i = 0, j = _pointList.Count - 1; i < _pointList.Count; j = i++)
            {
                if ((_pointList[i].Y > test.Y) != (_pointList[j].Y > test.Y) &&
                    (test.X < (_pointList[j].X - _pointList[i].X) * (test.Y - _pointList[i].Y) / (_pointList[j].Y - _pointList[i].Y) + _pointList[i].X))
                {
                    result = !result;
                }
            }
            return result;
        }

要計算射線與線段的交叉,可以觀察下圖:

 

  • t點與線段(v1-v2)要發生相交,t.y必須在線段的兩個頂點的y值之間,即  t.y<v2.y&&t.y>v1.y
  • 滿足上面這個條件以后,只需要判斷該點在線段的左側還是右側,如果在線段左側,則該射線與線段相交,要判斷t在左側還是右側,需要先求得水平線與線段的交點c的x坐標:c.x=(t.y-v1.y)*(v2.x-v1.x)/(v2.y-v1.y)+v1.x

由上兩條,可以推得,t點與線段相交的條件為: t.y<v2.y  &&  t.y>v1.y  &&  c.x<((t.y-v1.y)*(v2.x-v1.x)/(v2.y-v1.y)+v1.x)

接下來考慮一些特殊情況:

  • v1.y==v2.y,即射線與線段重合,該情況不滿足第一個條件,因而對結果沒有影響
  • 射線在頂點上相交,有如下幾種情況:

A頂點為交叉計數提供奇數(1),B、C為交叉計數提供偶數(分別是0、2),正好符合算法條件,A是多邊形真正的交叉,B、C不是

算法測試結果如下:

測試程序地址:https://github.com/xienb/SpatialRelationTest

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM