凸包

作者: Anxdada | 来源:发表于2017-03-02 20:54 被阅读0次

向量的叉乘就是由该两个向量所组成的平行四边形的面积(x1y2-x2y1).
这个凸包不是太懂.先留模板在此
这个是水平排序

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double

const int MAX = 1e3+7;
//const int maxn = 3e6+5;
const int mod = 1000000007;
const db eps = 1e-7;
int ca = 1;

struct PO
{
    int x, y;
    PO (){};
    PO (int x, int y):x(x), y(y){};
    friend PO operator - (const PO&a, const PO&b)
    {
        return PO(a.x-b.x, a.y-b.y);
    }
};
PO pos[MAX];//存点
PO ch[MAX];//栈
bool cmp(const PO&a, const PO&b)
{
    if(a.x==b.x)return a.y<b.y;
    else return a.x<b.x;
}
int cross(const PO&a, const PO&b)
{
    return a.x*b.y-a.y*b.x;
}

int n;

void solve()
{
    scanf("%d", &n);
    for(int i=0; i<n; i++)
        scanf("%d%d", &pos[i].x, &pos[i].y);
    sort(pos, pos+n, cmp);
    //第一条链
    int m = 0;
    for(int i=0; i<n; i++)
    {
        while(m>1 && cross(pos[i]-ch[m-2], ch[m-1]-ch[m-2])>=0) m--;
        ch[m++] = pos[i];
    }
    //第二条链
    int temp = m;
    for(int i=n-2; i>=0; i--)
    {
        while(m>temp && cross(pos[i]-ch[m-2], ch[m-1]-ch[m-2])>=0) m--;
        ch[m++] = pos[i];
    }
    if(n>1) m--;
    cout << "______________"<<endl;
    for(int i=0; i<m; i++)
        printf("%d %d\n", ch[i].x, ch[i].y);
}

int main()
{
    //Frei
    //Freo
    int t = 1;
    //cin >> t;
    while (t--) solve();

}

这个是极角排序

#include<stdio.h>
#include<math.h>
#define eps 1e-10
#define pi 3.1415926535898
#define N 1010
/*
point[]:输入的点集
ch[]:输出的凸包上的点集,按照逆时针方向排列
n:point中的点的数目
len:输出的凸包上的点的个数
*/
struct node
{
    double x,y;
} point[N],ch[N];
int n,len;
double multi(node a,node b,node c)
{
    return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
}
double dis(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
void graham_scan(node point[N],node ch[N],int n)
{
    int i,j,k,top;
    struct node t;
    k=0; //找到最下且偏左的那个点
    for(i=1; i<n; i++)
        if(point[i].y<point[k].y||(point[i].y==point[k].y&&(point[i].x<point[k].x)))
            k=i;
    t=point[0];//将这个点指定为point[0];
    point[0]=point[k];
    point[k]=t;
    //按极角从小到大,距离偏短进行排序
    for(i=1; i<n-1; i++)
    {
        k=i;
        for(j=i+1; j<n; j++)
            if(multi(point[j],point[k],point[0])>0||(fabs(multi(point[j],point[k],point[0]))<=eps&&
                    (dis(point[0],point[j])<dis(point[0],point[k]))))
                k=j; //k保存极角最小的那个点,或者相同距离原点最近
        t=point[i];
        point[i]=point[k];
        point[k]=t;
    }
    //第三个点先入栈
    ch[0]=point[0];
    ch[1]=point[1];
    ch[2]=point[2];
    top=2; //判断与其余所有点的关系
    for(i=3; i<n; i++)
    {
        //不满足向左转的关系,栈顶元素出栈
        while(multi(point[i],ch[top],ch[top-1])>0||fabs(multi(point[i],ch[top],ch[top-1]))<=eps)
            top--;
        //当前点与栈内所有点满足向左关系,因此入栈
        ch[++top]=point[i];
    }
    len=top+1;
}
int main()
{
    int i;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0; i<n; i++)
            scanf("%lf%lf",&point[i].x,&point[i].y);
        graham_scan(point,ch,n);
        for(i=0; i<len; i++)
            printf("%lf %lf\n",ch[i].x,ch[i].y);
    }
    return 0;
}

相关文章

  • 凸包

    向量的叉乘就是由该两个向量所组成的平行四边形的面积(x1y2-x2y1).这个凸包不是太懂.先留模板在此这个是水平...

  • 凸包

    凸包最常用的凸包算法是Graham扫描法和Jarvis步进法Graham's Scan法这个算法是由数学大师葛立恒...

  • 凸包

    convexHull 实例

  • 凸包

    逼近多边形是轮廓的高度近似,但是有时候我们希望使用一个多边形的凸包来简化它。凸包跟逼近多边形很像,只不过它是物体最...

  • Python3 趣味系列题8 ------ 凸包动态绘制

    本文介绍利用Graham Scan算法获得凸包(平面凸包),并动态展示凸包的形成过程。下面用比较通俗的语言,介绍下...

  • 算法复习-geometric algo

    convex hull 凸包-video25&video26 凸包算法剖析https://cyw3.github....

  • 图像轮廓(2)

    1. 凸包 凸缺陷可以用来处理手势识别问题 points:轮廓clockwise:True:凸包按顺时针方向排列;...

  • 3,4 仿射,凸,凸锥

    仿射组合凸组合凸锥组合组合后的所有点组成的称为仿射\凸\凸锥包

  • 提取平面点云的轮廓

    一. 基于凸包的凹点挖掘算法: 1. 提取点云的凸包 2. 计算凸包每条边的顶点的点密度(即该点 K 个临...

  • 凸包(andrew)

    将所有点按照x为first,y为second从小到大排序,(可以先删除相同点)得到p数组,将p1p2放到凸包中,从...

网友评论

      本文标题:凸包

      本文链接:https://www.haomeiwen.com/subject/jmozwttx.html