旋轉卡殼(計算凸多邊形中最遠距離的兩個點)

2021-06-08 19:44:41 字數 2045 閱讀 4822

2023年, m.i. shamos's ph.d. 的**"computational geometry"標誌著電腦科學的這一領域的誕生。 當時他發表成果的是乙個尋找凸多邊形直徑的乙個非常簡單的演算法, 即根據多邊形的一對點距離的最大值來確定。 

後來直徑演化為由一對對踵點對來確定。 shamos提出了乙個簡單的 o(n) 時間的演算法來確定乙個凸 n 角形的對踵點對。 因為他們最多只有 3n/2 對, 直徑可以在 o(n) 時間內算出。 

如同toussaint後來提出的, shamos的演算法就像繞著多邊形旋轉一對卡殼。 因此就有了術語「旋轉卡殼」。 2023年, toussaint發表了一篇**, 其中用同樣的技術來解決許多問題。 從此, 基於此模型的新演算法就確立了, 解決了許多問題。 

他們包括: 

外接矩形

三角剖分

凸多邊形屬性

最薄截面

我們將乙個多邊形上任意兩點間的距離的最大值定義為多邊形的直徑。 確定這個直徑的點對數可能多於一對。 事實上, 對於擁有 

n 個頂點的多邊形, 就可能有 

n 對「直徑點對」存在。 

乙個多邊形直徑的簡單例子如左圖所示。 直徑點對在圖中顯示為被平行線穿過的黑點 (紅色的一對平行線). 直徑用淺藍色高亮顯示。

顯然, 確定乙個凸多邊形 

p 直徑的點對不可能在多邊形 

p 內部。 故搜尋應該在邊界上進行。 事實上, 由於直徑是由多邊形的平行切線的最遠距離決定的, 所以我們只需要查詢

對踵點。 shamos (1978) 提供了乙個 

o(n) 時間複雜度計算n點凸包對踵點對的演算法。直徑通過遍歷頂點列表, 得到最大距離即可。 如下是2023年發表於 preparata 和 shamos 文章中的 shamos 演算法的偽**。 

輸入是乙個多邊形 

p=. 

begin

p0:=pn;

q:=next[p];

while (area(p,next[p],next[q]) > area(p,next[p],q)) do

q:=next[q];

q0:=q;

while (q != p0) do

begin

p:=next[p];

print(p,q);

while (area(p,next[p],next[q]) > area(p,next[p],q) do

begin

q:=next[q];

if ((p,q) != (q0,p0)) then print(p,q)

else return

end;

if (area(p,next[p],next[q]) = area(p,next[p],q)) then

if ((p,q) != (q0,p0)) then print(p,next[q])

else print(next[p],q)

endend.

此處print(p,q)表示將 

(p,q) 作為乙個對踵點對輸出,area(p,q,r)表示三角形 

pqr 的有向面積。 

雖然直觀上看這個過程與常規旋轉卡殼演算法不同, 但他們在本質上是相同的, 並且避免了所有角度的計算。 

如下是乙個更直觀的演算法:

計算多邊形 y 方向上的端點。 我們稱之為 ymin 和 ymax 。

通過 ymin 和 ymax 構造兩條水平切線。 由於他們已經是一對對踵點, 計算他們之間的距離並維護為乙個當前最大值。

同時旋轉兩條線直到其中一條與多邊形的一條邊重合。

乙個新的對踵點對此時產生。 計算新的距離, 並和當前最大值比較, 大於當前最大值則更新。

重複步驟3和步驟4的過程直到再次產生對踵點對 (ymin,ymax) 。

輸出確定最大直徑的對踵點對。

至此, 上述的過程(偽**中的)顯得十分有用, 我們可以從對踵點對中得到其他的資訊, 如多邊形的

寬度 。

求一棵樹兩個點的最遠距離

原題 1361 樹的最遠距離 題意 給一棵樹,求兩個點這間的距離的最大值 解析 想了很久,發現兩個點a,b也就只有幾種情況 a為b的父結點 a與b屬於同一父結點的兩條不同分支 看到題目,很多人當然會想到離root最遠的那個結點。我們現在就利用這個結點來設計演算法。證明 最遠路一點以最遠結點為端點 如...

(演算法)二叉樹兩個結點的最遠距離

求二叉樹兩個結點的最遠距離。二叉樹定義如下 class treenode 遍歷每個節點,找出以當前節點為根的最長路徑,然後找出所有最長路徑中的最大值。1 class node void longestpath 1 node proot,int maxlen int rightlen if proot...

python 計算兩個多邊形的IOU

計算兩個多邊形的iou。可以是不同類的多邊形,如乙個矩形和乙個三角形 也可以是兩個同類的多邊形。import cv2 import math from skimage.draw import polygon from skimage.feature import peak local max imp...