zoukankan      html  css  js  c++  java
  • HDU5130 Signal Interference

      1 /*
      2  HDU5130 Signal Interference
      3  http://acm.hdu.edu.cn/showproblem.php?pid=5130
      4  计算几何 圆与多边形面积交
      5  *
      6  */
      7 
      8 
      9 #include <cstdio>
     10 #include <algorithm>
     11 #include <cmath>
     12 using namespace std;
     13 const double Pi=acos(-1.0);
     14 const double eps = 1e-8;
     15 const int Nmax=1005;
     16 double k;
     17 int sgn(double x)
     18 { 
     19     if(x<-eps)
     20         return -1;
     21     if(x>eps)
     22         return 1;
     23     return 0;
     24 }
     25 double Abs(double x)
     26 {
     27     if(sgn(x)<0)
     28         x=-x;
     29     else if(sgn(x)==0)
     30         x=0.0;
     31     return x;
     32 }
     33 double sqr(double x)
     34 {
     35     return x*x;
     36 }
     37 double Sqrt(double x) 
     38 { 
     39     return max(0.0,sqrt(x)); 
     40 }
     41 struct Pt 
     42 {
     43     double x,y;
     44     Pt() { }
     45     Pt(double x, double y) : x(x), y(y) { }
     46     
     47     Pt operator - (const Pt &b)
     48     {
     49         return Pt(x-b.x,y-b.y);
     50     }
     51     Pt operator + (const Pt &b)
     52     {
     53         return Pt(x+b.x,y+b.y);
     54     }
     55     friend Pt operator * (double a,Pt p)
     56     {
     57         return Pt(p.x*a,p.y*a);
     58     }
     59     friend Pt operator * (Pt p,double a)
     60     {
     61         return Pt(p.x*a,p.y*a);
     62     }
     63     friend Pt operator / (Pt p,double a)
     64     {
     65         return Pt(p.x/a,p.y/a);
     66     }
     67     double norm()
     68     { 
     69         return Sqrt(x*x + y*y); 
     70     }
     71     double len()
     72     {
     73         return norm();
     74     }
     75     void print() 
     76     { 
     77         printf("(%f, %f)
    ", x, y); 
     78     }
     79 };
     80 int n;
     81 Pt pl[Nmax];
     82 Pt pr,A,B,p0,p1;
     83 double dist (Pt a, Pt b) 
     84 {    
     85     return (a-b).norm(); 
     86 }
     87 double dot(Pt a,Pt b)//点乘 
     88 {
     89     return a.x*b.x+a.y*b.y; 
     90 }
     91 double det(Pt a,Pt b)
     92 {
     93     return a.x*b.y-a.y*b.x;
     94 }
     95 Pt rotate(Pt p,double a)//P点绕原点逆时针旋转a弧度
     96 {
     97     return Pt(p.x*cos(a)-p.y*sin(a),p.x*sin(a)+p.y*cos(a));
     98 }
     99 struct Sg//线段 
    100 {
    101     Pt s, t;
    102     Sg() { }
    103     Sg(Pt s, Pt t) : s(s), t(t) { }
    104     Sg(double a, double b, double c, double d) : s(a, b), t(c, d) { }
    105 };
    106 bool PtOnSegment(Pt p, Pt a, Pt b) //p是否在线段ab上,把<=改成<就能实现不含线段端点的点在线段上的判断。
    107 {
    108     return !sgn(det(p-a, b-a)) && sgn(dot(p-a, p-b)) <= 0;
    109 }
    110 bool PtOnLine(Pt p, Pt a, Pt b) //p是否在直线ab上
    111 {
    112     return !sgn(det(p-a, b-a));
    113 }
    114 Pt PtLineProj(Pt s, Pt t, Pt p) //p到直线st的投影
    115 {
    116     double r = dot(p-s, t-s) / (t - s).norm();
    117     return s + (t - s) * r;
    118 }
    119 bool parallel(Pt a, Pt b, Pt s, Pt t) 
    120 {
    121     return !sgn(det(a-b, s-t));
    122 }
    123 Pt triangleMassCenter(Pt a, Pt b, Pt c) 
    124 {
    125     return (a+b+c) / 3.0;
    126 }
    127 double polygon_area(Pt poly[],int n)
    128 {
    129     double ans=0.0;
    130     if(n<3)
    131         return ans;
    132     for(int i=1;i<=n;i++)
    133         ans+=det(poly[i],poly[i%n+1]);
    134     return ans*0.5;
    135 }
    136 
    137 struct Circle
    138 {
    139     Pt c;
    140     double r;
    141     Circle(Pt _c,double _r)
    142     {
    143         c=_c;
    144         r=_r;
    145     }
    146 };
    147 bool PointInCircle(Circle a,Pt p)
    148 {
    149     Pt c=a.c;
    150     return sgn( (p-c).norm()-a.r )<0;
    151 }
    152 
    153 bool PointOnCircle(Circle a,Pt p)
    154 {
    155     Pt c=a.c;
    156     return sgn( (p-c).norm()-a.r )==0;
    157 }
    158 
    159 bool PointIOCircle(Circle a,Pt p)
    160 {
    161     Pt c=a.c;
    162     return sgn( (p-c).norm()-a.r )<=0;
    163 }
    164 
    165 void circle_cross_line(Circle c,Pt a, Pt b, Pt ans[], int &num)
    166 {
    167     double x1=a.x,y1=a.y,x2=b.x,y2=b.y;
    168     double dx=x2-x1,dy=y2-y1;
    169     double tmpx=x1-c.c.x,tmpy=y1-c.c.y;
    170     double A=dx*dx+dy*dy;
    171     double B=2.0*( dx*tmpx+dy*tmpy );
    172     double C=tmpx*tmpx+tmpy*tmpy-c.r*c.r;
    173     double delta=B*B-4.0*A*C;
    174     num=0;
    175     if(sgn(delta)<0)
    176         return;
    177     double t1=(-B-Sqrt(delta))/(2.0*A);
    178     double t2=(-B+Sqrt(delta))/(2.0*A);
    179     if(sgn(t1-1.0)<=0 && sgn(t1)>=0)
    180         ans[++num]=Pt(x1+t1*dx,y1+t1*dy);
    181     if(sgn(delta)==0)
    182         return;
    183     if(sgn(t2-1.0)<=0 && sgn(t2)>=0)
    184         ans[++num]=Pt(x1+t2*dx,y1+t2*dy);
    185 }   
    186 
    187 double sector_area(Circle c,Pt a,Pt b)
    188 {
    189     a=a-c.c,b=b-c.c;
    190     double theta = atan2(a.y, a.x) - atan2(b.y, b.x);
    191     while (sgn(theta) <= 0) theta += 2.0*Pi;
    192     while (sgn(theta-2.0*Pi)>0) theta -= 2.0*Pi;
    193     theta = min(theta, 2.0*Pi - theta);
    194     return c.r*c.r*theta*0.5;
    195 }
    196 
    197 double CirclePolyArea(Circle c,Pt poly[],int n)
    198 {
    199     double ans=0.0;
    200     Pt p[3];
    201     int num;
    202     for(int i=1;i<=n;i++)
    203     {
    204         Pt a=poly[i],b=poly[i%n+1];
    205         int ina=PointInCircle(c,a);
    206         int inb=PointInCircle(c,b);
    207         Pt da=a-c.c,db=b-c.c;
    208         int s=sgn(det(da,db));
    209         double part=0.0;
    210         if(ina)
    211         {
    212             if(inb)
    213             {
    214                 part=Abs(det(da,db))*0.5;
    215             }
    216             else
    217             {
    218                 circle_cross_line(c,a,b,p,num);
    219                 part=sector_area(c,p[1],b)+Abs(det(da,p[1]-c.c))*0.5;
    220             }
    221         }
    222         else
    223         {
    224             if(inb)
    225             {
    226                 circle_cross_line(c,a,b,p,num);
    227                 part=sector_area(c,p[1],a)+Abs(det(db,p[1]-c.c))*0.5;
    228             }
    229             else
    230             {
    231                 circle_cross_line(c,a,b,p,num);
    232                 if(num==2)
    233                 {
    234                     part=sector_area(c,a,p[1])+sector_area(c,b,p[2])+Abs(det(p[1]-c.c,p[2]-c.c))*0.5;
    235                 }
    236                 else
    237                 {
    238                     part=sector_area(c,a,b);
    239                 }
    240             }
    241         }
    242         if(s!=0)
    243             ans+=1.0*s*part;
    244     }
    245     return ans;
    246 }
    247 int main()
    248 {
    249    int t=0;
    250     while(scanf("%d%lf",&n,&k)==2)
    251     {
    252         t++;
    253         for(int i=1;i<=n;i++)
    254             scanf("%lf%lf",&pl[i].x,&pl[i].y);
    255         scanf("%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y);
    256         double r;
    257         double E=(2.0*B.x-2.0*sqr(k)*A.x)/(1.0-sqr(k));  
    258         double F=(2.0*B.y-2.0*sqr(k)*A.y)/(1.0-sqr(k));  
    259         double G=(sqr(k*A.x)+sqr(k*A.y)-sqr(B.x)-sqr(B.y))/(1.0-sqr(k));  
    260         pr.x=E/2.0,pr.y=F/2.0;  
    261         r=Sqrt(G+sqr(E)/4.0+sqr(F)/4.0);  
    262         Circle C(pr,r);
    263         double ans=Abs( CirclePolyArea(C,pl,n) );
    264         printf("Case %d: ",t);
    265         printf("%.10f
    ",ans+eps);
    266     }
    267     return 0;
    268 }
  • 相关阅读:
    浅入了解GCD 并发 并行 同步 异步 多线程
    XSD
    想在Images.xcassets 只能用 imageNamed 加载里边的素材 其他方法 你就别费老劲了
    如何在SCENEKIT使用SWIFT RUNTIME动态加载COLLADA文件
    编译 wxWidgets3.0.2 on Mac OS X Yosemite 出错?!的解决方法
    3、技术积累方面总结
    2、日常计划管理总结
    站在客户的角度考虑问题
    公司管理的一点思虑
    项目管理一定要规范阿
  • 原文地址:https://www.cnblogs.com/BBBob/p/6624847.html
Copyright © 2011-2022 走看看