求两圆交点-角度-面积

#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <assert.h>
#include <queue>
#define mme(a,b) memset((a),(b),sizeof((a)))  
#define fuck(x) cout<<"* "<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
const double eps = 1e-10;
const int N = 1e3 + 7;
const double pi = acos(-1.0);
int n;
double R;
struct Point{
  double x,y;
  Point(double x=0,double y=0):x(x),y(y){}
}aa;
typedef Point Vector;
Vector operator +(Vector A,Vector B){
  return Vector(A.x+B.x,A.y+B.y);
}
Vector operator -(Vector A,Vector B){
  return Vector(A.x-B.x,A.y-B.y);
}
int dcmp(double x){
  if(fabs(x)<eps)return 0;else return x<0?-1:1;
}
bool operator ==(const Point &a,const Point &b){
  return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}

double Length(Point a,Point b){
  return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
struct Circle{
  Point c;
  double r;
  Circle(){}
  Circle(Point c,double r):c(c),r(r){}
  Point point(double a){
    return Point(c.x+cos(a)*r,c.y+sin(a)*r);
  }
};
double angle(Vector v){return atan2(v.y,v.x);}
int getCircleCircleIntersection(Circle c1,Circle c2,vector<Point>& sol){
  double d = Length(c1.c,c2.c);
  if(dcmp(d)==0){
    if(dcmp(c1.r-c2.r)==0)return -1;
    return 0;
  }
  if(dcmp(c1.r+c2.r-d)<0)return 0;
  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));
  Point p1=c1.point(a-da),p2=c1.point(a+da);
  sol.push_back(p1);
  if(p1==p2)return 1;
  sol.push_back(p2);
  return 2;
}
Circle cw[N];
double Dot(Point a,Point b){
  return a.x*b.x+a.y*b.y;
}
double hisLen(Point a){
  return sqrt(a.x*a.x+a.y*a.y);
}
double angle1(Point A,Point B){//求两向量夹角
  return acos(Dot(A,B)/hisLen(A)/hisLen(B));
}
int main(){
  int tim;
  scanf("%d",&tim);
  while(tim--){
    scanf("%d%lf",&n,&R);
    for(int i=1;i<=n;++i){
      double c;
      scanf("%lf%lf%lf",&aa.x,&aa.y,&c);
      cw[i].c=aa;cw[i].r=c;
    }
    cw[0].c=Point(0,0);cw[0].r=R;
    double ans=2*pi*R;
    for(int i=1;i<=n;++i){
      vector<Point>sol;
      int num = getCircleCircleIntersection(cw[0],cw[i],sol);
    }
  }
  return 0;
}
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <assert.h>
#include <queue>
#define mme(a,b) memset((a),(b),sizeof((a)))  
#define fuck(x) cout<<"* "<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef double DB;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-10;
const int N = 1e3 + 7;
const double pi = acos(-1.0);
int n;
double R;
struct lp{
  double x,y,r;
}cw[N];
int Area(int a1,int a2,double &ag1,double &ag2){
    double x1 = cw[a1].x, y1 = cw[a1].y;
    double x2 = cw[a2].x, y2 = cw[a2].y;
    double r1 = cw[a1].r, r2 = cw[a2].r;
    double d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    ag1=0;ag2=0;
    if(d+r1==r2||d+r2==r1)return 1;
    if(d>=r1+r2)return 0;
    else if(fabs(r1-r2)>=d){
      //两圆内含c1大/c2大
      //if(r1>r2)return PI*r2*r2;
      //else return PI*r1*r2;
      return 0;
    }else{
      //正弦定理求扇形圆心角
      ag1=2*acos((r1*r1+d*d-r2*r2)/(2*r1*d));
      ag2=2*acos((r2*r2+d*d-r1*r1)/(2*r2*d));
      return 2;
      //两个扇形面积和减去四边形的面积即为相交区域面积
      //四边形面积再转化为两个三角形的面积之和来计算
      //double ans=r1*r1*ag1/2+r2*r2*ag2/2-r1*r1*sin(ag1)/2-r2*r2*sin(ag2)/2;
      //return ans;
  }
}
int main(){
  int tim;
  scanf("%d",&tim);
  cw[0].x=cw[0].y=0;
  while(tim--){
    scanf("%d%lf",&n,&R);
    cw[0].r=R;
    for(int i=1;i<=n;++i){
      scanf("%lf%lf%lf",&cw[i].x,&cw[i].y,&cw[i].r);
    }
    double ans=2*pi*R,ag1=0,ag2=0;
    for(int i=1;i<=n;++i){
      int num = Area(0,i,ag1,ag2);
      if(num==1){
        double tmp=sqrt(cw[i].x*cw[i].x+cw[i].y*cw[i].y);
        if(tmp<R)ans+=2*pi*cw[i].r;
        continue;
      }
      if(num==0)continue;
      if(ag2>pi){
        ans+=ag2*cw[i].r;
        ans-=ag1*R;
      }else{
        ans+=ag2*cw[i].r;
        ans-=ag1*R;
      }
    }
    printf("%.14f\n", ans);
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/81453426