Gym-100935I Farm 计算几何 圆和矩形面积交

题面

题意:就是给你一个圆,和你一个矩形,求面积并,且 保证是一种情况:三角剖分后 一个点在圆内 两个在圆外

题解:可以直接上圆与凸多边形交的板子,也可以由这题实际情况,面积等于扇形减两个三角形

   

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int T;
 6     double dx,dy,yx,ux,uy,rx,ry,R;
 7     double s1,s2,s3,x1,y1,x2,y2,cosA;
 8     scanf("%d",&T);
 9     for (int i=1;i<=T;i++)
10     {
11         scanf("%lf%lf%lf",&rx,&ry,&R);
12         scanf("%lf%lf%lf%lf",&dx,&dy,&ux,&uy);
13         dx-=rx;ux-=rx;dy-=ry;uy-=ry;
14         x1=dx;
15         y1=-sqrt(R*R-x1*x1);
16         y2=uy;
17         x2=sqrt(R*R-y2*y2);
18         cosA=acos((x1*x2+y1*y2)/sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2)));
19         s1=R*R*cosA/2;
20         s2=x1*(y2-y1)/2;
21         s3=y2*(x1-x2)/2;
22         printf("Case %d: %.5lf
",i,s1-s2-s3);
23     }
24 }
 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 T,n=4;
75     double rx,ry,R;
76     scanf("%d",&T);
77     for (int ii=1;ii<=T;ii++)
78     {
79         scanf("%lf%lf%lf",&rx,&ry,&R);
80         scanf("%lf%lf%lf%lf",&p[1].x,&p[1].y,&p[3].x,&p[3].y);
81         p[2].x=p[1].x;p[2].y=p[3].y;
82         p[4].x=p[3].x;p[4].y=p[1].y;
83         p[5]=p[1];
84         Point O(rx,ry);
85         for (int i=1;i<=n+1;i++) p[i]=p[i]-O;
86         O=Point(0,0);
87         double sum=0;
88         for (int i=1;i<=n;i++)
89         {
90             int j=i+1;
91             double s=area(p[i],p[j],R);
92             if (cross(O,p[i],p[j])>0) sum+=s;else sum-=s;
93         }
94         printf("Case %d: %.5lf
",ii,fabs(sum));
95     }
96     return 0;
97 }
原文地址:https://www.cnblogs.com/qywhy/p/9772681.html