poj 1279 -- Art Gallery (半平面交)

鏈接:http://poj.org/problem?id=1279

Art Gallery
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 5337   Accepted: 2277

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

 
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
这道题好坑的,题目根本没题给定的点有序,然后大家就一起照有序的来做了
自己写了个排序的,发现不行,如果默认有序,再去排序,就会得到错误的结
果,主要是极角排序,是根据角度,一点点逆时针移动,会使原多边形改变形
状,进而求出错误的结果。不知道有没有办法去解决这个问题
 
一下是错误排序代码:
  1 #include <stdio.h>
  2 #include <math.h>
  3 #include <string.h>
  4 #include <stdlib.h>
  5 #include <iostream>
  6 #include <algorithm>
  7 
  8 #define eps 1e-8
  9 #define MAXX 1510
 10 
 11 typedef struct point
 12 {
 13     double x;
 14     double y;
 15 }point;
 16 
 17 point p[MAXX],s[MAXX];
 18 
 19 using namespace std;
 20 bool dy(double x,double y)
 21 {
 22     return x>y+eps;
 23 }
 24 bool xy(double x,double y)
 25 {
 26     return x<y-eps;
 27 }
 28 bool dyd(double x,double y)
 29 {
 30     return x>y-eps;
 31 }
 32 bool xyd(double x,double y)
 33 {
 34     return x<y+eps;
 35 }
 36 bool dd(double x,double y)
 37 {
 38     return fabs(x-y)<eps;
 39 }
 40 
 41 double crossProduct(point a,point b,point c)
 42 {
 43     return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
 44 }
 45 
 46 point IntersectPoint(point u1,point u2,point v1,point v2)
 47 {
 48     point ans=u1;
 49     double t = ((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/
 50         ((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
 51     ans.x += (u2.x-u1.x)*t;
 52     ans.y += (u2.y-u1.y)*t;
 53     return ans;
 54 }
 55 
 56 double Area(point p[],int n)
 57 {
 58     double ans=0.0;
 59     for(int i=1; i<n-1; i++)
 60     {
 61         ans += crossProduct(p[0],p[i],p[i+1]);
 62     }
 63     return fabs(ans)/2.0;
 64 }
 65 
 66 double dist(point a,point b)
 67 {
 68     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 69 }
 70 
 71 bool cmp(point a,point b)
 72 {
 73     double tmp=crossProduct(p[0],a,b);
 74     if(dd(tmp,0.0))
 75         return dy(dist(p[0],a),dist(p[0],b));
 76     return xy(tmp,0.0);
 77 }
 78 
 79 point Getsort(int n)
 80 {
 81     int tmp=0;
 82     for(int i=1; i<n; i++)
 83     {
 84         if(xy(p[i].x,p[tmp].x) || dd(p[i].x,p[tmp].x)&&xy(p[i].y,p[tmp].y))
 85         {
 86             tmp=i;
 87         }
 88     }//                           printf("%d^^",tmp);
 89     swap(p[0],p[tmp]);
 90     sort(p+1,p+n,cmp);
 91 }
 92 
 93 void cut(point p[],point s[],int n,int &len)
 94 {
 95     point tp[MAXX];
 96     p[n]=p[0];
 97     for(int i=0; i<=n; i++)
 98     {
 99         tp[i]=p[i];
100     }
101     int cp=n,tc;
102     for(int i=0; i<n; i++)
103     {
104         tc=0;
105         for(int k=0; k<cp; k++)
106         {
107             if(xyd(crossProduct(p[i],p[i+1],tp[k]),0.0))
108                 s[tc++]=tp[k];
109             if(xy(crossProduct(p[i],p[i+1],tp[k])*
110                   crossProduct(p[i],p[i+1],tp[k+1]),0.0))
111                 s[tc++]=IntersectPoint(p[i],p[i+1],tp[k],tp[k+1]);
112         }
113         s[tc]=s[0];
114         for(int k=0; k<=tc; k++)
115             tp[k]=s[k];
116         cp=tc;
117     }
118     len=cp;
119 }
120 
121 int main()
122 {
123     int t,n,m,i,j;
124     scanf("%d",&t);
125     while(t--)
126     {
127         scanf("%d",&n);
128         for(i=0; i<n; i++)
129         {
130             scanf("%lf%lf",&p[i].x,&p[i].y);
131         }
132         //point tmp=IntersectPoint(p[0],p[1],p[2],p[3]);
133         //printf("%lf %lf
",tmp.x,tmp.y);
134         Getsort(n);//for(i=0; i<n; i++)printf("%lf**%lf*
",p[i].x,p[i].y);
135         int len;
136         cut(p,s,n,len);//for(i=0; i<len; i++)printf("%lf==%lf=
",s[i].x,s[i].y);
137         double area=Area(s,len);
138         printf("%.2lf
",area);
139     }
140     return 0;
141 }
View Code

利用面积正负来判断顺or逆,这种代码是以逆时针为主,我的面积顺时针为正,

需要改变方向 

这是AC代码:
  1 #include <stdio.h>
  2 #include <math.h>
  3 #include <string.h>
  4 #include <stdlib.h>
  5 #include <iostream>
  6 #include <algorithm>
  7 
  8 #define eps 1e-8
  9 #define MAXX 1510
 10 
 11 typedef struct point
 12 {
 13     double x;
 14     double y;
 15 }point;
 16 
 17 point p[MAXX],s[MAXX];
 18 
 19 using namespace std;
 20 bool dy(double x,double y)
 21 {
 22     return x>y+eps;
 23 }
 24 bool xy(double x,double y)
 25 {
 26     return x<y-eps;
 27 }
 28 bool dyd(double x,double y)
 29 {
 30     return x>y-eps;
 31 }
 32 bool xyd(double x,double y)
 33 {
 34     return x<y+eps;
 35 }
 36 bool dd(double x,double y)
 37 {
 38     return fabs(x-y)<eps;
 39 }
 40 
 41 double crossProduct(point a,point b,point c)
 42 {
 43     return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
 44 }
 45 
 46 point IntersectPoint(point u1,point u2,point v1,point v2)
 47 {
 48     point ans=u1;
 49     double t = ((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))/
 50         ((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
 51     ans.x += (u2.x-u1.x)*t;
 52     ans.y += (u2.y-u1.y)*t;
 53     return ans;
 54 }
 55 
 56 double Area(point p[],int n)
 57 {
 58     double ans=0.0;
 59     p[n]=p[0];
 60     point tmp;
 61     tmp.x=0,tmp.y=0;
 62     for(int i=0; i<n; i++)
 63     {
 64         ans += crossProduct(tmp,p[i],p[i+1]);
 65     }
 66     return ans/2.0;
 67 }
 68 
 69 void changeWise(point p[],int n)
 70 {
 71     for(int i=0; i<n/2; i++)
 72         swap(p[i],p[n-i-1]);
 73 }
 74 
 75 double dist(point a,point b)
 76 {
 77     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 78 }
 79 /*
 80 bool cmp(point a,point b)
 81 {
 82     double tmp=crossProduct(p[0],a,b);
 83     if(dd(tmp,0.0))
 84         return dy(dist(p[0],a),dist(p[0],b));
 85     return xy(tmp,0.0);
 86 }
 87 
 88 point Getsort(int n)
 89 {
 90     int tmp=0;
 91     for(int i=1; i<n; i++)
 92     {
 93         if(xy(p[i].x,p[tmp].x) || dd(p[i].x,p[tmp].x)&&xy(p[i].y,p[tmp].y))
 94         {
 95             tmp=i;
 96         }
 97     }//                           printf("%d^^",tmp);
 98     swap(p[0],p[tmp]);
 99     sort(p+1,p+n,cmp);
100 }
101 */
102 void cut(point p[],point s[],int n,int &len)
103 {
104     point tp[MAXX];
105     p[n]=p[0];
106     for(int i=0; i<=n; i++)
107     {
108         tp[i]=p[i];
109     }
110     int cp=n,tc;
111     for(int i=0; i<n; i++)
112     {
113         tc=0;
114         for(int k=0; k<cp; k++)
115         {
116             if(xyd(crossProduct(p[i],p[i+1],tp[k]),0.0))
117                 s[tc++]=tp[k];
118             if(xy(crossProduct(p[i],p[i+1],tp[k])*
119                   crossProduct(p[i],p[i+1],tp[k+1]),0.0))
120                 s[tc++]=IntersectPoint(p[i],p[i+1],tp[k],tp[k+1]);
121         }
122         s[tc]=s[0];
123         for(int k=0; k<=tc; k++)
124             tp[k]=s[k];
125         cp=tc;
126     }
127     len=cp;
128 }
129 
130 int main()
131 {
132     int t,n,m,i,j;
133     scanf("%d",&t);
134     while(t--)
135     {
136         scanf("%d",&n);
137         for(i=0; i<n; i++)
138         {
139             scanf("%lf%lf",&p[i].x,&p[i].y);
140         }
141         double tmp=Area(p,n);
142         if(dy(tmp,0.0))
143             changeWise(p,n);
144         //point tmp=IntersectPoint(p[0],p[1],p[2],p[3]);
145         //printf("%lf %lf
",tmp.x,tmp.y);
146         //Getsort(n);for(i=0; i<n; i++)printf("%lf**%lf*
",p[i].x,p[i].y);
147         int len;
148         cut(p,s,n,len);//for(i=0; i<len; i++)printf("%lf==%lf=
",s[i].x,s[i].y);
149         double area=Area(s,len);
150         printf("%.2lf
",fabs(area));
151     }
152     return 0;
153 }
View Code
原文地址:https://www.cnblogs.com/ccccnzb/p/3944997.html