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

计算几何-闵可夫斯基和

闵可夫斯基和

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

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

[ 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]战争

原文链接: https://www.cnblogs.com/Jekyll-Y/p/16340934.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

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

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/189881

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午3:46
下一篇 2023年2月12日 下午3:48

相关推荐