Hdu-2892 area 计算几何 圆与凸多边形面积交

题面

题意:有一个凸多边形岛屿,然后告诉你从高空(x,y,h)投下炸弹,爆炸半径r,飞机水平速度和重力加速度,问岛屿被炸了多少

题解:算出来岛屿落地位置,再利用圆与凸多边形面积交

 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     double x,y,h,x1,y1,R;
75     while(scanf("%lf%lf%lf",&x,&y,&h)!=-1)
76     {
77         scanf("%lf%lf%lf",&x1,&y1,&R);
78         int n;
79         scanf("%d",&n);
80         for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
81         p[n+1]=p[1];
82         double V=sqrt(2*10*h);
83         double t0=V/10;
84         double x0=x+x1*t0;
85         double y0=y+y1*t0;
86         Point O(x0,y0);
87         for(int i=1;i<=n+1;i++) p[i]=p[i]-O;
88         O=Point(0,0);
89         double sum=0;
90         for(int i=1;i<=n;i++)
91         {
92             int j=i+1;
93             double s=area(p[i],p[j],R);
94             if(cross(O,p[i],p[j])>0) sum+=s; else sum-=s;
95         }
96         printf("%.2lf
",fabs(sum));
97     }
98     return 0;
99 }
原文地址:https://www.cnblogs.com/qywhy/p/9772742.html