道格拉斯普克压缩算法
基于第一特征点的道格拉斯—普克压缩算法
基于第一特征点的道格拉斯—普克压缩算法作者:王笑天吕海洋来源:《软件导刊》2016年第11期摘要:对传统的道格拉斯-普克压缩算法进行了分析,指出其存在迭代计算,在面对复杂曲线时可能会出现效率较低的情况。
提出了曲线第一特征点概念,并基于第一特征点对传统算法进行改进,既保留曲线的基本形状,又避免在算法中出现迭代,以较小的压缩比性能损失为代价,显著提升了算法的计算效率。
通过仿真实例验证了改进算法的可行性。
关键词关键词:道格拉斯-普克算法;数据压缩;第一特征点;压缩比;计算效率DOIDOI:10.11907/rjdk.162052中图分类号:TP312文献标识码:A 文章编号文章编号:16727800(2016)0110068030 引言数据对于图形系统的重要性不言而喻。
随着现代数据采集技术以及存储技术的蓬勃发展,数据的量级也逐步由原先的K、M攀升到G,甚至是T了。
对于网络传输和绝大部分界面显示而言,必须预先对数据进行有效压缩,保留必要的特征信息,去除不必要的冗余。
而为了保证应用的实时性,数据压缩计算效率也应予以考虑。
传统的道格拉斯-普克算法能够按照预先设定的阈值对曲线图形进行有效压缩[12],但因其算法中存在迭代,所以面对复杂曲线时可能会出现效率较低的情况。
杜婧等[3]提出了一种改进算法,能够避免传统算法中的迭代,但是引入了累积误差,所以不适用于平缓曲线的压缩。
王净等[45]针对一些特殊情况,对传统算法进行了改进,拓展了适用场景。
赵永清等[67]在阈值自动化设置方面提供了一些解决思路。
本文通过定义曲线特征点,对传统算法进行改进,既保留了曲线的基本形状,又避免了在算法中出现迭代,以较小的压缩比性能损失为代价显著提升了算法的计算效率。
1 道格拉斯-普克算法道格拉斯-普克算法是矢量曲线压缩的经典算法,它从整体角度考虑一条完整曲线。
首先选取曲线的两个端点,计算端点之间各点到两个端点所在直线的垂直距离。
如果这些点到直线的垂直距离中最大值小于或等于预先设定的阈值,则认为所有这些点都可以丢弃;若最大距离大于预先设定的阈值,则认为该最大距离点为线段上的关键点,需要保留。
matlabDouglas-Peucker道格拉斯-普克算法
matlabDouglas-Peucker道格拉斯-普克算法function [ps,ix] = dpsimplify(p,tol)% Recursive Douglas-Peucker Polyline Simplification, Simplify%% [ps,ix] = dpsimplify(p,tol)%% dpsimplify uses the recursive Douglas-Peucker line simplification% algorithm to reduce the number of vertices in a piecewise linear curve% according to a specified tolerance. The algorithm is also know as% Iterative Endpoint Fit. It works also for polylines and polygons% in higher dimensions.%% In case of nans (missing vertex coordinates) dpsimplify assumes that% nans separate polylines. As such, dpsimplify treats each line% separately.%% For additional information on the algorithm follow this link %/doc/7e14536306.html,/wiki/Ramer-Douglas-Peucker_algorithm%% Input arguments%% p polyline n*d matrix with n vertices in d% dimensions.% tol tolerance (maximal euclidean distance allowed% between the new line and a vertex)%% Output arguments%% ps simplified line% ix linear index of the vertices retained in p (ps = p(ix)) %% Examples%% 1. Simplify line%% tol = 1;% x = 1:0.1:8*pi;% y = sin(x) + randn(size(x))*0.1;% p = [x' y'];% ps = dpsimplify(p,tol);%% plot(p(:,1),p(:,2),'k')% hold on% plot(ps(:,1),ps(:,2),'r','LineWidth',2);% legend('original polyline','simplified')%% 2. Reduce polyline so that only knickpoints remain by % choosing a very low tolerance%% p = [(1:10)' [1 2 3 2 4 6 7 8 5 2]'];% p2 = dpsimplify(p,eps);% plot(p(:,1),p(:,2),'k+--')% hold on% plot(p2(:,1),p2(:,2),'ro','MarkerSize',10);% legend('original line','knickpoints')%% 3. Simplify a 3d-curve%% x = sin(1:0.01:20)';% y = cos(1:0.01:20)';% z = x.*y.*(1:0.01:20)';% ps = dpsimplify([x y z],0.1);% plot3(x,y,z);% hold on% plot3(ps(:,1),ps(:,2),ps(:,3),'k*-');%%%% Author: Wolfgang Schwanghart, 13. July, 2010. % w.schwanghart[at]unibas.chif nargin == 0help dpsimplifyreturnend% error(nargchk(2, 2, nargin))narginchk(2, 2);% error checkingif ~isscalar(tol) || tol<0;error('tol must be a positive scalar')end% nr of dimensionsnrvertices = size(p,1);dims = size(p,2);% anonymous function for starting point and end point comparision% using a relative tolerance testcompare = @(a,b) abs(a-b)/max(abs(a),abs(b)) <= eps;% what happens, when there are NaNs?% NaNs divide polylines.Inan = any(isnan(p),2);% any NaN at all?Inanp = any(Inan);% if there is only one vertexif nrvertices == 1 || isempty(p);ps = p;ix = 1;% if there are twoelseif nrvertices == 2 && ~Inanp;% when the line has no vertices (except end and start point of the% line) check if the distance between both is less than the tolerance.% If so, return the center.if dims == 2;d =hypot(p(1,1)-p(2,1),p(1,2)-p(2,2));elsed = sqrt(sum((p(1,:)-p(2,:)).^2));endif d <= tol;ps = sum(p,1)/2;ix = 1;elseps = p;ix = [1;2];endelseif Inanp;% case: there are nans in the p array% --> find start and end indices of contiguous non-nan data Inan = ~Inan;sIX = strfind(Inan',[0 1])' + 1;eIX = strfind(Inan',[1 0])';if Inan(end)==true;eIX = [eIX;nrvertices];endif Inan(1);sIX = [1;sIX];end% calculate length of non-nan componentslIX = eIX-sIX+1;% put each component into a single cellc = mat2cell(p(Inan,:),lIX,dims);% now call dpsimplify again inside cellfun.if nargout == 2;[ps,ix] = cellfun(@(x) dpsimplify(x,tol),c,'uniformoutput',false);ix = cellfun(@(x,six) x+six-1,ix,num2cell(sIX),'uniformoutput',false);elseps = cellfun(@(x) dpsimplify(x,tol),c,'uniformoutput',false);end% write the data from a cell array back to a matrixps = cellfun(@(x) [x;nan(1,dims)],ps,'uniformoutput',false);ps = cell2mat(ps);ps(end,:) = [];% ix wanted? write ix to a matrix, too.if nargout == 2;ix = cell2mat(ix);endelse% if there are no nans than start the recursive algorithmixe = size(p,1);ixs = 1;% logical vector for the vertices to be retainedI = true(ixe,1);% call recursive functionp = simplifyrec(p,tol,ixs,ixe);ps = p(I,:);% if desired return the index of retained verticesif nargout == 2;ix = find(I);endend% _________________________________________________________ function p = simplifyrec(p,tol,ixs,ixe)% check if startpoint and endpoint are the same% better comparison needed which included a tolerance epsc1 = num2cell(p(ixs,:));c2 = num2cell(p(ixe,:));% same start and endpoint with tolerancesameSE = all(cell2mat(cellfun(compare,c1(:),c2(:),'UniformOutput',false)));if sameSE;% calculate the shortest distance of all vertices between ixs and% ixe to ixs onlyif dims == 2;d = hypot(p(ixs,1)-p(ixs+1:ixe-1,1),p(ixs,2)-p(ixs+1:ixe-1,2));elsed = sqrt(sum(bsxfun(@minus,p(ixs,:),p(ixs+1:ixe-1,:)).^2,2));endelse% calculate shortest distance of all points to the line from ixs to ixe% subtract starting point from other locationspt = bsxfun(@minus,p(ixs+1:ixe,:),p(ixs,:));% end pointa = pt(end,:)';beta = (a' * pt')./(a'*a);b= pt-bsxfun(@times,beta,a)';if dims == 2;% if line in 2D use the numerical more robust hypot functiond = hypot(b(:,1),b(:,2));elsed = sqrt(sum(b.^2,2));endend% identify maximum distance and get the linear index of its location[dmax,ixc] = max(d);ixc = ixs + ixc;% if the maximum distance is smaller than the tolerance remove vertices% between ixs and ixeif dmax <= tol;if ixs ~= ixe-1;I(ixs+1:ixe-1) = false;end% if not, call simplifyrec for the segments between ixs and ixc (ixc% and ixe)elsep = simplifyrec(p,tol,ixs,ixc);p = simplifyrec(p,tol,ixc,ixe);endendend。
道格拉斯-普客算法在数据手套数据优化中的应用
道格拉斯-普客算法在数据手套数据优化中的应用孙浩鹏;李杨【摘要】数据手套因为其逼真的人机交互方式,在虚拟现实中越来越广泛地得到应用,尤其在工业装配、仿真手术、控制及手势识别等多个领域.通过分析数据手套的数据特征,运用道格拉斯普客算法,解决了大数据量下的数据手套交互时间延迟问题.通过改进优化数据方法,实现了数据在输入设备采集时大量数据的优化,将数据手套的数据进行优化在数据平滑上进行了处理,得到逼真的虚拟空间虚拟手或者机械手的交互效果,改善了虚拟手在仿真时的颤抖错误,实现了稳定的虚拟手交互效果.【期刊名称】《吉林工程技术师范学院学报》【年(卷),期】2013(029)010【总页数】3页(P79-81)【关键词】虚拟现实;数据手套;道格拉斯-普客【作者】孙浩鹏;李杨【作者单位】长春工程学院计算机技术与工程学院,吉林长春130012;长春建筑学院科研处,吉林长春130699【正文语种】中文【中图分类】TP3911 引言随着交互技术的快速发展,越来越多的人机交互系统要求对手部动作实现高精度的捕捉及仿真。
利用数据手套上的传感器和发射器,可以实时跟踪操作者灵活多变的手势及空间坐标。
将操作者的每个手指关节的坐标和方向数据输入计算机,可以很好地还原手部运动情况。
数据手套在很多场合都有着广阔的应用前景。
如虚拟现实的手术系统等,要求辅助的手部动作侦测设备能够实时、精确地捕捉和还原操作人员的手部动作变化过程。
因此,数据手套的自然性和准确高效性成为非常重要的指标。
2 数据手套的工作方式数据手套在虚拟现实系统中占据重要位置,是一种非常昂贵的人机接口设备,其功能可以实时在虚拟系统中获取人手的各个关节空间坐标,以便在虚拟环境中再现人手动作,达到仿真的人机交互目的。
数据手套有很多种类,以cyber数据手套为例,可以对手部主要骨骼部位的关节运动进行实时测量。
系统可根据反向运动学原理测算出手指关节的位置,并将数据施加到相应的骨骼上。
基于Douglas-Peucker和Quick Bundles算法的水上交通模式识别
基于Douglas-Peucker和Quick Bundles算法的水上交通模式识别作者:陈信强徐祥龙彭静孙洋王梓创阎莹来源:《上海海事大学学报》2022年第03期摘要:针对船舶航迹数据量大、数据冗余、航迹特征不明显等问题,提出一种融合道格拉斯-普克(Douglas-Peucker,DP)压缩算法和基于距离的快速捆绑包(Quick Bundles,QB)聚类算法的水上交通模式识别方法。
该方法根据航迹数据特征、压缩率和压缩误差等指标选择合理的压缩阈值实现大规模船舶自动识别系统(automatic identification system,AIS)数据的压缩。
在此基础上,提出一种基于最小直接翻转距离的聚类指标,利用QB算法实现船舶航迹的有效聚类。
实验结果表明,提出的方法既可以简化航迹聚类过程,也可准确高效地实现航迹聚类,为水上交通精细化管理与决策提供数据支撑。
关键词:船舶航迹聚类; 船舶自动识别系统(AIS); Douglas-Peucker算法; Quick Bundles算法中图分类号: U697.3; U675.79 文献标志码: AMaritime traffic pattern recognition based on Douglas-Peucker andQuick Bundles algorithmsCHEN Xinqiang XU Xianglong PENG Jing SUN Yang WANG Zichuang YAN Ying (1.a.Institute of Logistics Science and Engineering; b.Merchant Marine College,Shanghai Maritime University, Shanghai 201306, China;2.School of Transportation,Chang’an University,Xi’an 710064, China)Abstract:For the problems of large amount of ship trajectory data, data redundancy, and unobvious trajectory characteristics, a maritime traffic pattern recognition method is proposed based on Douglas-Peucker (DP) compression algorithm and the distance-based Quick Bundles (QB)clustering algorithm. In the algorithm, a reasonable compression threshold is determined to achieve the large-scale automatic identification system (AIS) data compression according to the indices of the trajectory data characteristics, the compression ratio and the compression error. A clustering index based on the minimum direct flipping distance is proposed to realize the effective clustering of ship trajectory with the help of QB algorithm. Experimental results show that, the proposed method can not only simplify the ship trajectory clustering process, but also realize the ship trajectory clustering accurately and efficiently. The study provides data support for the fine management and decision-making of maritime traffic.Key words:ship trajectory clustering;automatic identification system (AIS); Douglas-Peucker algorithm; Quick Bundles algorithm0引言隨着经济全球化的进一步发展,航运业已经成为经济和社会发展的重要载体。
道格拉斯普克压缩算法
道格拉斯普克压缩算法#include <algorithm>using namespace std;struct FromTo{int from;int to;};vector DouglasPeuckerDataCompress(vector pts,double tolerance) {double distance = 0;int nStart = 0;int nEnd = pts.size()-1;int numPt = 0;bool flag = true;FromTo from_to;vector Stack;vector numPoints;numPoints.push_back(0);do{distance = GetMaxArcLength(pts,nStart,nEnd,numPt);if (distance > tolerance){numPoints.push_back(numPt);from_to.from = numPt;from_to.to = nEnd;Stack.push_back(from_to);nEnd = numPt;}else{if (Stack.empty())flag = false;else{from_to = Stack[Stack.size()-1];nStart = from_to.from;nEnd = from_to.to;Stack.erase(Stack.end()-1);}}} while(flag);numPoints.push_back(pts.size()-1);vector pnts;for (int i = 0; i != pts.size(); ++i){if (find(numPoints.begin(),numPoints.end(),i) != numPoints.end()) pnts.push_back(pts[i]);}return pnts;}double GetMaxArcLength(vector pts,int nStart,int nEnd,int& numPoint) {double maxLength = 0;double distance = 0;for (int i = nStart+1; i != nEnd; ++i){distance = DistancePointToLine(pts[i],pts[nStart],pts[nEnd]);if (distance > maxLength){maxLength = distance;numPoint = i;}}return maxLength;}double DistancePointToLine(pointD pt,pointD pt1,pointD pt2){if (!DoubleEqual(pt1.x,pt2.x)) //不垂直{double k1 = (pt2.y - pt1.y)/(pt2.x - pt1.x);double b1 = pt2.y - pt2.x * k1;if (!DoubleEqual(0,k1)){double k2 = (-1)/k1;double b2 = pt.y - k2 * pt.x;pointD pt3;pt3.x = (b2 - b1)/(k1 - k2);pt3.y = pt3.x * k1 + b1;return GetDistance(pt,pt3); }else //直线水平return fabs(pt.y - pt1.y);}else //直线垂直return fabs(pt2.x - pt.x);}。
道格拉斯普克算法 java
道格拉斯普克算法 java道格拉斯-普克(Douglas-Peucker)算法是一种用于抽稀多边形的算法,可以大幅减少数据点的数量,从而减小数据存储和计算量。
它可以被用于地理信息系统(GIS)中的线简化和绘图中的平滑。
简单地说,该算法的目标是通过移除一些数据点,使得简化后的多边形与原始多边形尽量相似。
被移除的数据点将不会影响多边形的形状,但可以大大减少数据的数量。
算法的基本思想是通过迭代地应用以下两步来实现多边形简化:1.找到距离最大的点:选择多边形中与折线距离最大的点,该点与折线之间的距离可以用于度量折线与多边形之间的偏差。
2.检查点与多边形之间的偏差:如果距离最大的点与多边形之间的距离小于设定的阈值,那么相应的数据点将被移除。
如果距离大于阈值,则把多边形的线段分割成两部分,然后分别对两部分进行递归处理。
以下是一个用Java实现道格拉斯-普克算法的示例代码:```javaimport java.util.ArrayList;import java.util.List;public class DouglasPeuckerAlgorithm {private static final double DEFAULT_TOLERANCE = 0.1; //默认阈值private double tolerance; //阈值private List<Point> resultPoints; //简化后的点集public List<Point> simplify(List<Point> points) {resultPoints = new ArrayList<>();if (points.size() < 3) {return points; //当点集少于3个时直接返回}tolerance = DEFAULT_TOLERANCE;simplifyLine(points, 0, points.size() - 1);return resultPoints;}private void simplifyLine(List<Point> points, int startIndex, int endIndex) {double maxDistance = 0.0;int maxIndex = startIndex;for (int i = startIndex + 1; i < endIndex; i++) {double distance = perpendicularDistance(points.get(i), points.get(startIndex), points.get(endIndex));if (distance > maxDistance) {maxDistance = distance;maxIndex = i;}}if (maxDistance > tolerance) {simplifyLine(points, startIndex, maxIndex);resultPoints.add(points.get(maxIndex));simplifyLine(points, maxIndex, endIndex);}}private double perpendicularDistance(Point point, Point lineStart, Point lineEnd) {double x = point.getX();double y = point.getY();double startX = lineStart.getX();double startY = lineStart.getY();double endX = lineEnd.getX();double endY = lineEnd.getY();double normalLength = Math.sqrt((endX - startX) * (endX - startX) + (endY - startY) * (endY - startY));return Math.abs((x - startX) * (endY - startY) - (y - startY) * (endX - startX)) / normalLength;}public static void main(String[] args) {List<Point> points = new ArrayList<>();points.add(new Point(0, 0));points.add(new Point(1, 1));points.add(new Point(2, 2));points.add(new Point(3, 4));points.add(new Point(4, 1));points.add(new Point(5, 3));points.add(new Point(6, 0));DouglasPeuckerAlgorithm algorithm = new DouglasPeuckerAlgorithm();List<Point> simplifiedPoints = algorithm.simplify(points);for (Point point : simplifiedPoints) {System.out.println("(" + point.getX() + ", " +point.getY() + ")");}}}class Point {private double x;private double y;public Point(double x, double y) {this.x = x;this.y = y;}public double getX() {return x;}public double getY() {return y;}}```以上代码中,我们定义了一个`DouglasPeuckerAlgorithm`类来实现道格拉斯-普克算法。
DouglasPeucker算法
下一步的基准线
5
Hale Waihona Puke Douglas-Peucker算法的问题
公共边分裂
自相交的出现
步骤三:重复将步骤二中得到的基准顶点对进行步 骤二的计算,直到所有点到他们的基准线的距离都 小于等于ε。
V3离线段 V0V7最远
V5 V1
V2
V0
V7 V6
V4 处理前的点的连线 第一次计算的基准线 第二次计算的基准线
Step 1
Step 2
4
Step 3
Last Step 处理前的点的连线 当前基准线
曲线数据压缩算法(DouglasPeucker算法)
步骤一:确定阀值ε。
步骤二:先连接第一个和最后一个边界网格顶点, 计算这对基准顶点对之间的点到基准线的距离。如 果有一个及一个以上的点到基准线的距离大于ε, 将距离基准线最远的点记为第n个点,删除基准线, 并将第一个点和第n个点记为基准顶点对,将第n 个点和最后一个点记为基准顶点对;如果所有点到 基准线的距离都小于等于ε,删除基准顶点之间的 所有点,只保留基准顶点对作为基准顶点对之间曲 线的控制顶点。
douglas—peucker 算法公式
douglas—peucker 算法公式
【最新版】
目录
1.道格拉斯 - 皮克算法简介
2.道格拉斯 - 皮克算法公式
3.道格拉斯 - 皮克算法的应用
4.道格拉斯 - 皮克算法的优缺点
正文
道格拉斯 - 皮克算法是一种非常著名的曲线拟合算法,被广泛应用
于计算机图形学、数值分析以及工程领域等。
该算法是由道格拉斯和皮克
于 1979 年首次提出,目的是为了解决在给定一组离散点集的情况下,找
到最佳的拟合曲线。
道格拉斯 - 皮克算法公式如下:
设 N 个点集为 X={(x1, y1), (x2, y2),..., (xN, yN)},拟合直线
为 y=ax+b,通过最小化误差平方和来寻找最佳的拟合直线,即寻找 a 和
b 的最佳值。
误差平方和可表示为:
S = Σ[(yi - axi - b)] (i=1,2,...,N)
通过求导可得 a 和 b 的最佳值分别为:
a = (N∑(xi * yi) - Σ(xi * Σ(yi))) / (N∑(xi) - (Σ(xi)))
b = (Σ(yi) - a * Σ(xi)) / N
道格拉斯 - 皮克算法的应用非常广泛,其中最主要的应用是在计算
机图形学中,用于对离散的点集进行平滑处理,得到连续的曲线。
此外,
该算法也被广泛应用于数据压缩、图像处理以及数值分析等领域。
道格拉斯 - 皮克算法的优点是计算简单,易于实现,且拟合效果较
好。
但是,该算法也存在一些缺点,例如对于一些特殊形状的点集,可能无法得到理想的拟合效果。
基于形状特征点的改进道格拉斯—普克压缩算法
基于形状特征点的改进道格拉斯—普克压缩算法作者:肖亚楠来源:《西部论丛》2018年第04期【摘要】本文通过对传统的矢量数据压缩算法的分析发现,道格拉斯-普克压缩算法在处理复杂线要素时,存在错误删除特征点、存在自相交等问题;而垂距法则注重局部判断处理,没有从宏观角度对整体线要素进行分析处理。
基于此对道格拉斯-普克压缩算法进行了改进,首先根据各顶点处的形状参数大小,提取特征点,然后以各特征点为分界点对线要素进行分段,最后使用道格拉斯普克算法对各分段进行处理。
文中使用矢量数据对算法进行了验证,并与传统矢量压缩算法的处理结果进行了比较,发现改进后的算法在处理复杂线要素时具有更高的准确性。
【关键词】矢量数据数据压缩道格拉斯-普克压缩算法形状特征点1 引言地理数据的有效获取与处理,一直以来都是进行GIS工程建设以及地图制图的重要基础性工作,地理数据的数量以及处理质量将直接影响后续的数据分析与应用工作。
本文分析了传统矢量数据压缩算法的优缺点,融入了线要素形状特征的思想,对道格拉斯-普克算法进行了改进,并对改进后的算法进行了实验验证。
2 传统矢量数据压缩算法矢量数据压缩是在保证信息量的前提下,尽可能的减少表达信息所需要的数据量。
矢量数据压缩的方法一是降低数据精度,二是减少构成线要素的数据点。
前者在精度要求较高的应用中不适用,后者常见算法有间隔点删除法、光栏法、垂距法,以及最为经典的道格拉斯-普克算法(Douglas-Peucker algorithm)。
间隔点删除法没有考虑各顶点之间的关系,仅按照间隔进行数据删除,精度保持效果较差;垂距法和光栏法均为局部算法,仅考虑局部顶点之间的位置关系,没有考虑到线要素的整体性,并且在数据量大的情况下,对精度的保持效果有所下降。
道格拉斯-普克算法综合考虑了线要素的整体特征,通过计算线要素各中间顶点到首尾顶点连线的距离,比较最大距离值与阈值的大小,若小于阈值,则删除所有中间点;若大于阈值,则以距离最大点为分界点,将线要素分割为前后两段。
170316.道格拉斯-普克算法
170316.道格拉斯-普克算法道格拉斯-普克算法道格拉斯-普克算法 (Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法、迭代适应点算法、分裂与合并算法)是乌尔斯·拉默(Urs Ramer)于1972年以及⼤卫·道格拉斯(David Douglas)和托马斯·普克(Thomas Peucker)于1973年提出的⼀种简化线的⼀种经典算法。
它是通过减少曲线中点的数量,得出⼀条尽可能完整的表达原有曲线的特征的曲线。
⼀般来讲,道格拉斯-普克算法需要⼀个极差D,极差D的值越⼤,证明曲线简化的越多,反之极差越⼩,表⽰简化的越⼩通俗的理解,道格拉斯-普克算法是通过分治策略处理⼀组曲线,⽽极差D则可以理解为⼀个⽐较值,或者可以说是⼀个临界点,通过对垂距⼤于此临界点的点进⾏保留,对⼩于此临界点的点进⾏删除,达到简化曲线的效果算法的基本思路是:对曲线的⾸末点虚连⼀条直线,求此曲线其余所有点到直线的距离(垂距),从中找出最⼤距离值dmax ,⽤d max与限差D相⽐:若d max <D,这条曲线上的中间点全部舍去;若d max ≥D,保留d max 对应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使⽤该⽅法,当曲线⽆法分为两部分时结束。
具体步骤如下:(1) 在曲线⾸尾两点间虚连⼀条直线,求出其余各点到该直线的距离。
(2)选其最⼤者与极差D相⽐较,若⼤于极差D,则离该直线距离最⼤的点保留,否则将直线两端点间各点全部舍去。
(3)以保留的点为中⼼,将已知曲线分成两部分处理,重复执⾏第1、2步操作,迭代操作,即仍选该直线距离最⼤者与极差D⽐较,依次取舍,直到⽆点可舍去,最后得到满⾜给定精度限差为D的曲线点坐标具体的实现过程如下图(此图来⾃于⽹络)在计算最⼤距离的时候(垂距),⼀般来讲,我们知道三个点的坐标,两个坐标点形成得直线,求另⼀个坐标点到此直线的距离。
道格拉斯普克算法代码
道格拉斯普克算法代码道格拉斯-普克(Douglas-Peucker)算法是一种用于曲线简化的算法,常用于GIS(地理信息系统)数据压缩。
这个算法的主要思想是在曲线上选择一个点,使得以该点为分割点的两段曲线的误差最小。
以下是一个简单的Python实现:```pythonimport numpy as npdef douglas_peucker(points, epsilon):# 获取点的数量n = len(points)# 如果只包含一个点,直接返回该点if n <= 1:return points# 初始化最大距离为无穷大max_dist = float('inf')# 初始化最大距离点为第一个点max_point = points[0]# 遍历所有点,计算与第一个点的距离for i in range(1, n):x = points[i] - points[0]dist = np.sqrt(x[0]**2 + x[1]**2)if dist > max_dist:max_dist = distmax_point = points[i]# 如果最大距离小于epsilon,直接返回第一个点if max_dist < epsilon:return [points[0]]else:# 使用递归对第一段曲线和第二段曲线进行道格拉斯-普克算法处理first_segment = douglas_peucker(points[:max_point+1], epsilon)second_segment =douglas_peucker(points[max_point+1:], epsilon)return first_segment + second_segment[1:] # 忽略最后一个点,因为它与第一段曲线最后一个点重合```在这个代码中,`points`是一个二维numpy数组,表示一系列的点。
Douglas-Peucker轨迹压缩算法
对于一般路径而言,Douglas-Peucker算法是有效的,但是不难想到,当出现折返路径时,往外突出的部分很容易被压缩掉,因为偏差是以 垂直距离为准的。下面的图片展示了这种情况下的压缩效果。
对于一般路径而言douglaspeucker算法是有效的但是不难想到当出现折返路径时往外突出的部分很容易被压缩掉因为偏差是以垂直距离为准的
Douglas-Peucker轨 迹 压 缩 算 法
算法的基本思路是: 对每一条曲线的首末点虚连一条直线,求所有点与直线的距离,并找出最大距离值dmax ,用dmax与限差D相比: 若dmax <D,这条曲线上的中间点全部舍去; 若dmax ≥D,保留dmax 对重复使用该方法。
矢量数据和栅格数据压缩方法
矢量数据和栅格数据压缩方法嘿,咱今儿个就来唠唠矢量数据和栅格数据压缩方法。
你说这数据啊,就跟咱过日子似的,有时候东西多了就得想法子归置归置,不然多占地方呀!矢量数据呢,就好比是一群有规矩的小伙伴,它们都有着明确的位置和方向。
那要怎么给它们压缩呢?就好像我们整理衣柜,把相似的衣服放在一起,节省空间。
一种常见的方法就是道格拉斯-普克算法,这就像是把那些不太重要的细节给忽略掉,只留下关键的部分,这不就省地方了嘛!还有一种叫垂距限值法,就好像给这些小伙伴划定一个范围,超出范围的就不管啦,也能达到压缩的效果呢。
再说说栅格数据,它就像是一张大拼图。
那怎么给这张大拼图压缩呢?可以用游程编码呀,把连续相同的部分用一个简单的方式表示,这不就相当于把一大串重复的东西简化了嘛!还有四叉树编码,就像是把这张大拼图不断地分成小块,只关注那些重要的小块,其他的就先放一边,多聪明的办法呀!你想想看,要是没有这些压缩方法,那数据得占多大地方呀!就像家里东西堆得乱七八糟,找啥都不方便。
有了这些方法,就像是给数据来了一次大整理,让它们变得井井有条。
矢量数据和栅格数据压缩方法可不简单是技术问题哦,它们关系到我们处理数据的效率和成本呢。
要是不压缩,那存储和传输都得花费好多力气和资源。
但有了这些巧妙的方法,就像是给数据穿上了瘦身衣,变得小巧玲珑,多好呀!咱平时用手机、电脑,不也希望它们运行得快一点,别占太多空间嘛。
这矢量数据和栅格数据压缩方法就是背后的功臣呀!它们让我们能更轻松地处理和利用数据,就像给我们的生活加了一把助力。
所以说呀,可别小看了这些压缩方法,它们就像隐藏在数据世界里的小精灵,默默地为我们服务呢!你说是不是呀?它们让我们的数据世界变得更加有序、高效,让我们能更好地利用这些宝贵的数据资源。
总之呢,矢量数据和栅格数据压缩方法真的很重要,它们是数据处理领域不可或缺的一部分。
我们得好好了解它们,利用它们,让我们的数字生活更加美好呀!。
道格拉斯-普克抽稀算法《转》
道格拉斯-普克抽稀算法《转》1、抽稀通俗点讲,直接举个栗⼦吧:我们知道运动轨迹实际上是由很多个经纬度坐标连接⽽成。
那么我们是否需要将所有运动时记录下来的经纬度坐标都⽤来绘制轨迹呢?其实是没必要的,很多数据其实是多余的,实际上将这些多余的数据剔除仍然能保证轨迹曲线形状⼤致不变,⽽且还能让曲线更平滑更节省存储空间,类似这样的过程我们就称之为抽稀。
抽稀的算法很多,这⾥将介绍⼀种经典的算法:道格拉斯-普克(Douglas-Peuker)算法。
2、道格拉斯-普克(Douglas-Peuker)算法还是举个栗⼦吧,假设在平⾯坐标系上有⼀条由N个坐标点组成的曲线,已设定⼀个阈值epsilon。
(1)⾸先,将起始点与结束点⽤直线连接,再找出到该直线的距离最⼤,同时⼜⼤于阈值epsilon的点并记录下该点的位置(这⾥暂且称其为最⼤阈值点),如图所⽰:(2)接着,以该点为分界点,将整条曲线分割成两段(这⾥暂且称之为左曲线和右曲线),将这两段曲线想象成独⽴的曲线然后重复操作(1),找出两边的最⼤阈值点,如图所⽰:(3)最后,重复操作(2)(1)直⾄再也找不到最⼤阈值点为⽌,然后将所有最⼤阈值点按顺序连接起来便可以得到⼀条更简化的,更平滑的,与原曲线⼗分近似的曲线,如图所⽰:代码实现先计算出距离开始、结束点距离最⼤的点。
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);}}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;}。
python 道格拉斯算法-概述说明以及解释
python 道格拉斯算法-概述说明以及解释1.引言【1.1 概述】道格拉斯算法,又称为Ramer-Douglas-Peucker算法,是一种用于抽稀曲线的算法。
在计算机图形学和地理信息系统中得到广泛应用。
该算法通过在曲线上删除冗余点来减少数据量,同时保持曲线的形状特征。
本文将深入介绍道格拉斯算法的原理和应用场景。
随着数据的不断增长,曲线数据的处理变得日益重要。
在许多情况下,我们需要将复杂的曲线数据简化为更简洁的形式,以减少数据存储和处理的开销。
这时,道格拉斯算法的作用就显得尤为重要。
道格拉斯算法的核心思想是通过逐步删除冗余点来实现曲线简化。
该算法通过计算每个点到曲线的垂直距离,选取距离最远的点作为关键点,并将曲线划分为两个较小的子曲线。
然后,在两个子曲线上递归地应用同样的过程,直到满足预设的简化误差要求为止。
最终,算法将保留一系列关键点,这些点能够尽可能准确地代表原始曲线的形状。
道格拉斯算法的应用非常广泛。
在地理信息系统中,该算法常被用于简化地图的边界线或路网数据,以减少存储和传输的开销。
在计算机图形学中,道格拉斯算法可以用于简化曲线的绘制,提高图形渲染的效率。
此外,道格拉斯算法还可以应用于数据压缩、图像处理和轨迹分析等领域。
本文将在下文中逐步介绍道格拉斯算法的具体原理和应用案例。
通过深入了解道格拉斯算法,读者将能够更好地理解和应用该算法来处理曲线数据,实现更高效的数据处理和可视化。
接下来,我们将详细介绍本文的结构和目的。
1.2文章结构1.2 文章结构本文将按照以下结构来进行论述道格拉斯算法的相关内容。
1. 引言:首先对本文的主题进行简要介绍和概述,解释道格拉斯算法的基本概念和作用,引发读者的兴趣和注意。
2. 正文:2.1 道格拉斯算法介绍:对道格拉斯算法进行详细的介绍,包括算法原理、基本步骤和关键思想。
通过对算法的解析,读者将能够深入了解算法的运行机制和优缺点。
2.2 道格拉斯算法的应用:介绍道格拉斯算法在实际场景中的应用,包括图像处理、地理信息系统等领域。
Douglas_Peucker算法在无拓扑矢量数据压缩中的新改进
第27卷第1期 计算机应用与软件Vol 127No .12010年1月 Computer App licati ons and Soft w are Jan .2010D ougl a s 2Peucker 算法在无拓扑矢量数据压缩中的新改进谢亦才1 林渝淇2 李 岩1,31(华南师范大学计算机学院 广东广州510631)2(四川大学软件学院 四川成都610207)3(华南师范大学空间信息研究中心 广东广州510631)收稿日期:2008-07-31。
广东省百项工程项目(2005B30801006)。
谢亦才,硕士生,主研领域:图形图像处理,空间信息处理。
摘 要 分析常规Douglas 2Peucker 算法压缩无拓扑矢量数据时产生公共边“裂缝”现象的原因———公共边被两次或可能更多次压缩,而每次运用Douglas 2Peucker 算法压缩时所选择的初始点和终点不同造成的。
为此,提出公共边对象化Douglas 2Peucker 改进算法。
为实现此算法,首先设计了新的公共边提取算法来提取公共边,然后使用OOP 技术,把公共边的相关信息封装成类,最后根据公共边对象提供的信息对多边形的公共边和非公共边分别进行Douglas 2Peucker 压缩。
以广东省行政界线的S VG 矢量图为实验对象验证了此算法的有效性,分析了本算法相对于其它Douglas 2Peucker 改进算法在所需辅助空间和时间效率上的优势。
关键词 Douglas 2Peucker 算法 矢量数据压缩 S VG 公共边对象化Douglas 2Peucker 改进算法NE W IM PRO VE M ENT O F DO UGLAS 2PEUCKER AL GO R I TH M I N NO N 2TO POLO GYVECTO R DATA COM PRESS IO NXie Yicai 1 L in Yuqi 2 L i Yan1,31(School of Co m puter ,South China N or m al U niversity,Guangzhou 510631,Guangdong,China )2(College of Soft w are Engineering,S ichuan U niversity,Chengdu 610207,S ichuan,China )3(Spatial Infor m ation R esearch Center ,South China N or m al U niversity,Guangzhou 510631,Guangdong,China )Abstract The article analysed the reas on of crack phenomenon on common boundary of graphicswhen comp ressing the non 2t opol ogy vect or graphics by conventi onal Douglas 2Peucker algorith m 2the common boundary m ight be comp ressed t w ice or more,whiles each comp ressi on with Douglas 2Peucker algorith m selects different initial and end points .Theref ore,an i m p r oved Douglas 2Peucker algorith m t o objectify the common boundary is put for ward .To i m p le ment it,first,we design a ne w algorith m t o extract the common boundaries bet w een t w o polygons .Then we a 2dop t OOP technol ogy t o encap sulate the inf or mati on with regard t o common boundaries t o a class .And at last,on the basis of the class,we ap 2p ly conventi onal Douglas 2Peucker comp ressi on t o vect or graphics of the common boundary and non 2common boundary of the polygons res pec 2tively according t o the infor mati on p r ovided by common boundary object .The validity of the ne w comp ressing algorith m is p r oved in an experi 2ment with S VG vect or graphics of the ad m inistrative boundary of Guangdong Pr ovince .And the advantages in auxiliary s pace and ti m e efficien 2cy this algorith m possesses is analysed in contrasting with other i m p r oved Douglas 2Peucker algorith m s .Keywords Douglas 2Peucker algorith m Vect or data comp ressing Scalable vect or graphics (S VG ) I m p r oved Douglas 2Peucker algorith m for objectifying the common boundary0 引 言随着W ebGI S 的迅速发展,海量空间数据在目前带宽有限的网络上的传输速度慢的问题越来越突出,因此有必要对空间数据进行压缩。
道格拉斯—普克法(Douglas—Peucker)简化线算法报告
道格拉斯—普克法(Douglas—Peucker)简化线算法报告线简化算法程序设计报告⽮量数据是GIS中,使⽤⾮常普遍的⼀种数据类型。
在使⽤中,有时需要对⽮量数据进⾏压缩,⽮量数据压缩的⽬的是删除冗余数据,减少数据的存贮量,节省存贮空间,加快后继处理的速度。
⽮量数据的压缩⽅法常⽤的有道格拉斯—普克法、垂距法、光栏法。
本⽂主要讨论道格拉斯—普克法,运⽤该算法的思想,⽤C语⾔于TC20中编写⼀个⼩程序,实现对既有线的简化。
⾸先,简要介绍下道格拉斯—普克法(Douglas—Peucker)的核⼼思想:基本思路(如图1):对每⼀条曲线的⾸末端点连⼀条线,求所有点到该直线的距离,并找出最⼤距离值dmax,⽤dmax与限差D相⽐:(1)若dmax<D,这条曲线上的中间点全部舍去;(2)若dmax≥D,保留dmax对应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使⽤该⽅法。
图1由该算法的基本思路可知,该算法是递归的,⽽且算法的核⼼是求得点到直线的距离。
根据以上分析,结合⽼师给出的数据,编写出了程序代码。
经过调试,能实现线简化的功能。
使⽤TC20做为程序的开发环境,主程序流程图如下所⽰:该算法的主要功能函数是Simp(),该函数的功能是根据输⼊的限差LimitDis 确定线上的点是保留还是去除。
Simp()函数的实现思想是,将曲线上的各点与曲线的端点连接,组成⼀个三⾓形,如下:先根据点到点的距离公式,求出a,b,c 的值。
然后再应⽤余弦公式cosA=(b*b+c*c-a*a)/(2*b*c);cosB=(a*a+c*c-b*b)/(2*a*c);sinA=(float)sqrt(1-co sA*cosA);再根据cosA ,cosB ,sinA 的值,算出距离。
对每个点进⾏上述的计算,求出每个点到AB 的距离,取最⼤值和LimitDis ⽐较,如果⼤于限差,那么从C 点将曲线分为⼆段,重复第⼀步。
如果⼩于,则去除AB 间的所有点。
lesson08-数据压缩与综合
算法如nt,int*PointNum,int beginNum,int endNum,double D) { if(已经没有中间点) 返回: else { for(首末两点之间的点) { 求垂距; 寻找最大值点; } if(如果最大距离仍小于阈值) {舍弃其中的所有点;返回;} else { 以最大值点为界,分为两段直线L1,L2。 对L1,L2分别调用CharaFilter()函数继续压缩 } } }
……在规定的精度 范围内最好地逼近 ① 原集合…… 垂距法
② 光栏法
10405个数据点 个数据点
6.2.2 用的线压缩算法 ①垂距法 垂距法 算 法 思 路
在给定的曲线上每 次顺序取三个点, 计算中间点与其它 两点连线的垂距d, 并与限差L比较。 d ≥L 保留中间点 d<L 舍去中间点 d2>L d3<L d4>L P1
6.1 什么是矢量数据压缩
又称为数据化简,是指从所取得的数据集合中抽出一 压缩比:表示曲线信息载负量减少的程度。 设曲线的原点序A: 设曲线的原点序A: A1 , A2 , A3 ,......Am 能够用尽可能少的数据量, 个子集,这个子集作为一个新的信息源, ③
经过压缩处理后的点序为As: 经过压缩处理后的点序为As: As 1 , As 2 , As 3 ,......A ① 在规定的精度范围内,② 最好地逼近原集合。 sn m α = , α≥1 则压缩比α为: 则压缩比α n
在上述的算法中,采用了递归的方法。其中Point指针指向的是曲线的点 集,PointNum表示曲线的点数,而begionNum,endNum分别为每次所得的曲线的首 末点,D是限差。
垂距法
光栏法
道格拉斯—普克法
优 点: 点:可以有效保留线划上的特征点,精度高。 缺 点: 点:计算量较大,有时会产生自相交的情况。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
道格拉斯普克压缩算法
#include <algorithm>
using namespace std;
struct FromTo
{
int from;
int to;
};
vector DouglasPeuckerDataCompress(vector pts,double tolerance) {
double distance = 0;
int nStart = 0;
int nEnd = pts.size()-1;
int numPt = 0;
bool flag = true;
FromTo from_to;
vector Stack;
vector numPoints;
numPoints.push_back(0);
do
{
distance = GetMaxArcLength(pts,nStart,nEnd,numPt);
if (distance > tolerance)
{
numPoints.push_back(numPt);
from_to.from = numPt;
from_to.to = nEnd;
Stack.push_back(from_to);
nEnd = numPt;
}
else
{
if (Stack.empty())
flag = false;
else
{
from_to = Stack[Stack.size()-1];
nStart = from_to.from;
nEnd = from_to.to;
Stack.erase(Stack.end()-1);
}
}
} while(flag);
numPoints.push_back(pts.size()-1);
vector pnts;
for (int i = 0; i != pts.size(); ++i)
{
if (find(numPoints.begin(),numPoints.end(),i) != numPoints.end()) pnts.push_back(pts[i]);
}
return pnts;
}
double GetMaxArcLength(vector pts,int nStart,int nEnd,int& numPoint) {
double maxLength = 0;
double distance = 0;
for (int i = nStart+1; i != nEnd; ++i)
{
distance = DistancePointToLine(pts[i],pts[nStart],pts[nEnd]);
if (distance > maxLength)
{
maxLength = distance;
numPoint = i;
}
}
return maxLength;
}
double DistancePointToLine(pointD pt,pointD pt1,pointD pt2)
{
if (!DoubleEqual(pt1.x,pt2.x)) //不垂直
{
double k1 = (pt2.y - pt1.y)/(pt2.x - pt1.x);
double b1 = pt2.y - pt2.x * k1;
if (!DoubleEqual(0,k1))
{
double k2 = (-1)/k1;
double b2 = pt.y - k2 * pt.x;
pointD pt3;
pt3.x = (b2 - b1)/(k1 - k2);
pt3.y = pt3.x * k1 + b1;
return GetDistance(pt,pt3); }
else //直线水平
return fabs(pt.y - pt1.y);
}
else //直线垂直
return fabs(pt2.x - pt.x);
}。