1. 程式人生 > >【模板/經典題型】閔可夫斯基和

【模板/經典題型】閔可夫斯基和

歐幾裏得 第一個 相同 tin 空間 -c code == 模板

閔可夫斯基和是兩個歐幾裏得空間的點集的和。
點集A與B的閔可夫斯基和就是{o|o=a+b},其中a屬於A,b屬於B。
求凸包之間的閔可夫斯基和的方法。
把兩個凸包的每一條向量都摳出來,按照極角序排序構成新凸包即可。
註意點和向量的去重(向量相同斜率去重)。
還有個地方可以提一下:求多個凸包的閔可夫斯基和的時候可以直接全把邊拿出來一塊求,沒有必要兩個兩個求。
具體實現的時候,找出最高且最靠左的點。
先把這個點加入答案,從這個點開始把所有向量跑一圈,最後去掉最後一個點即可(最後這個點會和第一個點重合)。

    pot P={-inf,-inf},Q={-inf,-inf},R={-inf,-inf};
    n=read(); 
    for(int i=1;i<=n;i++)
    {
        a[i].x=read();a[i].y=read();
        if(dcmp(a[i].y-P.y)==0&&dcmp(a[i].x-P.x)<0)P=a[i];
        if(dcmp(a[i].y-P.y)>0)P=a[i];
        if(i!=1)f[++cnt]=a[i]-a[i-1];if(i==n)f[++cnt]=a[1]-a[i];
    }
    n=read();
    for(int i=1;i<=n;i++)
    {
        b[i].x=read();b[i].y=read();
        if(dcmp(b[i].y-Q.y)==0&&dcmp(b[i].x-Q.x)<0)Q=b[i];
        if(dcmp(b[i].y-Q.y)>0)Q=b[i];
        if(i!=1)f[++cnt]=b[i]-b[i-1];if(i==n)f[++cnt]=b[1]-b[i];
    }
    n=read();
    for(int i=1;i<=n;i++)
    {
        c[i].x=read();c[i].y=read();
        if(dcmp(c[i].y-R.y)==0&&dcmp(c[i].x-R.x)<0)R=c[i];
        if(dcmp(c[i].y-R.y)>0)R=c[i];
        if(i!=1)f[++cnt]=c[i]-c[i-1];if(i==n)f[++cnt]=c[1]-c[i];
    }
    sort(f+1,f+cnt+1,cmp);
    pot k=P+Q+R;p[++tot]=k;
    for(int i=1;i<=cnt;i++)
    {
        k=k+f[i];
        if(i!=cnt&&dcmp(f[i].x*f[i+1].y-f[i].y*f[i+1].x)==0)continue;
        p[++tot]=k;
    }
    tot--;k=p[1];

【模板/經典題型】閔可夫斯基和