C++ 道格拉斯-普克(DP)算法

道格拉斯-普克算法(Douglas–Peucker algorithm,亦称为拉默-道格拉斯-普克算法、迭代适应点算法、分裂与合并算法)是将曲线近似表示为一系列点,并减少点的数量的一种算法。该算法的原始类型分别由乌尔斯·拉默(Urs Ramer)于1972年以及大卫·道格拉斯(David Douglas)和托马斯·普克(Thomas Peucker)于1973年提出,并在之后的数十年中由其他学者予以完善。

算法的基本思路是:对每一条曲线的首末点虚连一条直线,求所有点与直线的距离,并找出最大距离值dmax ,用dmax与限差D相比:若dmax <D,这条曲线上的中间点全部舍去;若dmax ≥D,保留dmax 对应的坐标点,并以该点为界,把曲线分为两部分,对这两部分重复使用该方法。

 

// DP.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "iostream"
#include "fstream"
#include "string"
#include "vector"
#include "cmath"
#include 

using namespace std;

class Point
{
public:
	int ID;
	string Name;
	double x;
	double y;
	bool isRemoved = false;


};

double PointToLine(Point p1, Point p2, Point p3)
{
	double dist;
	double A, B, C;
	A = -(p2.y - p1.y) / (p2.x - p1.x);
	B = 1.0;
	C = -A * p1.x - p1.y;
	dist = abs(A * p3.x + B * p3.y + C) / sqrt(A * A + B * B);
	return dist;
}

double getMaxDist(vector &Points, int begin, int end)
{
	vector dists;
	double maxdist;
	for (int i = begin; i <= end; i++)
	{
		dists.push_back(PointToLine(Points[begin], Points[end], Points[i]));
	}
	auto max = max_element(dists.begin(), dists.end());
	return *max;
}

int getMaxDistIndex(vector &Points, int begin, int end)
{
	vector dists;
	int index;
	for (int i = begin; i <= end; i++)
	{
		dists.push_back(PointToLine(Points[begin], Points[end], Points[i]));
	}
	auto max = max_element(dists.begin(), dists.end());
	index = Points[begin].ID + distance(dists.begin(),max);
	return index;
}

void DP(vector &Points, int begin, int end, double threshold)
{
	int mid;
	if (end - begin > 1)
	{
		if (getMaxDist(Points, begin, end) > threshold)
		{
			mid = getMaxDistIndex(Points, begin, end);
			DP(Points, begin, mid, threshold);
			DP(Points, mid, end, threshold);
		}
		else
		{
			for (int i = begin + 1; i < end; i++)
			{
				Points[i].isRemoved = true;
			}
		}
	}
	else
	{
		return;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	

	ifstream file;
	ofstream out;
	string line;


	vector points1;
	vector points2;


	file.open("轨迹数据.txt");
	if (!file.is_open())
	{
		cout << "The file doesn't exist!" << endl;
		system("Pause");
		exit(1);
	}
	Point point;
	int count = 0;
	cout << "raw data" << endl;
	while (!file.eof())
	{
		getline(file, line);
		char *cstr = new char[line.length() + 1];
		strcpy(cstr, line.c_str());
		char *p = strtok(cstr, ",");
		point.Name = p; p = strtok(NULL, ",");
		point.x = atof(p); p = strtok(NULL, ",");
		point.y = atof(p); point.ID = count++;
		points1.push_back(point);
		points2.push_back(point);
		cout << point.Name << "," << point.x << "," << point.y << "\n";
	}


	DP(points1, 0, 16, 5.0);
	DP(points2, 0, 16, 8.0);

	cout << "\n\nthreshold=5.0" << endl;
	for (int i = 0; i < points1.size();i++)
	{
		if (points1[i].isRemoved==false)
		{
			cout << points1[i].Name << "," << points1[i].x << "," << points1[i].y << "\n";
		}
	}
	cout << "\n\nthreshold=8.0" << endl;
	for (int i = 0; i < points2.size(); i++)
	{
		if (points2[i].isRemoved == false)
		{
			cout << points2[i].Name << "," << points2[i].x << "," << points2[i].y << "\n";
		}
	}
	return 0;
}

C++ 道格拉斯-普克(DP)算法_第1张图片

你可能感兴趣的:(C++)