【计算几何】闵可夫斯基和
计算几何-闵可夫斯基和
闵可夫斯基和
闵可夫斯基和,又称作闵可夫斯基加法,是两个欧几里得空间的点集的和,以德国数学家闵可夫斯基命名。(小知识:闵可夫斯基曾经做过爱因斯坦的老师。)
闵可夫斯基和是两个欧几里得空间的点集的和,也称为这两个空间的膨胀集,被定义为
\[ A + B=\{a+b|a \in A, b \in B \}
\]
根据闵可夫斯基和的定义,若集合元素所处代数系统满足阿贝尔群(加法可交换),则闵可夫斯基和本身也满足交换律:
\[ A+B=B+A
\]
(以上参考自Baidu)
其实对于闵可夫斯基和,可以通俗的理解为,对于一个凸包\(A\)绕着凸包\(B\)转一圈:
算法实现
对于求两个点集的闵可夫斯基和,通过肉眼观察,和理性分析,我们可以得出这么一个结论:两个凸包\(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++];
}
}
一些例题
Doctor,您还有许多事情需要处理。现在还不能休息哦。