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 两组图像:左边较暗,右边较亮 第一行是原图像,他们下面是用 ...
随机推荐
- c++(类) this指针
this指针的相关概念: this只能在成员函数中使用.全局函数,静态函数都不能使用this.实际上,成员函数默认第一个参数为T* const register this. 为什么this指针不能再静 ...
- 前端面试:提升web性能
1,减少HTTP请求数 A,从设计实现层简化页面 B,合理设置HTTP缓存 C,资源合并与压缩.如果可以的话,尽可能的将外部脚本,央视进行合并,多个合为一,css,javascript,image都可 ...
- [BZOJ2453]维护队列|分块
Description 你小时候玩过弹珠吗? 小朋友A有一些弹珠,A喜欢把它们排成队列,从左到右编号为1到N.为了整个队列鲜艳美观,小朋友想知道某一段连续弹珠中,不同颜色的弹珠有多少.当然,A有时候会 ...
- [bzoj3004][SDOI2012]吊灯——樹形DP
Brief Description 給定一棵樹, 判斷是否可以將其分成\(\frac{n}{k}\)個聯通塊, 其中每個聯通塊的大小均爲k. Algorithm Design 我們有一個結論: k可行 ...
- Java环境变量配置以及作用、JDK与JRE区别以及命令行引入jar包
在配置环境变量中: 设置JAVA_HOME: 一是为了方便引用,比如,JDK安装在C:\jdk1.6.0目录里,则设置JAVA_HOME为该目录路径, 那么以后要使用这个路径的时候, 只需输入%JAV ...
- swt 更新主UI线程
// 将msg送回对应的Applet public void write(String msg) { synchronized (msg) { try { m_out.writeUTF(msg); } ...
- POJ3264(线段树求区间最大最小值)
Balanced Lineup Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 41162 Accepted: 19327 ...
- shell命令行混合进制计算器smartbc
需要简单的计算的时候,不想用GUI的计算器,能在shell下直接计算就最好了 查了下,有个东西叫 bc, 具体的使用就不赘述了,可以运行bc,然后进去计算,也可以echo传递过去,大概是像这样 ec ...
- 可参考的js代码
function addcompanyFinalBalance(){ var currentDate = new Date(); var currentYear = date.getFullYear( ...
- require.js使用baseUrl + paths导入文件配置的3种方法
//main.js requirejs.config({ baseUrl: 'lib/js',//参照于引入这个js文件的index.html页面的相对路径,因为此时mian.js文件已经导入到了in ...