**算法思想 : **
寻找凸包这里演示打包法,有一种更优的Graham扫描法,以后有时间再更.
程序源码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;
typedef pair<double, double> POINT;
POINT startPoint;
double direction(POINT p, POINT p1, POINT p2)
{
//函数返回p -p1 向量 与 p -p2向量的叉积
//如果为正则说明 line1 逆时针旋转到 line2 即 p1大
POINT line1,line2;
line1.first = p1.first - p.first;
line1.second = p1.second - p.second;
line2.first = p2.first - p.first;
line2.second = p2.second - p.second;
return line1.first * line2.second - line2.first * line1.second;
}
bool on_segment(POINT p, POINT p1, POINT p2)
{
//判断点p1是否在直线p - p2上
double min_x = p.first < p2.first ? p.first : p2.first;
double min_y = p.second < p2.second ? p.second : p2.second;
double max_x = p.first > p2.first ? p.first : p2.first;
double max_y = p.second > p2.second ? p.second : p2.second;
if(p1.first <= max_x && p1.first >= min_x
&& p1.second <= max_y && p1.second >= min_y)
{
return true;
}
return false;
}
bool sortByPolorAngle(POINT p1, POINT p2)
{
//快速排序用到的规则 判断点p1是否比p2大
if(direction(startPoint, p1, p2) > 0) return true;
if(direction(startPoint, p1, p2) < 0) return false;
if(direction(startPoint, p1, p2) == 0 && on_segment(startPoint, p1, p2)) return false;
if(direction(startPoint, p1, p2) == 0 && on_segment(startPoint, p2, p1)) return true;
}
void find_convex_hull(vector<POINT> & point)
{
vector<POINT> convexHull;//存放凸包里的点
POINT p0 = point[0];
int k = 0;
for(int i = 1; i < point.size(); i++)
{
if(point[i].second < p0.second || (point[i].second == p0.second && point[i].first < p0.first))
{
p0 = point[i];
k = i;
}
}//for循环找到最下方的点
convexHull.push_back(p0);//将p0放入凸包
point.erase(point.begin() + k);//将p0从point中移除
while(1)
{
startPoint = convexHull.back();//获得起始点
sort(point.begin(), point.end(), sortByPolorAngle);//将point里的点按点的大小排序
point.push_back(convexHull.back());//将point里删掉的点重新放入凸包
if(point[0] == convexHull[0]) break;//如果最大的点和起点重合循环结束
convexHull.push_back(point[0]);//最大的点放入凸包
point.erase(point.begin());//将最大的点从凸包移除
}
cout << endl << "The convex hull contains : " ;//凸包里的点进行打印
for(int i = 0; i < convexHull.size(); i++){
cout << "(" << convexHull[i].first << "," << convexHull[i].second << ")" << " ";
}
cout << endl;
}
int main()
{
vector<POINT> point;
POINT tmp;
int n;
char c;
cout << "Please input the number of points : ";
cin >> n;
cout << endl;
cout << "Please input the points : ";
for(int i = 0; i < n; i++)
{
cin >> tmp.first >> c >> tmp.second;
point.push_back(tmp);
}
find_convex_hull(point);
return 0;
}
运行截图