分治算法求解凸包问题
#include <iostream>#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
// 定义点的结构体
struct Point {
int x, y;
};
// 计算点P到直线AB的距离
double distanceToLine(const Point& A, const Point& B, const Point& P) {
return abs((B.x - A.x) * (A.y - P.y) - (A.x - P.x) * (B.y - A.y)) /
sqrt(pow(B.x - A.x, 2) + pow(B.y - A.y, 2));
}
// 计算叉积,判断点C在向量AB的右侧、左侧或共线
int crossProduct(const Point& A, const Point& B, const Point& C) {
return (B.x - A.x) * (C.y - B.y) - (B.y - A.y) * (C.x - B.x);
}
// 判断点C是否在向量AB的右侧
bool isRightOf(const Point& A, const Point& B, const Point& C) {
return crossProduct(A, B, C) < 0;
}
// 快速凸包算法的部分实现
vector<Point> quick_half_hull(vector<Point>& S, const Point& a, const Point& b) {
if (S.empty()) return {};
double maxDist = -1;
Point c;
for (const auto& point : S) {
double dist = distanceToLine(a, b, point);
if (dist > maxDist) {
maxDist = dist;
c = point;
}
}
vector<Point> A, B;
// 筛选出右侧的点集A和B
for (const auto& point : S) {
if (isRightOf(b, c, point)) {
A.push_back(point);
}
else if (isRightOf(c, a, point)) {
B.push_back(point);
}
}
vector<Point> QA = quick_half_hull(A, a, c);
vector<Point> QB = quick_half_hull(B, c, b);
vector<Point> result;
result.insert(result.end(), QA.begin(), QA.end());
result.push_back(c);
result.insert(result.end(), QB.begin(), QB.end());
return result;
}
vector<Point> quick_hull(vector<Point>& S) {
if (S.size() < 3) return S;
// 寻找极端点a和b
sort(S.begin(), S.end(), [](const Point& p1, const Point& p2) {
return (p1.x < p2.x) || (p1.x == p2.x && p1.y < p2.y);
});
Point a = S;
Point b = S;
vector<Point> A, B;
// 筛选出右侧的点集A和B
for (const auto& point : S) {
if (isRightOf(b, a, point)) {
A.push_back(point);
}
else if (isRightOf(a, b, point)) {
B.push_back(point);
}
}
vector<Point> QA = quick_half_hull(A, a, b);
vector<Point> QB = quick_half_hull(B, b, a);
vector<Point> result;
result.push_back(a);
result.insert(result.end(), QA.begin(), QA.end());
result.push_back(b);
result.insert(result.end(), QB.begin(), QB.end());
return result;
}
int main() {
// 示例点集
vector<Point> points = { {0, 0}, {4, 4}, {4, 0}, {0, 4}, {3, 3} ,{3,1},{2,1},{1,2},{3,2},{4,3},{2,4} ,{0,2},{0,5} };
// 调用凸包算法
vector<Point> result = quick_hull(points);
// 输出凸包顶点
cout << "Convex Hull Points:\n";
for (const auto& point : result) {
cout << "(" << point.x << ", " << point.y << ")\n";
}
return 0;
}
页:
[1]