道格拉斯-普克算法(JavaScript实现)
需求:
有时候当移动速度很慢,GPS定位的轨迹点就非常的多,这时候为了缩减数据量,需要将不突出的点去掉。
思路:
(1) 在曲线首尾两点间虚连一条直线,求出其余各点到该直线的距离。

这里使用道格拉斯-普克算法实现,易于理解。效果对比图如下:
源代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>DouglasPeucker</title>
</head>
<body>
<canvas id="drawing" style="height:300px;width:100%"></canvas>
<canvas id="drawing2" style="height:300px;width:100%"></canvas>
</body>
<script type="text/javascript" > var points1=[];
var pointsshao=[];
var pts=[];
var hval=30;//阈值 //随机生成1000个点
for(var i=0;i<1000;i++){
var oldx=i*10,oldy=Math.random()*150;
points1.push([oldx,oldy,i]);
} //求斜率
function xielv(pt1,pt2)
{
var k,b;
var canshu={};
canshu.k=(pt1[1]-pt2[1])/(pt1[0]-pt2[0]);
canshu.b=pt1[1]-canshu.k*pt1[0];
return canshu;
}
//求点到直线的距离
function distanceToline(pt,cs){
return (Math.abs(cs.k*pt[0]-pt[1]+cs.b))/Math.sqrt(cs.k*cs.k+1);
} //开始计算(道格拉斯普克算法)
pts.push(points1[0]);
countPoint(points1);
pts.push(points1[points1.length-1]); //排序
function sort(pts){
for(var i=0;i<pts.length-1;i++)
{
var a=pts[i];
var b=pts[i+1];
if(b[2]>a[2]){
pts[i]=b;
pts[i+1]=a;
for(var j=i;j>0;j--)
{
var c=pts[j-1];
if(b[2]>c[2]){
pts[j-1]=b;
pts[j]=c;
}
}
}
}
}
//对坐标点进行取舍
function countPoint(points){ var maxD=0;
var maxPoint=null;
var maxindex=0;
//大于2个点才开始计算
if(points.length>2){
var pt1=points[0];
var pt2=points[points.length-1];
var cs=xielv(pt1,pt2);
for(var i=0;i<points.length;i++){
var pt=points[i];
var dis=distanceToline(pt,cs);
//判断该线段中是否有点到由该线段端点组成的直线的距离大于限值
if(dis>maxD)
{
maxD=dis;
maxPoint=pt;
maxindex=i;
}
}
if(maxD>hval) //如果最大值就从该点位置将线段进行切分
{
var pts1=points.slice(maxindex);//中分末尾数组
var pts2=points.slice(0,maxindex+1);//中分前面数组
if(pts1.length>2 && pts2.length>2)
{
if(!countPoint(pts1) && !countPoint(pts2)){ //如果两个线段都没有超过限制就结束计算
pts.push(maxPoint);
}
}else if(pts1.length>2 && pts2.length<=2){ //计算pts1
if(!countPoint(pts1))pts.push(maxPoint); }else if(pts1.length<=2 && pts2.length>2){ //计算pts2
if(! countPoint(pts2))pts.push(maxPoint); }
} return false;
}
}
//由大到小
sort(pts);
drawWay("drawing2",pts);
drawWay("drawing",points1)
//绘制曲线
function drawWay(name,points){
var drawing=document.getElementById(name);
if(drawing.getContext){
var context=drawing.getContext("2d");
context.beginPath();
var oldx=points[0][0];
var oldy=points[0][1];
for(var i=0;i<points.length;i++){
var p=points[i];
context.moveTo(oldx,oldy);
oldx=p[0];
oldy=p[1];
context.lineTo(oldx,oldy);
}
context.closePath();
context.stroke();
}
}
</script>
道格拉斯-普克算法(JavaScript实现)的更多相关文章
- OpenCV 学习笔记03 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数
凸形状内部的任意两点的连线都应该在形状里面. 1 道格拉斯-普克算法 Douglas-Peucker algorithm 这个算法在其他文章中讲述的非常详细,此处就详细撰述. 下图是引用维基百科的.ε ...
- GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现
GIS领域的同志都知道,传统的道格拉斯-普克算法都是递归实现.然而有时候递归的层次太深的话会出现栈溢出的情况.在此,介绍一种非递归的算法. 要将递归算法改为非递归算法,一般情况下分为两种场景.第一种是 ...
- 道格拉斯—普克(Douglas一Peukcer)节点抽稀算法
Douglas一Peukcer算法由D.Douglas和T.Peueker于1973年提出,简称D一P算法,是眼下公认的线状要素化简经典算法.现有的线化简算法中,有相当一部分都是在该算法基础上进行改进 ...
- .net中使用 道格拉斯-普特 抽希轨迹点
Douglas一Peukcer算法由D.Douglas和T.Peueker于1973年提出,简称D一P算法,是目前公认的线状要素化简经典算法.现有的线化简算法中,有相当一部分都是在该算法基础上进行改进 ...
- 数据结构与算法JavaScript (一) 栈
序 数据结构与算法JavaScript这本书算是讲解得比较浅显的,优点就是用javascript语言把常用的数据结构给描述了下,书中很多例子来源于常见的一些面试题目,算是与时俱进,业余看了下就顺便记录 ...
- 《数据结构与算法JavaScript描述》
<数据结构与算法JavaScript描述> 基本信息 作者: (美)Michael McMillan 译者: 王群锋 杜欢 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:9 ...
- 翻阅《数据结构与算法javascript描述》--数组篇
导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScript 中的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性 ...
- 数据结构与算法javascript描述
<数据结构与算法javascript描述>--数组篇 导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScri ...
- 列表的实现-----数据结构与算法JavaScript描述 第三章
实现一个列表 script var booklist = new List(); booklist.append('jsbook'); booklist.append('cssbook'); book ...
随机推荐
- 【转载】Windows平台下利用APM来做负载均衡方案 - 负载均衡(下)
概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...
- HDU 1698 Just a Hook 线段树区间更新、
来谈谈自己对延迟标记(lazy标记)的理解吧. lazy标记的主要作用是尽可能的降低时间复杂度. 这样说吧. 如果你不用lazy标记,那么你对于一个区间更新的话是要对其所有的子区间都更新一次,但如果用 ...
- 2018-8-10-使用-RetroShare-分享资源
title author date CreateTime categories 使用 RetroShare 分享资源 lindexi 2018-08-10 19:16:51 +0800 2018-02 ...
- java 集合遍历输出方式
Iterator:迭代输出 一旦操作集合的遍历输出,首选Iterator接口; ListIterator:Iterator子接口,专门输出List中的元素; Enumeration:古老的输出方式,迭 ...
- ERROR 1366 (HY000): Incorrect string value: '\xD5\xC5\xC8\xFD' for column 'name' at row 1
ERROR 1366 (HY000): Incorrect string value: '\xD5\xC5\xC8\xFD' for column 'name' at row 1 数据库字符集问 ...
- 2019-4-12-WPF-绑定的默认模式
title author date CreateTime categories WPF 绑定的默认模式 lindexi 2019-04-12 09:38:58 +0800 2019-04-12 09: ...
- P1017 聪聪排数字
题目描述 今天聪聪收到了n张卡片,他需要给他们从小到大排序. 输入格式 输入的第一行包含一个整数 \(n(1 \le n \le 10^3)\) . 输入的第二行包含 \(n\) 个正整数,以空格间隔 ...
- P1011 圆柱体的表面积
题目描述 输入底面半径 \(r\) 和高 \(h\) ,输出圆柱体的表面积,保留 \(3\) 位小数. 输入格式 输入包含两个实数 \(r,h(1 \le r,h \le 1000)\) 且保证输入的 ...
- H3C配置Header进入用户视图的提示信息--系统视图
incoming:登录终端用户界面时的提示信息. Header 3种类型 login:登录验证时的提示信息. Vty模式 ...
- springboot-aop日志打印
package com.cinc.ecmp.client; import com.cinc.ecmp.enums.BackResultEnum; import com.cinc.ecmp.except ...