(四)建筑物多边形化简系统——“去尾巴”和分割复杂多边形
問(wèn)題說(shuō)明
實(shí)際操作中,發(fā)現(xiàn)有的多邊形存在“尾巴”或者很細(xì)的部分。“尾巴”細(xì)長(zhǎng),明顯不是有效建筑物區(qū)域,特點(diǎn)就是區(qū)域面積小,看起來(lái)細(xì)長(zhǎng),附著于大面積多邊形外測(cè)或者連接兩個(gè)多邊形。
需要去除尾巴或者分割多邊形,為后面擬合多邊形做準(zhǔn)備。
算法思想
去除“尾巴”(凸出部分)和分割多邊形的算法思想:
1.求平均距離。
針對(duì)環(huán),遍歷每個(gè)點(diǎn),求到下一個(gè)點(diǎn)之間的距離,計(jì)算該環(huán)兩點(diǎn)間的平均距離L,為之后設(shè)定閾值做準(zhǔn)備。 ??
具體做法:每個(gè)polyline(環(huán))添加計(jì)算平均距離的函數(shù)calAvgDis,添加平均距離成員變量avgDis,在構(gòu)造函數(shù)中調(diào)用calAvgDis函數(shù)初始化avgDis。
2.設(shè)定判斷兩點(diǎn)的距離閾值和下標(biāo)閾值。
即存在兩個(gè)點(diǎn)下標(biāo)差超過(guò)閾值,距離差小于閾值,若兩點(diǎn)與其之間的點(diǎn)構(gòu)成的環(huán)面積小于閾值,則說(shuō)明“尾巴”存在;若大于閾值,則說(shuō)明多邊形應(yīng)該分割。
此處下標(biāo)閾值設(shè)定為10,距離閾值設(shè)定為3個(gè)avgDis,面積閾值設(shè)定為固定值,具體效果和參數(shù)的改變要根據(jù)實(shí)際效果改變。
3.遍歷環(huán)上的沒(méi)點(diǎn),找到最符合條件的兩點(diǎn)。
計(jì)算每點(diǎn)到其他點(diǎn)的距離,針對(duì)每個(gè)點(diǎn)來(lái)說(shuō),遍歷的起點(diǎn)是本點(diǎn)閾值+下標(biāo)閾值。
當(dāng)出現(xiàn)距離小于閾值時(shí),記錄下標(biāo)號(hào),得到(本點(diǎn)下標(biāo),距離小于閾值點(diǎn)的下標(biāo))的下標(biāo)對(duì)。
每個(gè)點(diǎn)可能有不同的下標(biāo)對(duì),每個(gè)環(huán)可能有不同的疑似點(diǎn)及其下標(biāo)對(duì)。
如何找到最合理的兩點(diǎn),遍歷這些下標(biāo)對(duì):1)首先找下標(biāo)號(hào)差距最大;2)相同的情況下距離最小的;
4.找到兩點(diǎn)后:1)針對(duì)“尾巴”(面積小于閾值),消除兩個(gè)點(diǎn)之間的點(diǎn),得到除去尾巴的多邊形。2)針對(duì)面積大于閾值的,分割多邊形。
5.循環(huán)操作,直至某一次操作前后環(huán)的點(diǎn)個(gè)數(shù)一致。
?
實(shí)際操作
1.設(shè)置 距離閾值 和 下標(biāo)差閾值,實(shí)際數(shù)值根據(jù)要求進(jìn)行設(shè)置
int firstNum = circles[i]->pts.size(); //操作前點(diǎn)數(shù) int lastNum = 0; //操作后點(diǎn)數(shù) 初始為0 int t = circles[i]->pointDisThreshold; //下標(biāo)差閾值 double length = circles[i]->calAvgDis(circles[i]->pts); //距離閾值2.針對(duì)環(huán)的每一個(gè)點(diǎn),求與之距離超出閾值,下標(biāo)差超過(guò)閾值且差值最大的點(diǎn),形成一個(gè)點(diǎn)與另一個(gè)點(diǎn)的關(guān)系對(duì)(J和K),遍歷所有的關(guān)系對(duì),找到最合適的一個(gè)關(guān)系對(duì)(因?yàn)槊看沃粍h除一個(gè)尾巴)
while( count<1 && firstNum!=lastNum ){firstNum = circles[i]->pts.size();int num = circles[i]->pts.size()-1; //環(huán)的點(diǎn)數(shù)(去除尾點(diǎn))int finalJ = 0, finalK = 0, FinalDis = 0, finalType = 0; //最后J,K,類(lèi)型if(num > t) { //環(huán)的總點(diǎn)數(shù)大于點(diǎn)數(shù)差閾值時(shí)//找到所有環(huán)中下標(biāo)差最大的兩點(diǎn)for(int j = 0 ; j < (num - t); j++){ //遍歷環(huán)的每個(gè)點(diǎn),int tempDis = 0, tempk = 0, temptype = 0;for(int k = (j + t) ; k<num && (j+num-k)>=t ; k++) { //針對(duì)每一個(gè)點(diǎn),計(jì)算該點(diǎn)與符合要求的點(diǎn)的距離,找到下標(biāo)差最大的另一個(gè)點(diǎn),int dis = (j+num-k)>=(k-j)?(k-j):(j+num-k); //取小的int type = (j+num-k)>=(k-j)?1:2; // 1代表順序,2代表非順序if( (calDis(circles[i]->pts[j],circles[i]->pts[k])<(length*3)) && (tempDis<dis) ){ //尋找下標(biāo)差最大tempDis = dis;tempk = k;temptype = type;}}if( FinalDis<=tempDis ){FinalDis = tempDis;finalJ = j;finalK = tempk;finalType = temptype;}} }3.刪除尾巴或者分割多邊形
實(shí)驗(yàn)效果
? ? ? ? ? ??
總結(jié)
由于本算法自己原創(chuàng),實(shí)際問(wèn)題又非常復(fù)雜,所以效果并沒(méi)有很理想,后期還有優(yōu)化。實(shí)際操作中,部分尾巴去不掉,算法也耗時(shí),這表明這種方法并不是一個(gè)很成熟的算法。而且由于數(shù)據(jù)的復(fù)雜性,考慮的問(wèn)題很多。比如有的最理想的點(diǎn)對(duì)中,一個(gè)在環(huán)首附近的位置,另一個(gè)在環(huán)尾附近位置,需要考慮不同的取舍辦法,等等。
該算法以后需要進(jìn)一步考慮和優(yōu)化。
?
轉(zhuǎn)載于:https://www.cnblogs.com/fan-0802-WHU/p/9748689.html
總結(jié)
以上是生活随笔為你收集整理的(四)建筑物多边形化简系统——“去尾巴”和分割复杂多边形的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: POJ 1330 Nearest Com
- 下一篇: spoj Help the Milita