日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

道格拉斯-普克 Douglas-Peuker(DP算法) python java实现

發(fā)布時間:2025/3/21 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 道格拉斯-普克 Douglas-Peuker(DP算法) python java实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、道格拉斯-普克抽稀算法說明

道格拉斯-普克抽稀算法是用來對大量冗余的圖形數(shù)據(jù)點進行壓縮以提取必要的數(shù)據(jù)點。
該算法實現(xiàn)抽稀的過程是:
1)對曲線的首末點虛連一條直線,求曲線上所有點與直線的距離,并找出最大距離值dmax,用dmax與事先給定的閾值D相比:?
2)若dmax<D,則將這條曲線上的中間點全部舍去;則該直線段作為曲線的近似,該段曲線處理完畢。?
 ?若dmax≥D,保留dmax對應的坐標點,并以該點為界,把曲線分為兩部分,對這兩部分重復使用該方法,即重復1),2)步,直到所有dmax均<D,即完成對曲線的抽稀。?
顯然,本算法的抽稀精度也與閾值相關,閾值越大,簡化程度越大,點減少的越多,反之,化簡程度越低,點保留的越多,形狀也越趨于原曲線。?

2、舉例說明

輸出結果:1.0 4.0,4.0 2.0,7.0 7.0,9.0 5.0,10.0 10.0,其中2 3,6 6,8 6兩個坐標被抽稀掉了。

示意圖:

假設在平面坐標系上有一條由N個坐標點組成的曲線,已設定一個閾值epsilon
(1)首先,將起始點與結束點用直線連接, 再找出到該直線的距離最大,同時又大于閾值epsilon的點并記錄下該點的位置(這里暫且稱其為最大閾值點),如圖所示:

(2)接著,以該點為分界點,將整條曲線分割成兩段(這里暫且稱之為左曲線和右曲線),將這兩段曲線想象成獨立的曲線然后重復操作(1),找出兩邊的最大閾值點,如圖所示:

(3)最后,重復操作(2)(1)直至再也找不到最大閾值點為止,然后將所有最大閾值點按順序連接起來便可以得到一條更簡化的,更平滑的,與原曲線十分近似的曲線,如圖所示:


3、Java代碼實現(xiàn)

Point類:

public class Point {double x;double y;public Point(int x, int y) {this.x = x;this.y = y;System.out.print("(" + x + "," + y + ") ");}public static Point instance(int x, int y) {return new Point(x, y);} }

DouglasPeuckerUtil 類:

public class DouglasPeuckerUtil {public static void main(String[] args) {System.out.print("原始坐標:");List<Point> points = new ArrayList<>();List<Point> result = new ArrayList<>();points.add(Point.instance(1, 1));points.add(Point.instance(2, 2));points.add(Point.instance(3, 4));points.add(Point.instance(4, 1));points.add(Point.instance(5, 0));points.add(Point.instance(6, 3));points.add(Point.instance(7, 5));points.add(Point.instance(8, 2));points.add(Point.instance(9, 1));points.add(Point.instance(10, 6));System.out.println("");System.out.println("=====================================================================");System.out.print("抽稀坐標:");result = DouglasPeucker(points, 1);for (Point p : result) {System.out.print("(" + p.x + "," + p.y + ") ");}}public static List<Point> DouglasPeucker(List<Point> points, int epsilon) {// 找到最大閾值點,即操作(1)double maxH = 0;int index = 0;int end = points.size();for (int i = 1; i < end - 1; i++) {double h = H(points.get(i), points.get(0), points.get(end - 1));if (h > maxH) {maxH = h;index = i;}}// 如果存在最大閾值點,就進行遞歸遍歷出所有最大閾值點List<Point> result = new ArrayList<>();if (maxH > epsilon) {List<Point> leftPoints = new ArrayList<>();// 左曲線List<Point> rightPoints = new ArrayList<>();// 右曲線// 分別提取出左曲線和右曲線的坐標點for (int i = 0; i < end; i++) {if (i <= index) {leftPoints.add(points.get(i));if (i == index)rightPoints.add(points.get(i));} else {rightPoints.add(points.get(i));}}// 分別保存兩邊遍歷的結果List<Point> leftResult = new ArrayList<>();List<Point> rightResult = new ArrayList<>();leftResult = DouglasPeucker(leftPoints, epsilon);rightResult = DouglasPeucker(rightPoints, epsilon);// 將兩邊的結果整合rightResult.remove(0);//移除重復點leftResult.addAll(rightResult);result = leftResult;} else {// 如果不存在最大閾值點則返回當前遍歷的子曲線的起始點result.add(points.get(0));result.add(points.get(end - 1));}return result;}/*** 計算點到直線的距離* * @param p* @param s* @param e* @return*/public static double H(Point p, Point s, Point e) {double AB = distance(s, e);double CB = distance(p, s);double CA = distance(p, e);double S = helen(CB, CA, AB);double H = 2 * S / AB;return H;}/*** 計算兩點之間的距離* * @param p1* @param p2* @return*/public static double distance(Point p1, Point p2) {double x1 = p1.x;double y1 = p1.y;double x2 = p2.x;double y2 = p2.y;double xy = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));return xy;}/*** 海倫公式,已知三邊求三角形面積* * @param cB* @param cA* @param aB* @return 面積*/public static double helen(double CB, double CA, double AB) {double p = (CB + CA + AB) / 2;double S = Math.sqrt(p * (p - CB) * (p - CA) * (p - AB));return S;}

輸出結果:

?

4 Python代碼實現(xiàn)

4.1 遞歸實現(xiàn)

4.2 非遞歸實現(xiàn)

參考:

1、https://www.jianshu.com/p/bf595477a124

2、https://zhuanlan.zhihu.com/p/74906781

3、https://blog.csdn.net/cdl2008sky/article/details/7701769

?

?

?

總結

以上是生活随笔為你收集整理的道格拉斯-普克 Douglas-Peuker(DP算法) python java实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。