Douglas Peucker算法的C#实现
一、算法原理
Douglas-Peucker算法
在数字化过程中,需要对曲线进行采样简化,即在曲线上取有限个点,将其变为折线,并且能够在一定程度
上保持原有的形状。
经典的Douglas-Peucker算法描述如下:
(1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦;
(2)得到曲线上离该直线段距离最大的点C,计算其与AB的距离D;
(3)比较该距离与预先给定的阈值threshold的大小,如果小于threshold,则该直线段作为曲线的近似,该段曲线处理完毕。
(4)如果距离大于阈值,则用C将曲线分为两段AC和BC,并分别对两段取信进行1~3的处理。
(5)当所有曲线都处理完毕时,依次连接各个分割点形成的折线,即可以作为曲线的近似。
二、算法C#实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace ConsoleApplication2
{
public struct cvPoint
{
public int X;
public int Y;
public cvPoint(int x, int y)
{
X = x;
Y = y;
}
}
class Program
{
static void Main(string[] args)
{
var points = new List<cvPoint>();
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
points.Add(new cvPoint(, ));
var epsilon = 0.8d;
var filteredPoints = new List<cvPoint>();
DouglasPeucker(points, epsilon, ref filteredPoints);
Console.WriteLine("Filtered points:");
foreach (var f in filteredPoints)
{
Console.WriteLine(string.Format("{0},{1}", f.X, f.Y));
}
Console.ReadKey();
}
private static double distanceToSegment(cvPoint p, cvPoint start, cvPoint end)
{
var m1 = ((double)(end.Y - start.Y)) / ((double)(end.X - start.X));
var c1 = start.Y - m1 * start.X;
var interPointX = 0d;
var interPointY = 0d;
if (m1 == )
{
interPointX = p.X;
interPointY = c1; }
else
{
var m2 = - / m1;
var c2 = p.Y - m2 * p.X;
interPointX = (c1 - c2) / (m2 - m1);
interPointY = m2 * interPointX + c2;
}
return Math.Sqrt(Math.Pow(p.X - interPointX, ) + Math.Pow(p.Y - interPointY, ));
} private static void DouglasPeucker(IList<cvPoint> PointList, double epsilon, ref List<cvPoint> filteredPoints)
{
var dmax = 0d;
int index = ;
int length = PointList.Count;
for (int i = ; i < length - ; i++)
{
var d = distanceToSegment(PointList[i], PointList[], PointList[length - ]);
Console.WriteLine(string.Format("{0}.distence:{1}", i, d));
if (d > dmax)
{
index = i;
dmax = d;
}
}
Console.WriteLine(string.Format("dMax:{0}", dmax));
// If max distance is greater than epsilon, recursively simplify
if (dmax > epsilon)
{
filteredPoints.Add(PointList[]);
filteredPoints.Add(PointList[index]);
filteredPoints.Add(PointList[length - ]);
DouglasPeucker(PointList.Take(index + ).ToList(), epsilon, ref filteredPoints);
DouglasPeucker(PointList.Skip(index + ).Take(PointList.Count - index - ).ToList(), epsilon, ref filteredPoints);
}
}
}
}
三、算法验证
近似前:
近似后的线段:
本文地址: http://www.cnblogs.com/deepleo/p/Douglas-Peucker.html
参考:http://www.codeproject.com/Articles/18936/A-C-Implementation-of-Douglas-Peucker-Line-Approxi
Douglas Peucker算法的C#实现的更多相关文章
- OpenCV 学习笔记03 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数
凸形状内部的任意两点的连线都应该在形状里面. 1 道格拉斯-普克算法 Douglas-Peucker algorithm 这个算法在其他文章中讲述的非常详细,此处就详细撰述. 下图是引用维基百科的.ε ...
- 盘点十大GIS相关算法
1.道格拉斯-普克算法(Douglas–Peucker) 道格拉斯-普克算法(Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法.迭代适应点算法.分裂与合并算法)是将曲 ...
- GIS原理学习目录
GIS原理学习目录 内容提要 本网络教程是教育部“新世纪网络课程建设工程”的实施课程.系统扼要地阐述地理信息系统的技术体系,重点突出地理信息系统的基本技术及方法. 本网络教程共分八章:第一章绪论,重点 ...
- 利用道格拉斯·普客法(DP法)压缩矢量多边形(C++)
1.算法描述 经典的Douglas-Peucker算法(简称DP法)描述如下: (1)在曲线首尾两点A,B之间连接一条直线AB,该直线为曲线的弦: (2)得到曲线上离该直线段距离最大的点C,计算其与A ...
- 道格拉斯—普克(Douglas一Peukcer)节点抽稀算法
Douglas一Peukcer算法由D.Douglas和T.Peueker于1973年提出,简称D一P算法,是眼下公认的线状要素化简经典算法.现有的线化简算法中,有相当一部分都是在该算法基础上进行改进 ...
- OOP: One pont of view of OOP与基于算法设计的区别
..摘自<C++网络编程 卷1:运用ACE和模式消除复杂性> <C++ Network Programming Volume 1 Mastering Complexity with ...
- 推些C语言与算法书籍
c语言系统学习与进阶: 1. C primer plus C primer plus 作为一本被人推崇备至的 c 入门经典,C primer plus 绝非浪得虚名.应该 算得上 C 教材里最好的入门 ...
- 每周荐书:云原生、Docker、Web算法(评论送书)
每周荐书:云原生.Docker.Web算法(评论送书) 感谢大家对每周荐书栏目的支持,先公布下上周中奖名单 名优秀评论可以免费获得此书. 云原生应用架构实践 云原生架构,关注简化开发流程.提升研发 ...
- 图像处理之增强---图像增强算法四种,图示与源码,包括retinex(ssr、msr、msrcr)和一种混合算法
申明:本文非笔者原创,原文转载自:http://blog.csdn.net/onezeros/article/details/6342661 两组图像:左边较暗,右边较亮 第一行是原图像,他们下面是用 ...
随机推荐
- Ant Design 使用小结
最近公司做了一个系统,因为页面涉及的表单交互非常多,如果使用之前的 Node + Express 的开发模式效率是非常低的,因此经过考虑,最后决定使用 Node + React 的开发模式,并且使用了 ...
- Spring 4 + Hibernate 4 下 getCurrentSession()的使用情况
前言:1 getCurrentSession创建的session会和绑定到当前线程,而openSession不会. 2 getCurrentSession创建的线程会在事务回滚或事物提交后自动关闭 ...
- BestCoder Round #39 解题报告
现场只做出前三题w 不过不管怎样这既是第一次认真打BC 又是第一次体验用在线编译器调代码 订正最后一题花了今天一整个下午(呜呜 收获还是比较大的^_^ Delete wld有n个数(a1,a2,... ...
- 【洛谷 P1364】医院设置(树的重心)
树的重心的定义: 树若以某点为根,使得该树最大子树的结点数最小,那么这个点则为该树的重心,一棵树可能有多个重心. 树的重心的性质: 1.树上所有的点到树的重心的距离之和是最短的,如果有多个重心,那么总 ...
- 河南省第十届省赛 Intelligent Parking Building
title: Intelligent Parking Building 河南省第十届省赛 tags: [模拟,省赛] 题目描述: There is a new revolution in the pa ...
- BZOJ 100题纪念
- [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法
Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...
- linux下ntp服务器搭建方法
环境 软件:fedora14,装在virtualbox虚拟机上 硬件:x86 具体步骤 检查是否安装了ntp 运行如下命令: rpm -qa | grep ntp 如果有如下输出,表示有安装ntp 服 ...
- 程序异常退出 却没有产生core文件
程序异常退出 却没有产生core文件 http://www.cnblogs.com/my_life/articles/4107333.html
- CSS边框属性
边框 圆角 border-radius border-top-left-radius border-top-right-radius border-bottom-left-radlius border ...