poj2451Uyuw's Concert(半平面交)

链接

逆时针给出线段,如果模板是顺时针的修改下系数的符号进行平面交即可。

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 20100
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 int m;
 18 int cCnt,curCnt;
 19 struct point
 20 {
 21     double x,y;
 22     point(double x=0,double y =0 ):x(x),y(y) {}
 23 };
 24 point points[N],p[N],q[N];
 25 void getline(point x,point y,double &a,double &b,double   &c)
 26 {
 27     a = x.y - y.y;
 28     b = y.x - x.x;
 29     c = x.x * y.y-y.x * x.y;
 30 }
 31 void initial()
 32 {
 33     for(int i = 1; i <= m; ++i)p[i] = points[i];
 34     p[m+1] = p[1];
 35     p[0] = p[m];
 36     cCnt = m;
 37 }
 38 point intersect(point x,point y,double a,double b,double c)
 39 {
 40     double u = fabs(a * x.x + b * x.y + c);
 41     double v = fabs(a * y.x + b * y.y + c);
 42     point pt;
 43     pt.x=(x.x * v + y.x * u) / (u + v);
 44     pt.y=(x.y * v + y.y * u) / (u + v);
 45     return  pt;
 46 }
 47 void cut(double a,double b ,double c)
 48 {
 49     curCnt = 0;
 50     for(int i = 1; i <= cCnt; ++i)
 51     {
 52         if(a*p[i].x + b*p[i].y + c >= 0)q[++curCnt] = p[i];
 53         else
 54         {
 55             if(a*p[i-1].x + b*p[i-1].y + c > 0)
 56                 q[++curCnt] = intersect(p[i],p[i-1],a,b,c);
 57             if(a*p[i+1].x + b*p[i+1].y + c > 0)
 58                 q[++curCnt] = intersect(p[i],p[i+1],a,b,c);
 59         }
 60     }
 61     for(int i = 1; i <= curCnt; ++i)p[i] = q[i];
 62     p[curCnt+1] = q[1];
 63     p[0] = p[curCnt];
 64     cCnt = curCnt;
 65 }
 66 void solve()
 67 {
 68     double area = 0;
 69     for(int i = 1; i <= cCnt; ++i)
 70         area += p[i].x * p[i + 1].y - p[i + 1].x * p[i].y;
 71     area = fabs(area / 2.0);
 72     printf("%.1f
",area);
 73 
 74 }
 75 void GuiZhengHua()
 76 {
 77     //规整化方向,逆时针变顺时针,顺时针变逆时针
 78     for(int i = 1; i < (m+1)/2; i ++)
 79         swap(points[i], points[m-i]);
 80 }
 81 int main()
 82 {
 83     points[1] = point(0,0);
 84     points[4] = point(0,10000);
 85     points[3] = point(10000,10000);
 86     points[2] = point(10000,0);
 87     points[5] = p[1];
 88     int n,i;
 89     while(scanf("%d",&n)!=EOF)
 90     {
 91         m = 4;
 92         initial();
 93         for(i = 1; i <= 4; ++i)
 94         {
 95             double a,b,c;
 96             getline(points[i],points[i+1],a,b,c);
 97             cut(a,b,c);
 98         }
 99         for(i = 1 ; i <= 2*n ; i+=2)
100         {
101             point p1,p2;
102             scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y);
103             double a,b,c;
104             getline(p1,p2,a,b,c);
105             cut(a,b,c);
106         }
107 
108        // m = 2*n+4;
109         //GuiZhengHua();
110         //points[m+1] = points[1];
111         solve();
112     }
113     return 0;
114 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3889309.html