zoukankan      html  css  js  c++  java
  • 【模板】闵可夫斯基和

    闵可夫斯基和,是两个欧几里得空间的点集的和,以德国数学家闵可夫斯基命名。
    点集A与B的闵可夫斯基和就是{o|o=a+b},其中a属于A,b属于B。

    对于凸包这种特殊的图形,它的闵可夫斯基和有一些较好的性质。
    比如:凸包之间的闵可夫斯基和一定是凸包。

    求凸包之间的闵可夫斯基和的方法。
    把两个凸包的每一条向量都抠出来,按照极角序排序构成新凸包即可。
    注意点和向量的去重(向量相同斜率去重)。
    还有个地方可以提一下:求多个凸包的闵可夫斯基和的时候可以直接全把边拿出来一块求,没有必要两个两个求。
    具体实现的时候,找出最高且最靠左的点。
    先把这个点加入答案,从这个点开始把所有向量遍历一遍,最后去掉最后一个点即可(最后这个点会和第一个点重合)。
    下面是C++的代码实现:

    	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];
    

    应用:
    1.判断两个凸包是否相交
    两个凸包相交的条件:存在a=b,a属于A,b属于B。
    也就是存在a-b=0
    对B取反后和A计算一下闵可夫斯基和,若包含点(0,0)则说明原方程优借,即两个凸包有交。

    2.给出三个凸包,每次询问一个点,问能否从三个凸包中各选出一个点并连接成三角形,使得三角形的重心在询问点上。
    解:
    考虑重心的表达式。设三角形的三个顶点的坐标分别为(x1,y1),(x2,y2),(x3,y3),那么重心一定位于((x1+x2+x3)/3,(y1+y2+y3)/3)。
    发现这个表达式显然是一个闵可夫斯基和的形式,因此,直接求出三个凸包的闵可夫斯基和然后按比例缩小一下即可。

  • 相关阅读:
    使用Pandas groupby连接来自多行的字符串
    Pandas数据分析介绍
    SQL Server 32位数据源与64位数据源区别
    SQL Server install
    windows 远程提示CredSSP
    linux 终端下以图形界面打开当前文件夹
    Linux g++ include link
    undefined reference to symbol 'pthread_create@@GLIBC_2.2.5'
    Linux下的库操作工具-nm、ar、ldd、ldconfig和ld.so
    git update
  • 原文地址:https://www.cnblogs.com/Creed-qwq/p/10317535.html
Copyright © 2011-2022 走看看