#include
#include
#include
#include
struct Point {
int x, y;
bool operator<(const Point& p) const {
return x < p.x || (x == p.x && y < p.y);
}
};
// 计算两个点之间的斜率
int orientation(const Point &p, const Point &q, const Point &r) {
int val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
if (val == 0) return 0; // 共线
return (val > 0) ? 1 : 2; // 逆时针或顺时针
}
// 按照极角排序,如果极角相同,则按照距离排序
bool compare(const Point &p1, const Point &p2) {
int o = orientation(p0, p1, p2);
if (o == 0) {
return (p0.x - p1.x) * (p0.x - p1.x) + (p0.y - p1.y) * (p0.y - p1.y) <
(p0.x - p2.x) * (p0.x - p2.x) + (p0.y - p2.y) * (p0.y - p2.y);
}
return (o == 2);
}
std::vector convexHull(std::vector &points) {
// 找到最左下方的点
Point p0 = *std::min_element(points.begin(), points.end());
// 根据极角排序
std::sort(points.begin(), points.end(), compare);
// 创建一个栈来存储凸包的顶点
std::stack<Point> hull;
hull.push(points[0]);
hull.push(points[1]);
for (int i = 2; i < points.size(); i++) {
while (hull.size() > 1 && orientation(hull.top(), hull.second_from_top(), points[i]) != 2) {
hull.pop();
}
hull.push(points[i]);
}
// 将栈转换为向量
std::vector<Point> convexHull;
while (!hull.empty()) {
convexHull.push_back(hull.top());
hull.pop();
}
return convexHull;
}
int main() {
std::vector points = {{0, 3}, {1, 1}, {2, 2}, {4, 4}, {0, 0}, {1, 2}, {3, 1}, {3, 0}};
std::vector hull = convexHull(points);
std::cout << "The points in the convex hull are:" << std::endl;
for (const auto& point : hull) {
std::cout << "(" << point.x << ", " << point.y << ")" << std::endl;
}
return 0;
}