天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 29|回复: 0

分治算法求解凸包问题

[复制链接]
  • TA的每日心情
    开心
    昨天 06:36
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    105

    主题

    11

    回帖

    1308

    积分

    管理员

    积分
    1308
    QQ
    发表于 2024-10-6 10:42:01 | 显示全部楼层 |阅读模式
    1. #include <iostream>
    2. #include <vector>
    3. #include <cmath>
    4. #include <algorithm>

    5. using namespace std;

    6. // 定义点的结构体
    7. struct Point {
    8.     int x, y;
    9. };

    10. // 计算点P到直线AB的距离
    11. double distanceToLine(const Point& A, const Point& B, const Point& P) {
    12.     return abs((B.x - A.x) * (A.y - P.y) - (A.x - P.x) * (B.y - A.y)) /
    13.         sqrt(pow(B.x - A.x, 2) + pow(B.y - A.y, 2));
    14. }

    15. // 计算叉积,判断点C在向量AB的右侧、左侧或共线
    16. int crossProduct(const Point& A, const Point& B, const Point& C) {
    17.     return (B.x - A.x) * (C.y - B.y) - (B.y - A.y) * (C.x - B.x);
    18. }

    19. // 判断点C是否在向量AB的右侧
    20. bool isRightOf(const Point& A, const Point& B, const Point& C) {
    21.     return crossProduct(A, B, C) < 0;
    22. }

    23. // 快速凸包算法的部分实现
    24. vector<Point> quick_half_hull(vector<Point>& S, const Point& a, const Point& b) {
    25.     if (S.empty()) return {};

    26.     double maxDist = -1;
    27.     Point c;
    28.     for (const auto& point : S) {
    29.         double dist = distanceToLine(a, b, point);
    30.         if (dist > maxDist) {
    31.             maxDist = dist;
    32.             c = point;
    33.         }
    34.     }

    35.     vector<Point> A, B;

    36.     // 筛选出右侧的点集A和B
    37.     for (const auto& point : S) {
    38.         if (isRightOf(b, c, point)) {
    39.             A.push_back(point);
    40.         }
    41.         else if (isRightOf(c, a, point)) {
    42.             B.push_back(point);
    43.         }
    44.     }

    45.     vector<Point> QA = quick_half_hull(A, a, c);
    46.     vector<Point> QB = quick_half_hull(B, c, b);

    47.     vector<Point> result;
    48.     result.insert(result.end(), QA.begin(), QA.end());
    49.     result.push_back(c);
    50.     result.insert(result.end(), QB.begin(), QB.end());

    51.     return result;
    52. }

    53. vector<Point> quick_hull(vector<Point>& S) {
    54.     if (S.size() < 3) return S;

    55.     // 寻找极端点a和b
    56.     sort(S.begin(), S.end(), [](const Point& p1, const Point& p2) {
    57.         return (p1.x < p2.x) || (p1.x == p2.x && p1.y < p2.y);
    58.         });

    59.     Point a = S[0];
    60.     Point b = S[S.size() - 1];

    61.     vector<Point> A, B;

    62.     // 筛选出右侧的点集A和B
    63.     for (const auto& point : S) {
    64.         if (isRightOf(b, a, point)) {
    65.             A.push_back(point);
    66.         }
    67.         else if (isRightOf(a, b, point)) {
    68.             B.push_back(point);
    69.         }
    70.     }

    71.     vector<Point> QA = quick_half_hull(A, a, b);
    72.     vector<Point> QB = quick_half_hull(B, b, a);

    73.     vector<Point> result;
    74.     result.push_back(a);
    75.     result.insert(result.end(), QA.begin(), QA.end());
    76.     result.push_back(b);
    77.     result.insert(result.end(), QB.begin(), QB.end());

    78.     return result;
    79. }

    80. int main() {
    81.     // 示例点集
    82.     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} };

    83.     // 调用凸包算法
    84.     vector<Point> result = quick_hull(points);

    85.     // 输出凸包顶点
    86.     cout << "Convex Hull Points:\n";
    87.     for (const auto& point : result) {
    88.         cout << "(" << point.x << ", " << point.y << ")\n";
    89.     }

    90.     return 0;
    91. }
    复制代码

     

     

     

     

    分治算法求解凸包问题
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

    GMT+8, 2024-11-1 09:27 , Processed in 0.150893 second(s), 24 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表