FindSmallestPolygon


#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include "GenMif.h"

using namespace std;

POINT_STRU FindStartPoint(vector<POINT_STRU> points)
{
POINT_STRU point = points[0];
for (size_t i = 1; i < points.size(); i++)
{
if (points[i].Lower(point))
{
point = points[i];
}
}
return point;
}

int FindNextPoint(vector<POINT_STRU> points, vector<int> searched, POINT_STRU start, double& bottomAngle)
{
double localMinAngle = 2 * PI;
double angle = 2 * PI;
int stopIdx = -1;
for (size_t i = 0; i < points.size(); i++)
{
if (searched[i])
{
continue;
}
angle = start.GetAngle(points[i]); // if self, got 2 * PI
//cout << "Start: " << start.x << ", " << start.y << " stop: " << points[i].x << ", " << points[i].y << " -- " << angle * 180 / PI << endl;
if ((angle <= localMinAngle) && ( angle >= bottomAngle) ) // 防 0
{
localMinAngle = angle;
stopIdx = i;
}
}
bottomAngle = localMinAngle;
//cout << points.size() << " " << stopIdx << "localMinAngle: " << localMinAngle * 180 / PI << "bottomAngle: " << bottomAngle * 180 / PI << endl;
return stopIdx;
}

void GenCycle(POINT_STRU center, vector<POINT_STRU>& cycle, double radius, int count)
{
double delta = 2 * PI / count;
for (double angle = 0; angle <= 2 * PI; angle+=delta)
{
POINT_STRU edge;
edge.x = center.x + radius * cos(angle);
edge.y = center.y + radius * sin(angle);
cycle.push_back(edge);
}
return;
}

bool FindSmallestPolygon(vector<POINT_STRU> orig, vector<POINT_STRU>& boundary)
{
vector<int> searched(orig.size());
POINT_STRU startPoint = FindStartPoint(orig);
//cout << startPoint.x << ", " << startPoint.y << endl;
boundary.push_back(startPoint);
int nextIdx;
double minAngle = 0.0;
nextIdx = FindNextPoint(orig, searched, startPoint, minAngle);
while( !orig[nextIdx].Equals(startPoint) )
{
if (nextIdx < 0)
{
return false;
}
boundary.push_back(orig[nextIdx]);
searched[nextIdx] = 1;
//cout << orig[nextIdx].x << ", " << orig[nextIdx].y << endl;
nextIdx = FindNextPoint(orig, searched, orig[nextIdx], minAngle);
}
return true;
}

int CMifObject::count = 0;

CMifObject::CMifObject()
{
header << "Version 300\n"
<< "Charset \"WindowsSimpChinese\"\n"
<< "Delimiter \",\"\n"
<< "CoordSys Earth Projection 1, 0\n"
<< "Columns 2\n"
<< "Lon Float\n"
<< "Lat Float\n"
<< "Data\n";
content << header.str();
}

string CMifObject::getContent()
{
return content.str();
}

/*
0 - 2 pi
cout << "0.0, 0.0 " << GetAngle(0.0, 0.0) << "\n";
cout << "1.0, 0.0 " << GetAngle(1.0, 0.0) << "\n";
cout << "1.0, 1.0 " << GetAngle(1.0, 1.0) << "\n";
cout << "0.0, 1.0 " << GetAngle(0.0, 1.0) << "\n";
cout << "-1.0, 1.0 " << GetAngle(-1.0, 1.0) << "\n";
cout << "-1.0, 0.0 " << GetAngle(-1.0, 0.0) << "\n";
cout << "-1.0, -1.0 " << GetAngle(-1.0, -1.0) << "\n";
cout << "0.0, -1.0 " << GetAngle(0.0, -1.0) << "\n";
cout << "1.0, -1.0 " << GetAngle(1.0, -1.0) << "\n";
*/

void CMifObject::AddRegion(std::vector<POINT_STRU> coords)
{
ostringstream ostr;
ostr << "Region 1\n"
<< " " << coords.size() << "\n" ;
for(size_t i = 0; i < coords.size(); i++)
{
ostr << coords[i].x << " " << coords[i].y << "\n";
}
content << ostr.str();
}

bool CMifObject::toFile(string filename)
{
ofstream fout;
fout.open(filename, ios::out);
fout << content.str();
fout.close();
return true;
}


#include <string>
#include <sstream>
#include <iostream>
#include <vector>

#include "MathUtil.h"

using namespace std;

POINT_STRU FindStartPoint(vector<POINT_STRU> points);
int FindNextPoint(vector<POINT_STRU> points, vector<int> searched, POINT_STRU start, double& bottomAngle);

void GenCycle(POINT_STRU center, vector<POINT_STRU>& cycle, double radius, int count);
bool FindSmallestPolygon(vector<POINT_STRU> orig, vector<POINT_STRU>& boundary);

class CMifObject
{
public:
CMifObject();
void AddRegion(std::vector<POINT_STRU> coords);
string getContent();
bool toFile(string filename);
private:
ostringstream header;
ostringstream content;
static int count;
};


#include <cmath>

const double PRECISION = 0.000000000000001;
const double PI = 3.1415926535;

bool IsZero(double value);

typedef struct POINT_STRU
{
double x;
double y;

POINT_STRU()
{

x = 0.0;
y = 0.0;
}
POINT_STRU(double x0, double y0)
{
x = x0;
y = y0;
}
bool Equals(POINT_STRU point)
{
return IsZero(x - point.x) && IsZero(y - point.y);
}
double GetAngle(POINT_STRU point)
{
if (Equals(point))
{
return 2 * PI;
}
double deltaX = point.x - x;
double deltaY = point.y - y;
if (IsZero(deltaY))
{
return deltaX > 0 ? 0 : PI;
}
double dist = sqrt(deltaX * deltaX + deltaY * deltaY);
double angle = acos(deltaX / dist);
return deltaY > 0 ? angle : ( 2 * PI - angle);
}
bool Lower(POINT_STRU point)
{
return (y < point.y) || ((point.y == y) && (x < point.x));
}
}POINT_STRU;


#include "GenMif.h"
#include <vector>
using namespace std;

int main()
{
vector<POINT_STRU> orig;
orig.push_back(POINT_STRU(1.1, 1.1));
orig.push_back(POINT_STRU(5.1, 5.1));
orig.push_back(POINT_STRU(1.1, 5.1));
//orig.push_back(POINT_STRU(2.1, 3.1));
orig.push_back(POINT_STRU(5.1, 1.1));
//orig.push_back(POINT_STRU(-1.1, 3.1));
//orig.push_back(POINT_STRU(1.1, 0.1));

double radius = 1.0;
int pointsOfCycle = 50;

vector<POINT_STRU> expand;
CMifObject* tt = new CMifObject();
for (size_t i = 0; i < orig.size(); i ++)
{
GenCycle(orig[i], expand, radius, pointsOfCycle);
}
vector<POINT_STRU> boundary;
bool res = FindSmallestPolygon(expand, boundary);
//tt->AddRegion(orig);
//tt->AddRegion(expand);
tt->AddRegion(boundary);
tt->toFile("C:\\Users\\ywx193642\\Desktop\\output\\boundaryTest.mif");
return 0;
}

FindSmallestPolygon

时间: 2024-09-21 03:25:01

FindSmallestPolygon的相关文章