【计算几何】闵可夫斯基和

计算几何-闵可夫斯基和

闵可夫斯基和

闵可夫斯基和,又称作闵可夫斯基加法,是两个欧几里得空间的点集的和,以德国数学家闵可夫斯基命名。(小知识:闵可夫斯基曾经做过爱因斯坦的老师。)

闵可夫斯基和是两个欧几里得空间的点集的和,也称为这两个空间的膨胀集,被定义为

\[ A + B=\{a+b|a \in A, b \in B \} \]

根据闵可夫斯基和的定义,若集合元素所处代数系统满足阿贝尔群(加法可交换),则闵可夫斯基和本身也满足交换律:

\[ A+B=B+A \]

(以上参考自Baidu)

其实对于闵可夫斯基和,可以通俗的理解为,对于一个凸包\(A\)绕着凸包\(B\)转一圈:

来源于https://www.cnblogs.com/xzyxzy/p/10229921.html

算法实现

对于求两个点集的闵可夫斯基和,通过肉眼观察,和理性分析,我们可以得出这么一个结论:两个凸包\(A\)\(B\)上的边一定在闵可夫斯基和中出现。

然后我们就可以先求出两个点集的凸包,然后按极角排序后求闵可夫斯基和。

Code:

求凸包:

int Convexhull(geometric *p,ll l)
{
    for(int i=2;i<=l;i++)
    {
        if(p[i].y<p[1].y)swap(p[1],p[i]);
        if(p[i].y==p[1].y&&p[i].x<p[1].x)
            swap(p[i],p[1]);
    }
    geometric k=p[1];
    for(int i=1;i<=l;i++)p[i]=p[i]-k;
    sort(p+2,p+l+1,cmp);
    int top=0;
    geometric st[maxn];
    st[++top]=p[1];
    for(int i=2;i<=l;i++)
    {
        while(top>1&&cross(st[top-1],st[top],st[top],p[i])<0)
            top--;
        st[++top]=p[i];
    }
    for(int i=1;i<=top;i++)p[i]=st[i]+k;
    p[top+1]=p[1];
    return top;
}

求闵可夫斯基和:

void Minkowski()
{
    for(int i=1;i<=n;i++)s1[i]=p1[i+1]-p1[i];
    for(int i=1;i<=m;i++)s2[i]=p2[i+1]-p2[i];
    S[++cnt]=p1[1]+p2[1];
    int i=1,j=1;
    while(i<=n&&j<=m)
    {
        cnt++;
        if(cross(origin,s1[i],origin,s2[j])>=0)
            S[cnt]=S[cnt-1]+s1[i++];
        else S[cnt]=S[cnt-1]+s2[j++];
    }
    while(i<=n)
    {
        cnt++;
        S[cnt]=S[cnt-1]+s1[i++];
    }
    while(j<=m)
    {
        cnt++;
        S[cnt]=S[cnt-1]+s2[j++];
    }
}

一些例题

[JSOI2018]战争

posted @ 2022-06-03 22:46  Jekyll_Y  阅读(4329)  评论(0编辑  收藏  举报