Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 凸包排序步骤_Algorithm_Computational Geometry_Convex Hull - Fatal编程技术网

Algorithm 凸包排序步骤

Algorithm 凸包排序步骤,algorithm,computational-geometry,convex-hull,Algorithm,Computational Geometry,Convex Hull,我正在阅读格雷厄姆扫描算法,以从CLR中找到凸包。 CLRS中给出的凸包算法为: 我无法理解这一行(算法的第2步): 如果两个或多个点相对于p0具有相同的极角,那么除了最远的点之外,所有这些点都是p0和最远点的凸组合,因此我们完全不考虑它们 这是什么意思?如果多个点与Po具有相同的极角,我该怎么办 也就是说,我做了一个结构 struct points { int x, y; } P[10000]; 如何使用C++ STL库实现排序步骤?我的意思是,我应该如何在排序(P+1,P+N,c

我正在阅读格雷厄姆扫描算法,以从CLR中找到凸包。 CLRS中给出的凸包算法为:

我无法理解这一行(算法的第2步):

如果两个或多个点相对于p0具有相同的极角,那么除了最远的点之外,所有这些点都是p0和最远点的凸组合,因此我们完全不考虑它们

  • 这是什么意思?如果多个点与Po具有相同的极角,我该怎么办
  • 也就是说,我做了一个结构

    struct points
    {
        int x, y;
    } P[10000];
    
    如何使用C++ STL库实现排序步骤?我的意思是,我应该如何在
    排序(P+1,P+N,comparator)
    中定义comparator函数 这意味着什么,如果多个点相对于Po具有相同的极角,我该怎么办

    假设P0是
    (0,0)
    ,P1是
    (1,1)
    ,P2是
    (2,2)
    。现在P1和P2相对于P0具有相同的角度,在这种情况下,放弃P1。如果P0和P2之间有更多相同角度的点,则丢弃除P2之外的所有点(当然还有P0)

    如何使用C++ STL(算法中的排序函数)实现分拣步骤?特别是排序(P+1,P+N,比较器)。我应该如何定义比较器函数


    <>不太熟悉C++(STL),但检查它是否有一个可以使用的<代码> ATAN2</代码>函数。另请参见:和

    这是我在C语言中对凸包的gharam扫描算法的实现++

    struct vert
    {
        int x,y;
        float rad;
        int idx;
    };    
    bool operator<(const vert &a,const vert &b)//this is the function u are looking for
    {
        if(a.rad<b.rad)
            return true;
        if(a.rad==b.rad)
        {
            if(a.y>b.y)
                return true;
            else if(a.y==b.y&&a.x>b.x)
                return true;
            else
                return false;
        }
        return false;
    }    
    vert operator-(vert x,vert y)
    {
        vert tmp;
        tmp.x=x.x-y.x;
        tmp.y=x.y-y.y;
        return tmp;
    }
    double dist(vert a,vert b)
    {
        vert ab=b-a;
        return sqrt(ab.x*ab.x+ab.y*ab.y);
    }
    int cross(vert a,vert b,vert c)
    {
        vert ab,bc;
        ab=b-a;
        bc=c-b;
        return ab.x*bc.y-ab.y*bc.x;
    }
    int main()
    {
        int t,i,j,k,n;
        //("example.txt","r",stdin);
        scanf("%d",&t);
        vert a[100009],point[100009];
        int kx,ky;
        while(t--)
        {
            scanf("%d",&n);
            for(i=0;i<n;i++)
            {
                scanf("%d%d",&a[i].x,&a[i].y);
                a[i].idx=i+1;
            }
            vert d;
            d=a[0];
            for(i=1;i<n;i++)
            {
                if(a[i].y<d.y)
                    d=a[i];
                else if(a[i].y==d.y&&a[i].x<d.x)
                    d=a[i];
            }
            vector<vert> v;
            for(i=0;i<n;i++)
            {
                kx=a[i].x-d.x;
                ky=a[i].y-d.y;
                if(kx==0&&ky==0)
                    continue;
                a[i].rad=atan2(kx,ky)*-1.00;
                v.push_back(a[i]);
            }
            sort(v.begin(),v.end());
            float rad=-10000;
            j=0;
            for(i=0;i<v.size();i++)
            {
                if(v[i].rad!=rad)
                {
                    a[j++]=v[i];
                    rad=v[i].rad;
                }
            }
            k=0;
            point[k++]=d;
            for(i=0;i<j;i++)
            {
                if(k<=1)
                    point[k++]=a[i];
                if(cross(point[k-2],point[k-1],a[i])>0)
                {
                    point[k++]=a[i];
                }
                else
                {
                    do
                    {
                        k--;
                        if(cross(point[k-2],point[k-1],a[i])>0)
                            break;
                    }while(k>1);
                    point[k++]=a[i];
                }
            }
            double dis=0;
            for(i=1;i<k;i++)
                dis+=dist(point[i],point[i-1]);
            dis+=dist(point[0],point[k-1]);
            printf("%0.2f\n",dis);
            for(i=0;i<k;i++)
                printf("%d ",point[i].idx);
            cout<<endl<<endl;;
        }
        return 0;
    }
    
    struct vert
    {
    int x,y;
    浮动半径;
    int-idx;
    };    
    布尔运算符(b.x)
    返回true;
    其他的
    返回false;
    }
    返回false;
    }    
    垂直运算符-(垂直x,垂直y)
    {
    垂直tmp;
    tmp.x=x.x-y.x;
    tmp.y=x.y-y.y;
    返回tmp;
    }
    双距离(垂直a、垂直b)
    {
    垂直ab=b-a;
    返回sqrt(ab.x*ab.x+ab.y*ab.y);
    }
    内部交叉(垂直a、垂直b、垂直c)
    {
    垂直ab,bc;
    ab=b-a;
    bc=c-b;
    返回ab.x*bc.y-ab.y*bc.x;
    }
    int main()
    {
    int t,i,j,k,n;
    //(“example.txt”、“r”和stdin);
    scanf(“%d”、&t);
    顶点a[100009],点[100009];
    int kx,ky;
    而(t--)
    {
    scanf(“%d”和“&n”);
    对于(i=0;i
    

    (b)我应该如何使用C++ STL(算法函数库)中的排序函数来实现排序步骤?尤其是排序(P+1,P+N,比较器)。我应该如何定义比较器函数?< /P> 我建议您避免混乱的浮点运算。正如同一本书的练习33.1-3所指出的,您可以简单地使用叉积按极角排序。下面是如何做到这一点:

    struct Point {int x,y;}
    
    int operator^(Point p1, Point p2) {return p1.x*p2.y - p1.y*p2.x;}
    
    Point p0; //set this separately
    
    bool operator<(Point p1, Point p2) 
    {
        p1=p1-p0; p2=p2-p0; 
        if(p1.y==0&&p1.x>0) return true; //angle of p1 is 0, thus p2>p1
        if(p2.y==0&&p2.x>0) return false; //angle of p2 is 0 , thus p1>p2
        if(p1.y>0&&p2.y<0) return true; //p1 is between 0 and 180, p2 between 180 and 360
        if(p1.y<0&&p2.y>0) return false;
        return (p1^p2)>0; //return true if p1 is clockwise from p2
    }
    
    并将该行添加到比较器:

    if((p1^p2)==0&&p1*p2>0) return p1*p1<p2*p2;
    
    这里,如果点具有相同的角度,
    eq
    函数将返回true

    bool eq(Point p1, Point p2) 
    {
        p1=p1-p0; p2=p2-p0;
        return ((p1^p2)==0&&p1*p2>0); 
    }
    

    谢谢!你的意思是,在平局的情况下,即有n个点的极角相对于Po是相同的,那么,我应该只考虑这个点,它的欧几里得距离是Po最大的。
    sort(P.begin(),P.end());
    P.erase(unique(P.begin(),P.end(),eq),P.end());
    
    bool eq(Point p1, Point p2) 
    {
        p1=p1-p0; p2=p2-p0;
        return ((p1^p2)==0&&p1*p2>0); 
    }