Simple polygon triangulation (violence)
Said front
Online spread all kinds of magic polygon triangulation algorithm, but to speak the truth, difficult to achieve too high. . . There is no search to other people realize. Here write the most violent approach. . Random data validation is no problem, welcome to hack
achieve
A simple ear polygon defined as: If a bump with his triangular configuration adjacent points, there is no other point of the polygon, then he is an ear.
Our idea is simple, each cut off one ear, until the polygon into a triangle.
Core code
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;
}
experiment
Cyaron generated using simple polygon, the triangulation find the area, comparing the actual polygon area is determined.
Example:
Build: