問題描述:已知兩個多邊形Poly1和Poly2,分別由點集C1={P1,P2,...,Pm}和C2={Q1,Q2,...,Qn}表示,求這兩個多邊形的交集。
演算法思想:
兩個多邊形相交後,其頂點要麼是兩個多邊形邊的交點,要麼是在多邊形內部的點。
演算法步驟:
1.計算兩個多邊形每條邊之間的交點。
2.計算包含在多邊形內部的點。
3.將交點和多邊形內部的點,按逆時針(或順時針)排序,得出最終的點集。
程式碼基本實現如下:
1 typedef struct Point 2 { 3 int x; 4 int y; 5 }Point; 6 bool PolygonClip(const vector<Point> &poly1,const vector<Point> &poly2, std::vector<Point> &interPoly) 7 { 8 if (poly1.size() < 3 || poly2.size() < 3) 9 { 10 return false; 11 } 12 13 long x,y; 14 //計算多邊形交點 15 for (int i = 0;i < poly1.size();i++) 16 { 17 int poly1_next_idx = (i + 1) % poly1.size(); 18 for (int j = 0;j < poly2.size();j++) 19 { 20 int poly2_next_idx = (j + 1) % poly2.size(); 21 if (GetCrossPoint(poly1[i],poly1[poly1_next_idx], 22 poly2[j],poly2[poly2_next_idx], 23 x,y)) 24 { 25 interPoly.push_back(cv::Point(x,y)); 26 } 27 } 28 } 29 30 //計算多邊形內部點 31 for(int i = 0;i < poly1.size();i++) 32 { 33 if (IsPointInpolygon(poly2,poly1[i])) 34 { 35 interPoly.push_back(poly1[i]); 36 } 37 } 38 for (int i = 0;i < poly2.size();i++) 39 { 40 if (IsPointInpolygon(poly1,poly2[i])) 41 { 42 interPoly.push_back(poly2[i]); 43 } 44 } 45 46 if(interPoly.size() <= 0) 47 return false; 48 49 //點集排序 50 ClockwiseSortPoints(interPoly); 51 return true; 52 }
程式碼分析:
求多邊形交集,主要由計算多邊形交點、計算多邊形內部點、點集排序三部分組成,主要由以下三個函式完成。
GetCrossPoint(),求線段交點,參考:http://www.cnblogs.com/dwdxdy/p/3230485.html
IsPointInpolygon(),判斷點是否在多邊形內部,參考:http://www.cnblogs.com/dwdxdy/p/3230647.html
ClockwiseSortPoints(),點集排序,參考:http://www.cnblogs.com/dwdxdy/p/3230156.html
參考資料: