| 
	
	
		
			  code #include<iostream>
 #include<cmath>
 using namespace std;
 const double eps=1e-10;
 const double limit=1e-10;
 struct PT
 {
 double x,y;
 };
 struct LN
 {
 double a,b,c;
 };
 struct PL
 {
 int n;
 PT p[1501];
 };
 PL poly,newpoly,tmpoly;
 int cas;
 int n;
 LN getline(PT a,PT b)
 {
 LN l;
 l.a=b.y-a.y;
 l.b=a.x-b.x;
 l.c=b.x*a.y-a.x*b.y;
 return l;
 }
 PT getinterp(LN l1,LN l2)
 {
 PT ans;
 if(fabs(l1.b)<eps)
 {
 ans.x=-l1.c/l1.a;
 ans.y=(-l2.c-l2.a*ans.x)/l2.b;
 }
 else
 {
 ans.x=(l2.c*l1.b-l1.c*l2.b)/(l1.a*l2.b-l2.a*l1.b);
 ans.y=(-l1.c-l1.a*ans.x)/l1.b;
 }
 return ans;
 }
 double Cha(PT a,PT b,PT c)
 {
 return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
 }
 PT change(PT s,PT e,PT st,double L)
 {
 PT tmp;
 tmp.x=-(e.y-s.y);
 tmp.y=e.x-s.x;
 double len=sqrt((e.x-s.x)*(e.x-s.x)+(e.y-s.y)*(e.y-s.y));
 tmp.x/=len;tmp.x*=L;
 tmp.y/=len;tmp.y*=L;
 tmp.x+=st.x;
 tmp.y+=st.y;
 return tmp;
 }
 bool jud(double h)
 {
 int i,j;
 newpoly=poly;
 for(i=0;i<poly.n;i++)
 {
 tmpoly.n=0;
 PT s,e;
 s=change(poly.p[i],poly.p[(i+1)%poly.n],poly.p[i],h);
 e=change(poly.p[i],poly.p[(i+1)%poly.n],poly.p[(i+1)%poly.n],h);
 for(j=0;j<newpoly.n;j++)
 {
 double r1,r2;
 r1=Cha(s,e,newpoly.p[j]);
 r2=Cha(s,e,newpoly.p[(j+1)%newpoly.n]);
 if(r1>=0)
 {
 tmpoly.p[tmpoly.n++]=newpoly.p[j];
 }
 if(r1*r2<0)
 {
 LN l1=getline(s,e);
 LN l2=getline(newpoly.p[j],newpoly.p[(j+1)%newpoly.n]);
 PT interp=getinterp(l1,l2);
 tmpoly.p[tmpoly.n++]=interp;
 }
 }
 newpoly=tmpoly;
 }
 if(newpoly.n)
 return 1;
 return 0;
 
 }
 int main()
 {
 int i,j;
 while(1)
 {
 scanf("%d",&poly.n);
 if(!poly.n)
 break;
 for(i=0;i<poly.n;i++)
 scanf("%lf%lf",&poly.p[i].x,&poly.p[i].y);
 double left=0,right=100000000;
 while(left+limit<right)
 {
 double mid=(left+right)/2;
 if(jud(mid))
 left=mid;
 else right=mid;
 }
 printf("%.6lf\n",right);
 }
 }
 
求凸多边形最大内切圆半径。 方法就是把每条边向内推进R,对得到的新的边集进行半平面交,看是否得到空集。 R用二分枚举得到。 半平面交用的O(n^2)的。
		     
	    
    
 |