HDU5120-Intersection (计算几何,计算圆环相交的面积)

http://acm.hdu.edu.cn/showproblem.php?pid=5120

题意:

有两个相同的圆环,求其相交部分的面积,有T组输入数据,每个样例给出内圆半径r和外圆半径R,然后给出两个圆环的中心坐标。

输出case编号和相交部分面积,精确到小数点后六位。

思路:

圆环相交面积=两个大圆的交面积-2×大圆与小圆的交面积+两个小圆的交面积,

即主要求两个圆的交面积即可。

代码:

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string>
#include<iomanip>
#include<algorithm>
#include<string.h>
#include<queue>
#include<cmath>
#include<stack>

using namespace std;
const int maxn = 5010;
const int inf = 0x7f7f7f7f;
typedef long long ll;

struct point
{
  double x,y;
  point(){}
  point(int _x,int _y):x(_x),y(_y){}

  point operator -(const point & a) const{
    return point(x-a.x,y-a.y);
  }
  double operator *(const point &a)const{
    return x*a.y-y*a.x;
  }
  double len(){
    return sqrt(x*x+y*y);
  }
};

struct circle
{
  double r;
  point c;
  circle(){}
  circle(double _r,point _c):r(_r),c(_c){}
};

double cl_inter(circle a,circle b)
{
  if(a.r>b.r) swap(a,b);
  double r=a.r,R=b.r,d=(a.c-b.c).len();
  if(d<=R-r) return acos(-1.0)*r*r;
  else if(d>=R+r) return 0;

  double x1=(d*d+r*r-R*R)/(2*d),x2=(d*d+R*R-r*r)/(2*d);
  double ans=(x1*sqrt(r*r-x1*x1)-r*r*acos(x1/r));
  ans+=(x2*sqrt(R*R-x2*x2)-R*R*acos(x2/R));
  return fabs(ans);
}

int main()
{
  double r,R;
  point a,b;
  int T;
  scanf("%d",&T);
  for(int cas=1; cas<=T; cas++)
  {
    scanf("%lf%lf",&r,&R);
    scanf("%lf%lf",&a.x,&a.y);
    scanf("%lf%lf",&b.x,&b.y);
    double ans=cl_inter(circle(R,a),circle(R,b));//大圆交面积
    ans-=2*cl_inter(circle(R,a),circle(r,b));//大圆与小圆交面积
    ans+=cl_inter(circle(r,a),circle(r,b));//小圆交面积
    printf("Case #%d: %.6lf\n",cas,ans);
  }
  return 0;
}

 

posted on 2021-02-07 18:55  mmn  阅读(197)  评论(0编辑  收藏  举报