POJ 1279 半平面交

题意:
求一任意多边形的核的面积

 

题解:

半平面交。第一次搞。。。找了半天错,又和题解一样了。

 

View Code
  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <cmath>
  7 
  8 #define N 2222
  9 #define EPS 1e-7
 10 #define INF 1e9
 11 
 12 using namespace std;
 13 
 14 struct PO
 15 {
 16     double x,y;
 17 }p[N],tp[N],s[N],o;
 18 
 19 int n;
 20 
 21 inline void read()
 22 {
 23     scanf("%d",&n);
 24     for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
 25     p[n+1]=p[1];
 26 }
 27 
 28 inline PO operator -(PO a,PO b)
 29 {
 30     PO c;
 31     c.x=a.x-b.x;
 32     c.y=a.y-b.y;
 33     return c;
 34 }
 35 
 36 inline int dc(double x)
 37 {
 38     if(x>EPS) return 1;
 39     else if(x<-EPS) return -1;
 40     return 0;
 41 }
 42 
 43 inline double cross(PO &a,PO &b,PO &c)
 44 {
 45     return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
 46 }
 47 
 48 inline double getarea(PO *a,int n)//多边形面积,逆时针为正 
 49 {
 50     double res=0.0;
 51     for(int i=1;i<=n;i++) res+=cross(o,a[i],a[i+1]);
 52     return res*0.5;
 53 }
 54 
 55 inline PO getpoint(PO &a,PO &b,PO &c,PO &d)//直线交点 
 56 {
 57     PO ans,tp=b-a;
 58     double k1=cross(a,d,c);
 59     double k2=cross(b,c,d);
 60     ans.x=a.x+tp.x*k1/(k1+k2);
 61     ans.y=a.y+tp.y*k1/(k1+k2);
 62     return ans;
 63 }
 64 
 65 inline void change()//变顺时针为逆时针 
 66 {
 67     for(int i=1;i<=(n>>1);i++) swap(p[i],p[n-i+1]);
 68     p[n+1]=p[1];
 69 }
 70 
 71 void prt(PO a)
 72 {
 73     printf("%lf   %lf\n",a.x,a.y);
 74 }
 75 
 76 inline void getcut()
 77 {
 78     tp[1].x=tp[5].x=-INF,tp[1].y=tp[5].y=-INF;
 79     tp[2].x=INF,tp[2].y=-INF;
 80     tp[3].x=INF,tp[3].y=INF;
 81     tp[4].x=-INF,tp[4].y=INF;
 82     
 83     int cp=4,tc;
 84     for(int i=1;i<=n;i++)
 85     {
 86         tc=0;
 87         for(int j=1;j<=cp;j++)
 88         {
 89             if(dc(cross(p[i],p[i+1],tp[j]))>=0) s[++tc]=tp[j];
 90             if(dc(cross(p[i],p[i+1],tp[j])*cross(p[i],p[i+1],tp[j+1]))<0)
 91                 s[++tc]=getpoint(p[i],p[i+1],tp[j],tp[j+1]);
 92         }
 93         s[tc+1]=s[1];
 94         for(int j=1;j<=tc+1;j++) tp[j]=s[j];
 95         cp=tc;
 96     }
 97     n=cp;
 98 }
 99 
100 inline void go()
101 {
102     if(dc(getarea(p,n))<=0) change();
103     getcut();
104     printf("%.2lf\n",fabs(getarea(s,n)));
105 }
106 
107 int main()
108 {
109     int cas; scanf("%d",&cas);
110     while(cas--) read(),go();
111     return 0;
112 }

 

 

posted @ 2013-02-26 23:36  proverbs  阅读(215)  评论(0编辑  收藏  举报