Gym - 101208J 2013 ACM-ICPC World Finals J.Pollution Solution 圆与多边形面积交

题面

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

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

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

 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\n",fabs(sum));
90     return 0;
91 }

 

转载于:https://www.cnblogs.com/qywhy/p/10592069.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值