zoukankan      html  css  js  c++  java
  • Gym

    题面

    题意:给你一个半圆,和另一个多边形(可凹可凸),求面积交

    题解:直接上板子,因为其实这个多边形不会穿过这个半圆,所以他和圆的交也就是和半圆的交

            打的时候队友说凹的不行,不是板题,后面想想,圆与多边形面积交本来就是拆成有向三角形做的,所以无论凹凸了

     1 #include<bits/stdc++.h>
     2 #define inf 1000000000000
     3 #define M 100009
     4 #define eps 1e-12
     5 #define PI acos(-1.0)
     6 using namespace std;
     7 struct Point
     8 {
     9     double x,y;
    10     Point(){}
    11     Point(double xx,double yy){x=xx;y=yy;}
    12     Point operator -(Point s){return Point(x-s.x,y-s.y);}
    13     Point operator +(Point s){return Point(x+s.x,y+s.y);}
    14     double operator *(Point s){return x*s.x+y*s.y;}
    15     double operator ^(Point s){return x*s.y-y*s.x;}
    16 }p[M];
    17 double max(double a,double b){return a>b?a:b;}
    18 double min(double a,double b){return a<b?a:b;}
    19 double len(Point a){return sqrt(a*a);}
    20 double dis(Point a,Point b){return len(b-a);}//两点之间的距离
    21 double cross(Point a,Point b,Point c)//叉乘
    22 {
    23     return (b-a)^(c-a);
    24 }
    25 double dot(Point a,Point b,Point c)//点乘 
    26 {
    27     return (b-a)*(c-a);
    28 }
    29 int judge(Point a,Point b,Point c)//判断c是否在ab线段上(前提是c在直线ab上)
    30 {
    31     if (c.x>=min(a.x,b.x)
    32        &&c.x<=max(a.x,b.x)
    33        &&c.y>=min(a.y,b.y)
    34        &&c.y<=max(a.y,b.y)) return 1;
    35     return 0;
    36 }
    37 double area(Point b,Point c,double r)
    38 {
    39     Point a(0.0,0.0);
    40     if(dis(b,c)<eps) return 0.0;
    41     double h=fabs(cross(a,b,c))/dis(b,c);
    42     if(dis(a,b)>r-eps&&dis(a,c)>r-eps)//两个端点都在圆的外面则分为两种情况
    43     {
    44         double angle=acos(dot(a,b,c)/dis(a,b)/dis(a,c));
    45         if(h>r-eps) return 0.5*r*r*angle;else 
    46         if(dot(b,a,c)>0&&dot(c,a,b)>0)
    47         {
    48             double angle1=2*acos(h/r);
    49             return 0.5*r*r*fabs(angle-angle1)+0.5*r*r*sin(angle1);
    50         }else return 0.5*r*r*angle;
    51     }else 
    52         if(dis(a,b)<r+eps&&dis(a,c)<r+eps) return 0.5*fabs(cross(a,b,c));//两个端点都在圆内的情况
    53         else//一个端点在圆上一个端点在圆内的情况
    54         {
    55             if(dis(a,b)>dis(a,c)) swap(b,c);//默认b在圆内
    56             if(fabs(dis(a,b))<eps) return 0.0;//ab距离为0直接返回0
    57             if(dot(b,a,c)<eps)
    58             {
    59                 double angle1=acos(h/dis(a,b));
    60                 double angle2=acos(h/r)-angle1;
    61                 double angle3=acos(h/dis(a,c))-acos(h/r);
    62                 return 0.5*dis(a,b)*r*sin(angle2)+0.5*r*r*angle3;
    63             }else
    64             {
    65                 double angle1=acos(h/dis(a,b));
    66                 double angle2=acos(h/r);
    67                 double angle3=acos(h/dis(a,c))-angle2;
    68                 return 0.5*r*dis(a,b)*sin(angle1+angle2)+0.5*r*r*angle3;
    69             }
    70         }
    71 }
    72 int main()
    73 {
    74     int n;
    75     double R;
    76     scanf("%d%lf",&n,&R);
    77     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    78     p[n+1]=p[1];
    79     Point O(0,0);
    80     for(int i=1;i<=n+1;i++) p[i]=p[i]-O;
    81     O=Point(0,0);
    82     double sum=0;
    83     for(int i=1;i<=n;i++)
    84     {
    85         int j=i+1;
    86         double s=area(p[i],p[j],R);
    87         if(cross(O,p[i],p[j])>0) sum+=s; else sum-=s;
    88     }
    89     printf("%.12lf
    ",fabs(sum));
    90     return 0;
    91 }
  • 相关阅读:
    ASP.NET Core真实管道详解[2]:Server是如何完成针对请求的监听、接收与响应的【上】
    ASP.NET Core真实管道详解[1]:中间件是个什么东西?
    .NET Core下的日志(3):如何将日志消息输出到控制台上
    “前.NET Core时代”如何实现跨平台代码重用 ——程序集重用
    “前.NET Core时代”如何实现跨平台代码重用 ——源文件重用
    .NET Core下的日志(2):日志模型详解
    .NET Core下的日志(1):记录日志信息
    ASP.NET Core 1.0中实现文件上传的两种方式(提交表单和采用AJAX)
    ASP.NET Core管道深度剖析[共4篇]
    ASP.NET Core管道深度剖析(4):管道是如何建立起来的?
  • 原文地址:https://www.cnblogs.com/qywhy/p/10592069.html
Copyright © 2011-2022 走看看