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)\n", 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\n",ans+eps);
266 }
267 return 0;
268 }