计算几何入门不久,大家相互学习探讨!
题意:
给定N个互不相交的圆,告诉圆心的坐标和半径,求一个圆的半径,要求这个圆的圆心与N个圆中的某一个的圆心重合,并且这个圆至少要覆盖每个圆的一半,求满足条件的最小半径。
思路(baudu+小结):
既然圆心是某个圆的圆心,那么我们可以枚举圆心,只是半径怎么求呢?我们可以用二分的思想找到半径,依次求出每个圆心上满足条件的圆的半径,再取一个min值即为所求。
两圆相离、外切、内切、内含都好断定,然则相交情况如何断定面积,参考网址http://www.cnblogs.com/evan-oi/archive/2012/03/14/2395989.html
#include<stdio.h> #include<math.h> const double eps = 1e-8; const double pi = acos(-1.0); struct Point { double x,y; }; struct circle { Point pp; double r; }cir[30]; double area[30]; int n; double cir_area_inst(Point c1,double r1,Point c2,double r2) { //两圆面积交 double a1, a2, d, ret; d = sqrt((c1.x-c2.x)*(c1.x-c2.x)+(c1.y-c2.y)*(c1.y-c2.y)); //圆心距离 if ( d > r1 + r2 - eps ) return 0; //相离 if ( d < r2 - r1 + eps ) return pi*r1*r1; //内切与包含 if ( d < r1 - r2 + eps ) return pi*r2*r2; //内切与包含 a1 = acos((r1*r1+d*d-r2*r2)/2/d/r1);//相交 //余弦定理求角 a2 = acos((r2*r2+d*d-r1*r1)/2/d/r2); ret = (a1-0.5*sin(2*a1))*r1*r1 + (a2-0.5*sin(2*a2))*r2*r2; //求楔形(扇形减三角形)面积 return ret; } bool judge(Point p,double r)//枚举每个圆心 { int i,j; for(i=0;i<n;i++) { double Are = cir_area_inst(p,r,cir[i].pp,cir[i].r); if(Are<area[i])return false; } return true; } int main() { int t,i,j; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) { scanf("%lf %lf %lf",&cir[i].pp.x,&cir[i].pp.y,&cir[i].r); area[i] = pi*cir[i].r*cir[i].r/2; } Point a; double rans = 200000; //初始化符合要求的大圆半径 for(i=0;i<n;i++) { a = cir[i].pp; double l=0,r=200000,mid; while(fabs(l-r)>eps)//二分法 { mid = (l+r)/2; if(judge(a,mid)) { r =mid; if(mid<rans)//找符合要求的最小的圆 rans =mid; } else l=mid; } } printf("%.4lf\n",rans); } return 0; }
做一道题,各种找代码+详解,然后才弄懂啊!!!