【POJ】【2068】Art Gallery
计算几何/半平面交
裸的半平面交,关于半平面交的入门请看神犇博客:http://blog.csdn.net/accry/article/details/6070621
然而代码我是抄的proverbs的……
大体思路是这样的:(一个增量算法)
维护一个当前的半平面交的点集,每次用一条直线去cut它:
依次枚举“凸包”上的点,点在直线左边则保留下来了,否则就丢掉=。=
同时判一下如果“凸包”上连续的两个点分别在直线两侧,就加入这条“凸包”上的线段与直线的交点= =
然后新点集get!
最后求个面积>_>
有个trick是如果给的顺序是顺时针,需要反转成逆时针(用算多边形面积的方法就可以判断,如果是逆时针,面积为正)
1 Source Code 2 Problem: 1279 User: sdfzyhy 3 Memory: 720K Time: 32MS 4 Language: G++ Result: Accepted 5 6 Source Code 7 8 //POJ 1279 9 #include<cmath> 10 #include<vector> 11 #include<cstdio> 12 #include<cstring> 13 #include<cstdlib> 14 #include<iostream> 15 #include<algorithm> 16 #define rep(i,n) for(int i=0;i<n;++i) 17 #define F(i,j,n) for(int i=j;i<=n;++i) 18 #define D(i,j,n) for(int i=j;i>=n;--i) 19 #define pb push_back 20 using namespace std; 21 inline int getint(){ 22 int v=0,sign=1; char ch=getchar(); 23 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 24 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 25 return v*sign; 26 } 27 const int N=1e5+10; 28 const double INF=1e9; 29 typedef long long LL; 30 /******************tamplate*********************/ 31 const double eps=1e-8; 32 int dcmp(double x){return x>eps ? 1 : x<-eps ? -1 : 0;} 33 struct Poi{ 34 double x,y; 35 Poi(){} 36 Poi(double x,double y):x(x),y(y){} 37 void read(){scanf("%lf%lf",&x,&y);} 38 }p[N],tp[N],s[N],o; 39 typedef Poi Vec; 40 Vec operator - (const Poi&a,const Poi &b){return Vec(a.x-b.x,a.y-b.y);} 41 42 int n; 43 double Cross(const Vec &a,const Vec &b){return a.x*b.y-a.y*b.x;} 44 double getarea(Poi *p,int n){ 45 double ans=0.0; 46 F(i,1,n) ans+=Cross(p[i]-o,p[i+1]-o); 47 return ans*0.5; 48 } 49 Poi getpoint(const Poi &a,const Poi &b,const Poi &c,const Poi &d){ 50 Poi ans,tmp=b-a; 51 double k1=Cross(d-a,c-a),k2=Cross(c-b,d-b); 52 ans.x=a.x+tmp.x*k1/(k1+k2); 53 ans.y=a.y+tmp.y*k1/(k1+k2); 54 return ans; 55 } 56 57 void init(){ 58 n=getint(); 59 F(i,1,n) p[i].read(); 60 p[n+1]=p[1]; 61 } 62 void Change(){ 63 F(i,1,n>>1) swap(p[i],p[n-i+1]); 64 p[n+1]=p[1]; 65 } 66 void getcut(){ 67 tp[1]=tp[5]=Poi(-INF,-INF); 68 tp[2]=Poi(INF,-INF); 69 tp[3]=Poi(INF,INF); 70 tp[4]=Poi(-INF,INF); 71 int num=4,size=0; 72 F(i,1,n){ 73 size=0; 74 F(j,1,num){ 75 if (dcmp(Cross(p[i+1]-p[i],tp[j]-p[i]))>=0) 76 s[++size]=tp[j]; 77 if (dcmp(Cross(p[i+1]-p[i],tp[j]-p[i]) * 78 Cross(p[i+1]-p[i],tp[j+1]-p[i]))<0) 79 s[++size]=getpoint(p[i],p[i+1],tp[j],tp[j+1]); 80 } 81 s[size+1]=s[1]; 82 F(j,1,size+1) tp[j]=s[j]; 83 num=size; 84 } 85 n=num; 86 } 87 int main(){ 88 #ifndef ONLINE_JUDGE 89 freopen("1279.in","r",stdin); 90 freopen("1279.out","w",stdout); 91 #endif 92 int T=getint(); 93 while(T--){ 94 init(); 95 if (dcmp(getarea(p,n))<=0) Change(); 96 getcut(); 97 printf("%.2f\n",fabs(getarea(s,n))); 98 } 99 return 0; 100 }
Art Gallery
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 5805 | Accepted: 2455 |
Description
The art galleries of the new and very futuristic building of the Center for Balkan Cooperation have the form of polygons (not necessarily convex). When a big exhibition is organized, watching over all of the pictures is a big security concern. Your task is that for a given gallery to write a program which finds the surface of the area of the floor, from which each point on the walls of the gallery is visible. On the figure 1. a map of a gallery is given in some co-ordinate system. The area wanted is shaded on the figure 2.
Input
The
number of tasks T that your program have to solve will be on the first
row of the input file. Input data for each task start with an integer N,
5 <= N <= 1500. Each of the next N rows of the input will contain
the co-ordinates of a vertex of the polygon ? two integers that fit in
16-bit integer type, separated by a single space. Following the row with
the co-ordinates of the last vertex for the task comes the line with
the number of vertices for the next test and so on.
Output
For
each test you must write on one line the required surface - a number
with exactly two digits after the decimal point (the number should be
rounded to the second digit after the decimal point).
Sample Input
1 7 0 0 4 4 4 7 9 7 13 -1 8 -6 4 -4
Sample Output
80.00
Source
[Submit] [Go Back] [Status] [Discuss]