31 幾何演算法 點集的凸包

2021-10-05 18:56:04 字數 2753 閱讀 6242

extern "c" class algorithmlib convexhull

;

convexhull::convexhull()

convexhull::~convexhull()

datastruct::stack::dynstack> convexhull::run(

const datastruct::array::dynarray>& arrpos_)

math::point<2> _pos = arrpos_[0];

for (int _i = 1; _i < _nsize; _i++) }

// 對n個點,按每個點相對_pos逆時針轉動角度由小到大對n個點排序

datastruct::array::dynarray> _arrpos = arrpos_;

_arrpos.sort([_pos](const math::point<2>& po1_, const math::point<2>& po2_)->int

else if (_nret < 0)

else

else if (_nret < 0)

else

}});

// 將s入棧,將排序後首個點p入棧

_sret.push(_pos);

int _nindex = 0;

while (_nindex < _nsize)

else

}// 對排序後的每個點,按順序依次迭代

for (int _i = _nindex; _i < _nsize; _i++)

math::vector<2> _vec1(_sret.peek(1), _sret.peek());

math::vector<2> _vec2(_sret.peek(), _arrpos[_i]);

geometry::rotate_direction _dir = geometry::testdirection(_vec1, _vec2);

if (_dir == geometry::rotate_direction::anticlock)

else if (_dir == geometry::rotate_direction::no_rotate)

else

}} // 迭代處理完畢,

// 若棧內頂點個數大於等於3,則返回棧作為處理結果

// 若棧內頂點個數小於3,返回空棧以表示點集的凸包不存在

if (_sret.getsize() < 3)

else

}

正確性證明:

演算法目標:給定點集,求取此點集的凸包。

凸包是由點集的乙個子集圍成的封閉區域a

點集內所有點均在圍成的封閉區域之上或之內

封閉區域a的任何兩條相鄰的邊滿足:

假設以封閉區域 y最小【多個y最小時取x最小者】點p開始以逆時針順序對n條邊進行0,...,n-1編號,

則總是有

對i屬於[0,n-1], j=(i+1) % (n)

有i對應的向量 總是以逆時針轉動或者不轉動的 方式 到達 j對應的向量

目前棧中已經存在兩個點

對於後續的每個點

迴圈不變式:

棧中的點,代表了乙個 從封閉區域 y最小【多個y最小時取x最小者】點p開始以逆時針順序得到的點的集合。

依次連線此集合相鄰的點,構成乙個首尾相鄰的封閉區域。

此封閉區域是從p到上次迭代點q為止的點集的乙個凸包。

證明:初始時,

從p到q是兩個點構成的點集,凸包不存在。迴圈不變式滿足。

第k次迭代時

若迭代點t對應於p的旋轉角度,大於上次迭代點,則,滿足,棧中的點+t,代表了乙個 點p開始以逆時針順序的點的集合。

若迭代點t對應於p的旋轉角度 ,等於上次迭代點,則依據排序規則

要麼t和上次迭代點重合,此時不處理t

要麼t處於p和上次迭代點連線的延長線上,此時從棧刪除上次迭代點,加入t構成的集合滿足 代表了乙個 點p開始以逆時針順序的點的集合。

1.若迭代點t對應於p的旋轉角度,大於上次迭代點時,

以q1代表棧頂點,q2代表次棧頂點

1.1.若q2->q1沿逆時針轉動到達q1->t

則,必屬於圖示1

此時q2->q1,q1->t滿足凸包要求

q1->t,t->p也滿足凸包要求

依據迴圈不變式,p...q1是已經處理點集的凸包

可以知道 p...q1,t是本次迭代後已經處理點集的凸包。迴圈不變式滿足。

1.2.若q2->q1沿順時針轉動到達q1->t

此時可以刪除q1

因為易於知道 p->...->q2->t->p所圍成區域包含q1

同理,如此迴圈迭代,直到棧中q2->q1,q1->t沿逆時針轉動到達,或者t在p->q1延長線上時,處理並退出。

易於知道,處理完畢得到的

p->...->t滿足迴圈不變式的要求

2.若迭代點t對應於p的旋轉角度,等於上次迭代點時,

2.1.要麼t和上次迭代點重合,此時不處理t,

可以知道 p...q1是本次迭代後已經處理點集的凸包。迴圈不變式滿足。

2.1. 要麼t處於p和上次迭代點連線的延長線上,此時從棧刪除上次迭代點,加入本次迭代點

可以知道 p...p2,t是本次迭代後已經處理點集的凸包。迴圈不變式滿足。

綜合,k次迭代後迴圈不變式仍然成立

得證

計算幾何 凸包演算法

凸包演算法總結 凸包是指覆蓋平面座標系內若干點的面積最小的凸多邊形。求凸包的第一步是確定 凸包的定點都在給定的點中。通過幾何方法反證很容易得到這一結論。所以,只要從所有點中挑選若干正確的點,按順序 順時針或逆時針 排列,就相當與求得了凸包。計算幾何中的凸包問題程式 graham演算法 include...

計算幾何 凸包演算法 收藏

計算幾何 凸包演算法 收藏 計算幾何中的凸包問題程式 graham演算法 i nclude i nclude i nclude define maxn 10000 頂點的型別定義 typedef struct point1 int n 頂點的個數 point1 points maxn 頂點陣列 in...

計算幾何 經典演算法 凸包

在學習了一些有關計算機幾何的基礎知識和一些基本工具之後要快速的解決一些簡單的幾何問題,如兩點之間的距離 兩線段的交點個數等等是可以輕鬆應付的,但是對於複雜點的幾何問題,我們還是要有更好的演算法,這樣才可以更高效的解決它。在這一篇中來總結 平面凸包 的 graham演算法 平面凸包 定義 對乙個簡單多...