網上流傳着各類神奇的多邊形三角剖分算法,可是講道理,實現難度過高了。。。也沒有搜到其餘人的實現。這裏寫個最暴力的作法。。隨機數據驗證沒問題,歡迎 hack算法
一個簡單多邊形的耳朵定義爲:若是一個凸點與他相鄰的點構成的三角形內,沒有其餘多邊形的點,那麼他是一個耳朵。code
咱們的思想很簡單,每次切掉一個耳朵,直到多邊形變爲一個三角形。blog
typedef vector<vector<P>> VPP; VPP divPtoT(vector<P> ps){ // O(n^3) 簡單多邊形三角剖分 多邊形逆時針 VPP T; T.clear(); if(ps.size()<3) return T; list<int> L; rep(i, 0, ps.size()-1) L.pb(i); auto ck = [&](P A, P B, P C) { if( crossOp(B,C,A) < 0 ) return false; for(int p: L) { if( ps[p] == A || ps[p] == B || ps[p] == C ) continue; if( crossOp(A,B,ps[p])>0&&crossOp(B,C,ps[p])>0&&crossOp(C,A,ps[p])>0 ) return false; } return true; }; P A,B,C; while(L.size() > 3) { auto it = L.begin(); A = ps[*it]; ++it; B = ps[*it]; --it; C = ps[*--L.end()]; if(ck(A,B,C)) { L.erase(it); T.pb({A,B,C}); continue; } auto ed = --L.end(); B = ps[*ed]; -- ed; A = ps[*ed]; ++ ed; C = ps[*L.begin()]; if(ck(A,B,C)) { L.erase(ed); T.pb({A,B,C}); continue; } it = ++L.begin(); for( ; it != ed; ++ it) { B = ps[*it]; --it; A = ps[*it]; ++it; ++it; C = ps[*it]; --it; if(ck(A,B,C)) { L.erase(it); T.pb({A,B,C}); break; } } } if(L.size() == 3) { vector<P> tmp; for(auto it = L.begin(); it != L.end(); ++ it) tmp.pb(ps[*it]); T.pb(tmp); } return T; }
使用 cyaron 生成簡單多邊形,用三角剖分求面積,與實際多邊形面積比較判斷。it
樣例:
生成:
class