//poj 3525 二分+半平面交 #include<iostream> #include<algorithm> #include<utility> #include<cstdio> #include<cstring> #include<cstdlib> #include<sstream> #include<cmath> #include<ctime> #include<vector> #include<string> #include<map> #include<set> #include<queue> #include<stack> #include<numeric> #include<limits> using namespace std; const double eps= 1e-10; const int maxn = 1024; const int inf =1012345678; struct POINT { double x,y; void read(){scanf("%lf%lf", &x,&y);} POINT(){} POINT(double a,double b){x=a; y=b;} }; bool operator ==(const POINT &a,const POINT &b) { if(a.x==b.x && b.y==a.y) return true; else false; } int dblcmp(double t) { if(fabs(t)<eps) return 0; return t<0?-1:1; } double cross(POINT p2,POINT p3,POINT p1)//L12*L13 { //大于0则向量p1p2(p2-p1)在向量p1p3(p3-p1)顺时针方向 //小于0则向量p1p2(p2-p1) 在向量p1p3(p3-p1)逆时针方向 //等于0则在同一直线上 return (p2.x-p1.x)*(p3.y-p1.y)-(p3.x-p1.x)*(p2.y-p1.y); } inline void tuijin(POINT &p1,POINT &p2,double d)//逆时针的两个点想凸包内推进,顺时针向外 //向向量的左手方向推进 { // printf("d=%lf %lf %lf %lf %lf/n",d,p1.x,p1.y,p2.x,p2.y); double px,py,l; px=-p2.y+p1.y; py=p2.x-p1.x; l=sqrt(px*px+py*py); px=d*px/l; py=d*py/l; p1.x+=px; p2.x+=px; p1.y+=py; p2.y+=py; // printf("d=%lf %lf %lf %lf %lf/n",d,p1.x,p1.y,p2.x,p2.y); } inline int cutpolygon(POINT polygon[],int vcount,POINT p1,POINT p2)//凸包(多边形不行)必须逆时针方向,直线p1p2也是按照逆时针(左手)的,也就是和多边形的方向是相同的 //返回被切后多边形的点数(如果只剩一条线返回的点数也可能是正的) { POINT pp[maxn]; double now[maxn]; int a=0,b=0; int i,j; int nn; for (i=0; i<vcount; i++) { now[i]=cross(p2,polygon[i],p1); if (now[i]>0) a++;//左边 要保留的点 if (now[i]<0) b++;//右边 要删除的点 } if (a==0 && b==vcount) return 0; else if (a==0 && b!=vcount) //处理只剩下一条线的情况 { nn=0; for (i=0; i<vcount; i++) if (now[i]==0)//now[i]==0; polygon[nn++]=polygon[i]; polygon[nn]=polygon[0]; return nn; } if (b==0) return vcount; else if (b!=0)//处理切割的情况 { nn=2; polygon[vcount]=polygon[0]; now[vcount]=now[0]; i=0; for (;;) { if (now[i]>0 && now[i+1]<=0) break; i=(i+1)%vcount; } //定比分点法求坐标 pp[0].x=(now[i]*polygon[i+1].x-now[i+1]*polygon[i].x)/(now[i]-now[i+1]); pp[0].y=(now[i]*polygon[i+1].y-now[i+1]*polygon[i].y)/(now[i]-now[i+1]); j=(i+1)%vcount; for (;;) { if (now[j+1]>0) break; j=(j+1)%vcount; } pp[1].x=(now[j]*polygon[j+1].x-now[j+1]*polygon[j].x)/(now[j]-now[j+1]); pp[1].y=(now[j]*polygon[j+1].y-now[j+1]*polygon[j].y)/(now[j]-now[j+1]); j=(j+1)%vcount; for(;;j=(j+1)%vcount) { pp[nn++]=polygon[j]; if (i==j) break; } for (i=0; i<nn; i++) polygon[i]=pp[i]; polygon[nn]=polygon[0]; return nn; } } int n,m,nn; POINT p[maxn],pp[maxn]; double minx,miny,maxx,maxy; int main() { // freopen("in.txt","r",stdin); int i,j,k; while(scanf("%d", &n),n) { double r=0,l=0; minx=inf; miny=inf; maxx=-inf; maxy=-inf; for(i=0; i<n; i++) { p[i].read(); minx=min(p[i].x,minx); miny=min(p[i].y,miny); maxx=max(p[i].x,maxx); maxy=max(p[i].y,maxy); } r=max(maxx-minx,maxy-miny)/2; p[n]=p[0]; double ans=0,mid; while(dblcmp(r-l)!=0) { mid=(l+r)/2; for(i=0; i<=n; i++) pp[i]=p[i]; nn=n; for(i=0; i<n; i++) { POINT a=p[i],b=p[i+1]; tuijin(a,b,mid); nn=cutpolygon(pp,nn,a,b); if(nn<=0) break; } if(nn>0) { ans=mid; l=mid; } else r=mid; } printf("%lf/n",ans); } } 2011-05-02