要判斷兩個多邊形的關系,實際上屬於幾何圖形空間關系判斷。幾何圖形並不只有多邊形一種,它包括點、線、面構成的任何圖形,兩兩之間相互關系也有很多種,因此空間關系非常復雜。根據前人的研究,總結出了DE-9IM模型,作為一種空間關系判斷的標准。
DE-9IM,全稱是Dimensionally Extended nine-Intersection Model (DE-9IM),是一種拓撲模型,用於描述兩個幾何圖形空間關系的一種標准。在專業領域,通常將每個幾何圖形分為三部分:外部(exterior),邊界(boundary)和內部(interior)。相像一下,一個矩形的三個部分分別是指哪些地方?兩個圖形的關系判斷,實際上就是三個部分的分別判斷,因此就會有一個3*3交叉矩陣,這個矩陣就是DE-9IM模型,如下圖:
其中,a,b分別代表兩個面,I,B,E分別表示它的三個部分。Dim()函數表示相交部分的維度。如果相交部分是一個面,則是二維,即dim()=2;如果相交部分是一條線,則為一維,dim()=1;如果相交部分是一些點,則為0維,dim()=0;如果不相交,則dim()=-1;從上往下,從左往右讀取這個矩陣,就會有一個字符串,如"212101212",即將相互關系轉換成了一個字符串,最終對字符串進行判斷就可以了。上面的圖只是許多關系中的一種,畫的是相交的情形,所以並沒有出現-1的情況。
如果換一種寫法,我們將(0,1,2)認為是相交,寫為T,-1認為不相交,寫為F。則"212101212"變為"TTTTTTTTT"。 實際上這9個值,我們只需要知道其中幾個值就能作出判斷了,不需要全部知道。比如我們只要知道第一位是T,就能判斷兩者相交,而后面8位是什么並不關心。不關心是什么值,我們就用*來代替,因此,我們只要看到"T********",就知道兩個圖形相交。
將關系用專業術語來表達,我們就叫謂詞,比如相交、接觸、重疊、包含等。關系比較多,定義也是非常精細。我們這里只考慮兩個面(兩個多邊形)的關系,因此,只需要掌握幾種關系就可以了。如果需要判斷點、線關系的,建議去https://en.wikipedia.org/wiki/DE-9IM 仔細看看,介紹得非常詳細。
面之間的關系,主要兩種:相交和脫離(不相交),相交又分為接觸、重疊、覆蓋和相等。
謂詞 | 返回值 | 描述 |
相等(Equals) | T*F**FFF* |
邊界上的點和內部的點全部重合。屬於相交的一種 |
脫離(Disjoint) | FF*FF**** |
不相交,與相交相反 |
接觸(Touches) | FT*******\ |
只有邊界上有共同點,內部沒有。屬於相交的一種 |
覆蓋(Covers) | T*****FF*\ |
b上的每個點都在a上(邊界和內部),且所有點都不在a外部。屬於相交的一種 |
重疊(Overlaps) |
|
a和b相交,且具有一部分共同點,但不是全部內部點。屬於相交的一種 |
上圖分別表示:覆蓋、接觸和重疊
在geos中, 這五種關系,分別有對應的函數,返回一個BOOL值
a->equals(b) //判斷ab是否相等,返回 a->disjoint(b) //判斷ab是否脫離 a->touches(b) //判斷ab是否接觸 a->covers(b) //判斷ab是否覆蓋,注意和contains的區別 a->overlaps(b) //判斷兩者是否有重疊部分
另外,如果ab脫離,還可以用
a->distance(b) 計算兩者間的最短距離。
如果ab重疊,還可以用
a->intersection(b) 返回相交部分的幾何圖形。
如果不知道兩者之間是什么關系 ,可以使用
a->relate(b) 來返回一串字符串,然后去匹配字符串,看屬於哪一種關系。
具體代碼練習后續