注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

zxj015

 
 
 

日志

 
 

poj 3384 Feng Shui 半平面交  

2011-05-07 23:58:25|  分类: 计算几何 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
给定一个多边形,在多边形内放有两个相同的圆,使两个圆尽可能多的覆盖多边形。输出最终两个圆心的位置。
最优的放置方法必定是圆内切于两条边,那么把所有的边向内推移半径R的距离,得到新的多边形(也有可能是一个点或一条直线),求出新多边形相距最远的两个顶点,这两个顶点就是圆心的位置了。


#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<cmath>
using namespace std;
const double pi=acos(-1.0);
const int N=105;
const double eps=1e-9;
int n,m,s;
struct point
{
 double x,y;
}p[N],q[N],input[N];
int sig(double k)
{
 return (k<-eps)?-1:(k>eps);
}
double dis(point a,point b)
{
 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double xmule(point p1,point p2,point p3)
{
 return ((p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y));
}
void interect(point x,point y,double a,double b,double c)//求2直线交点(xy与ax0+by0+c=0的交点)
{
 double u=fabs(a*x.x+b*x.y+c);
 double v=fabs(a*y.x+b*y.y+c);
 q[++s].x=(x.x*v+y.x*u)/(u+v);
 q[s].y=(x.y*v+y.y*u)/(u+v);
}
void cut(double a,double b,double c)//半平面切割
{
 s=0;
 int i;
 for(i=1;i<=m;i++)//枚举所有点
 {
  if(sig(a*p[i].x+b*p[i].y+c)<=0)
  {
   q[++s]=p[i];//符合
  }
  else
  {
   if(sig(a*p[i-1].x+b*p[i-1].y+c)<0)
    interect(p[i-1],p[i],a,b,c);//p[i]p[i-1]与直线的交点符合
   if(sig(a*p[i+1].x+b*p[i+1].y+c)<0)
    interect(p[i],p[i+1],a,b,c);//p[i]p[i+1]与直线的交点符合
  }
 }
 for(i=1;i<=s;i++)
 {
  p[i]=q[i];//更新
 }
 p[0]=p[s];
 p[s+1]=p[1];
 m=s;
}
double dir(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main()
{
 int i,j,ans1,ans2,r;
 double mid,max,len;
 while(scanf("%d%d",&n,&r)!=EOF)
 {
  for(i=1;i<=n;i++)
  {
   scanf("%lf%lf",&input[i].x,&input[i].y);
   p[i]=input[i];
  }
  input[n+1]=input[1];
  p[0]=p[n];
  p[n+1]=p[1];
   double a,b,c;
   point tt,ta,tb;
   for(i=1;i<=n;i++)
   {
    p[i]=input[i];
   }
      p[0]=p[n];
      p[n+1]=p[1];
   m=n;
   for(i=1;i<=n;i++)
   {
    tt.x=input[i+1].y-input[i].y;//顺时针,注意顺序,每条边一起向“内”推进R
    tt.y=input[i].x-input[i+1].x;
    double k=r*1.0/sqrt(tt.x*tt.x+tt.y*tt.y);
    tt.x=tt.x*k;
    tt.y=tt.y*k;
    ta.x=input[i].x+tt.x;
    ta.y=input[i].y+tt.y;
    tb.x=input[i+1].x+tt.x;
    tb.y=input[i+1].y+tt.y;

    a=ta.y-tb.y;//由2点求出直线ax+by+c=0
    b=tb.x-ta.x;
    c=ta.x*tb.y-ta.y*tb.x;
    cut(a,b,c);
   }
   max=-1;
   ans1=m;
   ans2=m;
   for(i=1;i<m;i++)
   for(j=i+1;j<=m;j++)
   {
len=dir(p[i],p[j]);
if(len-max>eps)
{
max=len;
ans1=i;
ans2=j;
}
}
  printf("%.4f %.4f %.4f %.4f\n",p[ans1].x,p[ans1].y,p[ans2].x,p[ans2].y);
 }
 return 0;
}



  评论这张
 
阅读(270)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018