演示截图:
//蛮力法求凸包问题
#include<iostream>
#include<vector>
#include<algorithm>
#include<conio.h>
#include<map>
#include<graphics.h>
using namespace std;
const int maxn = 1e4 + 15;
const double eps = 1e-8;
struct Point {
double x;
double y;
};
vector<pair<double, double> > convexHull(vector<pair<double, double> >& point, int n) {
vector<pair<double, double> > pointPairVec;
if (n <= 2)
return point;
//扫描每个点
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
double a = point[j].second - point[i].second;
double b = point[i].first - point[j].first;
double c = point[i].first * point[j].second - point[i].second * point[j].first;
vector<pair<double, double> > signEqualVec;
signEqualVec.push_back(point[i]);
signEqualVec.push_back(point[j]);
int sign1 = 0, sign2 = 0; //记录直线两边的点
//扫描直线外的所有的点
for (int k = 0; k < n; k++) {
if (k == i || k == j)
continue;
else {
double sign = a * point[k].first + b * point[k].second - c;
if (sign == 0)
signEqualVec.push_back(point[k]);
else if (sign > 0)
sign1++;
else if (sign < 0)
sign2++;
}
}
if (sign1 > 0 && sign2 > 0)
continue;
else {
for (int l = 0; l < signEqualVec.size(); l++)
pointPairVec.push_back(signEqualVec[l]);
}
}
}
return pointPairVec;
}
//点点,将所有点画在坐标轴上
void drow_graph(vector<pair<double, double> >& point, int n) {
initgraph(800, 800); //画布大小
setbkcolor(WHITE);
cleardevice();
setlinecolor(BLUE);
line(400, 0, 400, 800); //制作横纵坐标轴
line(0, 400, 800, 400); //此时理论原点为画布中(400, 400)
for (int i = 0; i < n; i++) {
setfillcolor(RED);
double x = point[i].first + 400;
double y = 400 - point[i].second;
fillcircle(x, y, 5);
}
}
//连线,将点对连接起来
void connect_end(Point* point, int n) {
setlinecolor(RED);
setlinestyle(10);
for (int i = 0; i < n - 1; i++) {
double x1 = point[i].x + 400;
double y1 = 400 - point[i].y;
double x2 = point[i + 1].x + 400;
double y2 = 400 - point[i + 1].y;
line(x1, y1, x2, y2);
}
double x = point[0].x + 400;
double y = 400 - point[0].y;
double x1 = point[n - 1].x + 400;
double y1 = 400 - point[n - 1].y;
line(x, y, x1, y1);
_getch();
closegraph();
}
Point p[maxn];
int dblcmp(double k) {
if (fabs(k) < eps) return 0;
return k > 0 ? 1 : -1;
}
double multi(Point p0, Point p1, Point p2) {
return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}
bool cmp(const Point& a, const Point& b) {
return dblcmp(multi(p[0], a, b)) > 0;
}
int main()
{
vector<pair<double, double> > pointsArray(maxn);
cout << "请输入点的个数:";
int n; cin >> n;
cout << "请输入点的坐标:" << endl;
for (int i = 0; i < n; i++) {
double x, y; cin >> x >> y;
pointsArray[i] = make_pair(x, y);
}
drow_graph(pointsArray, n);
vector<pair<double, double> > convex = convexHull(pointsArray, n);
map<pair<double, double>, int>mp;
int t = 0;
//打标记,取消重复点
for (int i = 0; i < convex.size(); i++) {
pair<double, double> pa = make_pair(convex[i].first, convex[i].second);
if (mp[pa] == 0) {
p[t].x = convex[i].first;
p[t++].y = convex[i].second;
mp[pa]++;
}
}
sort(p + 1, p + t, cmp);
connect_end(p, t);
return 0;
}