首页 > 代码库 > hdu5012 圆环相交面积

hdu5012 圆环相交面积

题中给了 两个同心圆, 一个大圆一个小圆,然后再给了一个大圆一个小圆也是同心圆,求这两个圆环相交的面积,用两个大圆面积减去两倍大小圆面积交加上两个小圆面积交,就ok了

这里算是坑明白了 使用acos的时候要保证不能让大于1或者小于-1的数进来,因此加一个判断,在现场的时候就是这里被坑死了

#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <string.h>using namespace std;const double epl =0.0000000001;const double PI=acos(-1.0);struct point{  double x,y;  point(double a=0, double c=0){   x=a; y=c;   }};struct Circle{     point c;     double r;     point P(double a){        return point( (c.x+cos(a)*r) ,( c.y+sin(a)*r ) );     }}P1,P2,C1,C2;int dcmp(double x){   if(fabs(x)<epl) return 0;   return x<0?-1:1;}double myz(double a){   if(dcmp(a+1.0)<=0) return acos(-1.0);   if(dcmp(a-1.0)>=0) return acos(1.0);   return acos(a);}point operator -(point A, point B){   return point(A.x-B.x,A.y-B.y);}bool operator ==(point A, point B){   return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0;}double Dot(point A, point B){   return A.x*B.x+A.y*B.y;}double length(point A){   return sqrt(Dot(A,A));}double Angle(point A, point B){     return myz(Dot(A,B)/length(A)/length(B));}double angle(point v){  return atan2(v.y,v.x);}int getdd(Circle C1, Circle C2, point &p1, point &p2){      double d=length(C1.c-C2.c);      if(dcmp(d)==0){          return 0;      }      if(dcmp(C1.r+C2.r-d)<=0) return 1;      if(dcmp(fabs(C1.r-C2.r)-d)>=0) return 0;      double a=angle(C2.c-C1.c);      double da=acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d) );      p1= C1.P(a-da),p2=C1.P(a+da);      if(p1==p2)return 1;      return 2;}double Cross(point A, point B){  return A.x*B.y-A.y*B.x;}double Area(point A, point B, point C){    return fabs(Cross(B-A,C-A))/2;}double solve(Circle A, Circle B){     point pp1, pp2;     int a=getdd(A,B,pp1,pp2);     if(a==1) return 0;     if(a==0) {         double r=min(A.r,B.r);         return r*r*PI;     }     if(dcmp(A.r-B.r)==0){         double a=Angle(pp1-A.c,pp2-A.c);        double S=A.r*A.r*PI;        double rate=a/(2*PI);        double ans=S*rate-Area(A.c,pp1,pp2);        return ans*2.0;     }else{        if(A.r<B.r){            Circle te =A;            A=B;            B=te;        }        if(dcmp(Cross(pp1-pp2,A.c-pp2) )*dcmp(Cross(pp1-pp2,B.c-pp2))>=0 ){           double a1= Angle(pp1-A.c,pp2-A.c);           double S1=A.r*A.r*PI;           double rate1=a1/(2*PI);          double ans1=S1*rate1-Area(A.c,pp1,pp2);          double a2 = Angle(pp1-B.c,pp2-B.c);          double S2 = B.r*B.r*PI;          double rate2 = a2/(2*PI);          double ans2=S2*rate2-Area(B.c,pp1,pp2);          return S2-ans2+ans1;        }else{          double a1= Angle(pp1-A.c,pp2-A.c);           double S1=A.r*A.r*PI;           double rate1=a1/(2*PI);          double ans1=S1*rate1-Area(A.c,pp1,pp2);          double a2 = Angle(pp1-B.c,pp2-B.c);          double S2 = B.r*B.r*PI;          double rate2 = a2/(2*PI);          double ans2=S2*rate2-Area(B.c,pp1,pp2);          return ans1+ans2;        }     }}int main(){    int T;    scanf("%d",&T);    int cas=1;    double x1,x2,y1,y2,r,R;    while(T--){       scanf("%lf%lf",&r,&R);       scanf("%lf%lf",&x1,&y1);       scanf("%lf%lf",&x2,&y2);       P1.c=point(x1,y1);       P2.c=point(x1,y1);       C1.c=point(x2,y2);       C2.c=point(x2,y2);       P1.r=C1.r=R;       P2.r=C2.r=r;       double dada=solve(P1,C1);       double daxi=solve(P1,C2)*2;       double xixi=solve(C2,P2);       double ans=dada-daxi+xixi;       printf("Case #%d: %.6lf\n",cas++,ans);    }    return 0;}
View Code

 

hdu5012 圆环相交面积