1 /*
2
3 UVA 10652计算几何
4 凸包+面的旋转
5 就凸包部分而言,是模板。
6 这道题有个小障碍,就是有确定的图形中心点和转动角度,确定转动后的顶点的坐标。
7 我的方法是,先转动中心点向顶点的向量,再中心加上这个向量。这应该是普适的。
8 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <math.h>
13 #include <ctype.h>
14 #include <string>
15 #include <iostream>
16 #include <sstream>
17 #include <vector>
18 #include <queue>
19 #include <stack>
20 #include <map>
21 #include <list>
22 #include <set>
23 #include <algorithm>
24 #define INF 0x3f3f3f3f
25 #define eps 1e-7
26 #define eps2 1e-3
27 #define zero(x) (((x)>0?(x):-(x))<eps)
28 using namespace std;
29
30
31 struct Point
32 {
33 double x,y;
34 Point() {}
35 Point(double xx,double yy)
36 {
37 x=xx;
38 y=yy;
39 }
40 bool operator<(const Point& p) const{
41 if (x==p.x) return y<p.y;
42 else return x<p.x;
43 }
44 }P1[2505],P2[2505];
45
46 typedef Point Vector;
47
48 bool operator==(Point A,Point B)
49 {
50 if ((fabs(A.x-B.x)<eps) && (fabs(A.y-B.y)<eps)) return true;
51 else return false;
52 }
53 Vector operator-(Point A,Point B)//表示A指向B
54 {
55 return Vector(A.x-B.x,A.y-B.y);
56 }
57 Vector operator*(Vector A,double k)
58 {
59 return Vector(A.x*k,A.y*k);
60 }
61 Vector operator+(Point A,Point B)//表示A指向B
62 {
63 return Vector(B.x+A.x,B.y+A.y);
64 }
65 double Dot(Vector A,Vector B)
66 {
67 return A.x*B.x+A.y*B.y;
68 }
69 double Length(Vector A)
70 {
71 return sqrt(Dot(A,A));
72 }
73 double Cross(Vector A,Vector B)
74 {
75 return A.x*B.y-A.y*B.x;
76 }
77 double Area2(Point A,Point B,Point C)
78 {
79 return Cross(B-A,C-A);
80 }
81 int dcmp(double x)
82 {
83 if(fabs(x)<eps) return 0;
84 else if(x>0) return 1;
85 else return -1;
86 }
87 double angle(Vector v)
88 {
89 return atan2(v.y,v.x);
90 }
91 Vector Rotate(Vector A,double rad)//向量向逆时针旋转
92 {
93 return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
94 }
95
96 //p是原先点的数组,n是个数,ch是凸包的点集
97 //精度要求高是用dcmp比较
98 //返回凸包点的个数
99 int ConvexHull(Point *p, int n, Point* ch){ //求凸包
100 sort(p, p + n);//先按照x,再按照y
101 int m = 0;
102 for(int i = 0; i < n; i++){
103 while(m > 1 && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) < 0) m--;
104 ch[m++] = p[i];
105 }
106 int k = m;
107 for(int i = n-2; i >= 0; i--){
108 while(m > k && Cross(ch[m-1] - ch[m-2], p[i] - ch[m-2]) < 0) m--;
109 ch[m++] = p[i];
110 }
111 if(n > 1) m--;
112 return m;
113 }
114 double ConvexPolygonArea(Point *p, int n){//凸包面积
115 double area = 0;
116 for(int i = 1; i < n-1; i++) area += Area2(p[0], p[i], p[i+1]);
117 return area / 2;
118 }
119
120 double x,y,w,h,arf;
121 int t,n,cnt1,cnt2;
122 int main()
123 {
124 cin>>t;
125 while(t--)
126 {
127 double area1=0,area2=0;
128 cnt1=0;
129 cin>>n;
130 for(int i=0;i<n;i++)
131 {
132 cin>>x>>y>>w>>h>>arf;
133 arf=arf/180*M_PI;
134 area1+=w*h;
135 Vector v[4];//四个方向上的向量
136 v[0].x=w/2;v[0].y=h/2;
137 v[1].x=-w/2;v[1].y=h/2;
138 v[2].x=-w/2;v[2].y=-h/2;
139 v[3].x=w/2;v[3].y=-h/2;
140 for(int j=0;j<4;j++)//构造4个顶点
141 {
142 Vector nv=Rotate(v[j],2*M_PI-arf);
143 P1[cnt1].x=nv.x+x;
144 P1[cnt1++].y=nv.y+y;
145 }
146 }
147 sort(P1,P1+cnt1);
148 int cnt2=ConvexHull(P1,cnt1,P2);
149 area2=ConvexPolygonArea(P2,cnt2);
150 double ans=area1/area2*100;
151 printf("%.1lf %%\n",ans);
152 }
153 return 0;
154 }