关于道格拉斯算法的一些思考
2015-12-29 23:32
671 查看
第一种算法的代码下载
第三种算法的代码下载
道格拉斯-普克压缩算法不多说了,我认为问题的难点在于如何将筛选出来的点按照顺序添加入新的集合中,这也是下面我将要介绍的,我关于这的一点思考。
算法简介:
道格拉斯-普克压缩算法维基百科介绍
可以通过下面的动图来理解(来自维基百科介绍页面):
![](https://upload.wikimedia.org/wikipedia/commons/3/30/Douglas-Peucker_animated.gif)
继而,每当我通过计算出得到一个满足条件的点时,我需要将它添加到一个List中,最终再根据List中所有的点的在原线段中的索引值排序。
下面是道格拉斯算法的关键方法:
通过不断的迭代来完成算法的实现。
对一条直线处理完之后,对List中的点按照原索引值排序,这里用了委托方法,下面还有Lambda的例子:
至此,算法就基本完成了。
在处理完一条直线后,存在List中的点依旧是乱的,此时需要对其中的点排序,但是这些点没有了原先的索引值信息,为此,想出的排序方法是:
这样,就能实现排序了。
![](https://img-blog.csdn.net/20151229232410616)
![](https://img-blog.csdn.net/20151229232509748)
![](https://img-blog.csdn.net/20151229232538290)
第三种算法的代码下载
道格拉斯-普克压缩算法不多说了,我认为问题的难点在于如何将筛选出来的点按照顺序添加入新的集合中,这也是下面我将要介绍的,我关于这的一点思考。
算法简介:
道格拉斯-普克压缩算法维基百科介绍
可以通过下面的动图来理解(来自维基百科介绍页面):
![](https://upload.wikimedia.org/wikipedia/commons/3/30/Douglas-Peucker_animated.gif)
1,比较原始的方法:
我需要新建一个这样的类,来保存点的位置信息以及点在所属线段中的索引值。class GeoPoint { public PointF Point { get; private set; } public int Index { get; private set; } public GeoPoint(PointF point, int index) { this.Point = point; this.Index = index; } }
继而,每当我通过计算出得到一个满足条件的点时,我需要将它添加到一个List中,最终再根据List中所有的点的在原线段中的索引值排序。
下面是道格拉斯算法的关键方法:
private void DouglasPeucker(int startIndex,int endIndex) { if (endIndex - startIndex <= 1) return; int middleIndex = startIndex + 1; float maxDistance = 0; GeoPoint lineStartPoint = searchLine.Points[startIndex]; GeoPoint lineEndPoint = searchLine.Points[endIndex]; for (int n = startIndex + 1; n < endIndex; n++) { float distance = DistanceFromPointToLine( searchLine.Points , lineStartPoint, lineEndPoint); if (distance > maxDistance) { middleIndex = n; maxDistance = distance; } } if(maxDistance>this.criticalValue) this.points.Add(searchLine.Points[middleIndex]); DouglasPeucker(startIndex, middleIndex); DouglasPeucker(middleIndex,endIndex); }
通过不断的迭代来完成算法的实现。
对一条直线处理完之后,对List中的点按照原索引值排序,这里用了委托方法,下面还有Lambda的例子:
points.Sort(delegate (GeoPoint p1, GeoPoint p2) { return p1.index.CompareTo(p2.index); });
至此,算法就基本完成了。
2,不新建类如何实现:
在向List中添加点时,需要计算插入点的位置,过于复杂,我未能实现。3,不新建类且不用计算插入点位置
这个方法与刚刚上面的类似,区别在于没有使用带有索引值信息的点类。private void DouglasPeucker(PointF leftPoint, PointF rightPoint) { int leftIndex = tempLine.IndexOf(leftPoint); int rightIndex = tempLine.IndexOf(rightPoint); if ((rightIndex - leftIndex) <= 2) return; int middleIndex = leftIndex + 1; float maxDistance = 0; for (int n = leftIndex + 1; n < rightIndex; n++) { float distance = DistanceFromPointToLine(tempLine , leftPoint, rightPoint); if (distance > maxDistance) { middleIndex = n; maxDistance = distance; } } if (maxDistance > criticalValue) tempPointList.Add(tempLine[middleIndex]); DouglasPeucker(leftPoint, tempLine[middleIndex]); DouglasPeucker(tempLine[middleIndex], rightPoint); }
在处理完一条直线后,存在List中的点依旧是乱的,此时需要对其中的点排序,但是这些点没有了原先的索引值信息,为此,想出的排序方法是:
tempPointList.Sort( (p1, p2) => { return tempLine.IndexOf(p1).CompareTo(tempLine.IndexOf(p2)); });
这样,就能实现排序了。
附:道格拉斯压缩算法的压缩结果
相关文章推荐
- c#调用COM组件
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- C#实现把指定数据写入串口
- C#动态创建button的方法
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#使用加边法计算行列式的值
- C#实现多线程的同步方法实例分析
- C#中尾递归的使用、优化及编译器优化
- C#实现子窗体与父窗体通信方法实例总结
- C#通用邮件发送类分享
- C#中this的用法集锦
- C#数据结构之顺序表(SeqList)实例详解
- C#.NET获取拨号连接的宽带连接方法
- C#异步绑定数据实现方法
- C#实现AddRange为数组添加多个元素的方法
- C#中Equality和Identity浅析
- C#比较二个数组并找出相同或不同元素的方法
- C#生成饼形图及添加文字说明实例代码