UVA 10652凸包+面的旋转

  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 }

 

posted @ 2014-02-28 13:00  little_w  阅读(260)  评论(0编辑  收藏  举报