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;
}

时间: 2024-11-05 18:43:44

hdu5012 圆环相交面积的相关文章

HDU 5120 Intersection (求圆环相交面积)

题意:给定圆环的内径r和外径R,以及2个相同圆环的圆心,求两个圆环的相交面积. 思路: S = A大B大 - A大B小 - A小B大 + A小B小.(A表示A环,大表示大圆,B同) 1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include

NYOJ 1186 心理阴影(两个圆环的相交面积)

心理阴影 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述       自从shanghai reginal后,zkc学长的心理就有了阴影.什么不敢水题,不敢gj,不敢放松...(各种不敢).同样的你们的zsj学长也是这样的.并且他们的心理阴影是一样一样的. 已知一个人的心理阴影为一个环形,那么求你们的zkc学长和zjs学长站在一起的时候的心理阴影的重叠面积. 输入 T组数据 r,R表示是内圆半径和外圆半径. x1,y1 zkc学长站的位置(抽象为一个点) x2,y2

HDOJ Intersection 5120【环相交面积】

Intersection Time Limit: 4000/4000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 949    Accepted Submission(s): 360 Problem Description Matt is a big fan of logo design. Recently he falls in love with logo made

HDU2056 Rectangles【水题】【相交面积】

Rectangles Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15823    Accepted Submission(s): 5061 Problem Description Given two rectangles and the coordinates of two points on the diagonals of e

多边形相交面积模板

1 /* 2 类型:多边形相交面积模板 3 */ 4 5 #include<cstdio> 6 #include<iostream> 7 #include<algorithm> 8 #include<cstring> 9 #include<cmath> 10 using namespace std; 11 #define maxn 510 12 const double eps=1E-8; 13 int sig(double d){ 14 ret

HDU 1798 两圆相交面积

Tell me the area Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1755    Accepted Submission(s): 535 Problem Description There are two circles in the plane (shown in the below picture), there is

HDU 3264 Open-air shopping malls(圆相交面积+二分)

HDU 3264 Open-air shopping malls(圆相交面积+二分) ACM 题目地址:HDU 3264 Open-air shopping malls 题意: 给出一些圆,选择其中一个圆的圆心为圆心,然后画一个大圆,要求大圆最少覆盖每个圆的一半面积.求最小面积. 分析: 枚举每个点,用二分求出需要的圆,更新最小值即可. 其中用到了圆相交面积,可以参考这题: POJ 2546 Circular Area(两个圆相交面积) 代码: /* * Author: illuz <iillu

poj2546Circular Area(两圆相交面积)

链接 画图推公式 这两种情况 都可用一种公式算出来 就是两圆都求出圆心角 求出扇形的面积减掉三角形面积 #include <iostream> using namespace std; #include<cmath> #include<iomanip> #include<algorithm> int main() { double d,t,t1,s,x,y,xx,yy,r,rr; while(cin>>x>>y>>r) {

hdu3060Area2(任意多边形相交面积)

链接 多边形的面积求解是通过选取一个点(通常为原点或者多边形的第一个点)和其它边组成的三角形的有向面积. 对于两个多边形的相交面积就可以通过把多边形分解为三角形,求出三角形的有向面积递加.三角形为凸多边形,因此可以直接用凸多边形相交求面积的模板. 凸多边形相交后的部分肯定还是凸多边形,所以只需要判断哪些点是相交部分上的点,最后求下面积. 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #inc