一種改進的道格拉斯-普克演算法以及C++實現

來源:互聯網
上載者:User
  道格拉斯—普克(Douglas一Peukcer)演算法 分類: 地圖||地理資料 2012-05-10 21:55  1431人閱讀  評論(0)  收藏  舉報 演算法

Douglas一Peukcer演算法由D.Douglas和T.Peueker於1973年提出,簡稱D一P演算法,是目前公認的線狀要素化簡經典演算法。現有的線化簡演算法中,有相當一部分都是在該演算法基礎上進行改進產生的。它的優點是具有平移和旋轉不變性,給定曲線與閡值後,抽樣結果一定。本章線化簡重點講解該演算法。

演算法的基本思路是:對每一條曲線的首末點虛連一條直線,求所有點與直線的距離,並找出最大距離值dmax ,用dmax與限差D相比:若dmax < D ,這條曲線上的中間點全部捨去;若dmax ≥D ,保留dmax 對應的座標點,並以該點為界,把曲線分為兩部分,對這兩部分重複使用該方法。

演算法的詳細步驟如下:

(1) 在曲線首尾兩點間虛連一條直線,求出其餘各點到該直線的距離,如圖3(1)。

(2) 選其最大者與閾值相比較,若大於閾值,則離該直線距離最大的點保留,否則將直線兩端點間各點全部捨去,如圖3(2),第4點保留。

(3) 依據所保留的點,將已知曲線分成兩部分處理,重複第1、2步操作,迭代操作,即仍選距離最大者與閾值比較,依次取捨,直到無點可捨去,最後得到滿足給定精度限差的曲線點座標,如圖3(3)、(4)依次保留第6點、第7點,捨去其他點,即完成線的化簡。




  GIS向量資料化簡:一種改進的道格拉斯-普克演算法以及C++實現 分類: GIS底層開發 2013-10-05 16:46  124人閱讀  評論(0)  收藏  舉報

        既然今天有時間,就多寫幾篇博文算了,也為了明天出去玩好好放鬆一下。

       GIS領域的同志都知道,傳統的道格拉斯-普克演算法都是遞迴實現。然而有時候遞迴的層次太深的話會出現棧溢出的情況。在此,介紹一種非遞迴的演算法。

       要將遞迴演算法改為非遞迴演算法,一般情況下分為兩種情境。第一種是問題定義是遞迴的,如階乘、斐波那契數列等,對於這類問題,改為遞迴演算法很簡單,直接用迭代來做。另外一種是過程是遞迴的,如本文的道格拉斯-普克演算法,對於這類問題呢,一般是用棧(stack)來記錄中間結果,最後得到結果。

        為了保證極值點的不被捨去,將曲線在彎曲極值點分為兩段處理,彎曲極值點通過中間點與相鄰兩個頂點的角度度量。然而傳統的Douglas-Peucker演算法一般在計算過程中沒有考慮到記錄中間最大的距離的節點,造成迴圈時間長、遞迴嵌套層次太深,從而影響了程式的運行效率。本文提出一種結合棧資料結構的分段Douglas-Peucker演算法,它從曲線的一端出發,首先將第一個點和最後一個點作為改進的Douglas-Peucker演算法的工作區間,然後判斷最遠點的距離是否大於閾值,這樣完成線要素的綜合化簡。改進D-P演算法的具體步驟如下:

(1)尋找曲線曲率最大的點,將曲線以此點為界一分為二分成兩部分,對於每一部分都有點列 。然後分別處理這兩段曲線。

(2)對於第一段曲線,有向量的離散點序列 ,設 並且 ,串連 組成一條線段。產生一個棧 ,將 點入棧 。

(3)在 之間的點中尋找與 線段距離最大的點,記為 。

(4)判斷 點到 的距離是否小於閾值,若否,則設 ,並將 加入到特徵點序列,將 壓入棧 ,用線段串連 ,回到(3)。若是,執行第(5)步。

(5)判斷 是否等於 的棧頂元素,若否,則設 、 , 表示棧頂,用線段串連 ,回到(3)。若是,執行(6)。

(6)判斷 是否等於 ,若否,則設 、 ( 表示 的棧頂的下一點),用線段串連 ,棧頂元素出棧,回到(3)。

(7)當棧為空白時,第一段曲線計算結束。處理第二段曲線,重複(1)~(7)。

改進演算法的程式流程圖如下圖所示。

                                                                                                         

圖 改進Douglas-Peucker流程圖

 

本文提出的改進演算法雖然在編程上面比較複雜,但是能夠減少中間重複迴圈的次數。有了上面的流程圖之後,那麼代碼就相對簡單了。 [cpp]  view plain copy void DouglasPeucker(LineVertex *V,int &i,int &j,double e)   {       double dist = 9999;       int f = 0;          //最大距離的點的序號       stack<int> tempVertex;            //STL實現的棧       tempVertex.push(j);          do        {           //迴圈i和j之間距離直線ij最大的點           FindSplit(*V,i,j,&f,&dist);              if (dist > e)      //大於閾值  

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.