寻找凸包详细代码 合工大程序设计实验三

**算法思想 : **
在这里插入图片描述
在这里插入图片描述
寻找凸包这里演示打包法,有一种更优的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;
}

运行截图
在这里插入图片描述

Guess you like

Origin blog.csdn.net/qq_42650433/article/details/106394976