刘汝佳半平面交模板
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 using namespace std; 7 #define N 50005 8 9 const double eps=1e-8; 10 int dcmp(double x) { 11 if (x<=eps&&x>=-eps) return 0; 12 return (x>0)?1:-1; 13 } 14 struct Vector { 15 double x,y; 16 Vector(double X=0,double Y=0){ 17 x=X,y=Y; 18 } 19 }; 20 typedef Vector Point; 21 22 struct Line { 23 Point p; 24 Vector v; 25 double ang; 26 Line(Point P=Point(0,0),Vector V=Vector(0,0)) { 27 p=P,v=V; 28 ang=atan2(v.y,v.x); 29 } 30 bool operator < (const Line &a) const { 31 return ang<a.ang; 32 } 33 }; 34 Vector operator + (Vector a,Vector b) {return Vector(a.x+b.x,a.y+b.y);} 35 Vector operator - (Vector a,Vector b) {return Vector(a.x-b.x,a.y-b.y);} 36 Vector operator * (Vector a,double b) {return Vector(a.x*b,a.y*b);} 37 38 int n,l,r,m,cnt; 39 double ans; 40 Line L[N],q[N]; 41 Point p[N],poly[N]; 42 43 double Cross(Vector a,Vector b) { 44 return a.x*b.y-a.y*b.x; 45 } 46 Point GLI(Point P,Vector v,Point Q,Vector w) { 47 Vector u=P-Q; 48 double t=Cross(w,u)/Cross(v,w); 49 return P+v*t; 50 } 51 bool Onleft(Line m,Point P) { 52 Vector w=P-m.p; 53 return dcmp(Cross(m.v,w))>=0; 54 } 55 void halfp(){ 56 sort(L+1,L+n+1); 57 cnt=0; 58 q[l=r=1]=L[1]; 59 for (int i=2;i<=n;++i) { 60 while (l<r&&!Onleft(L[i],p[r-1])) --r; 61 while (l<r&&!Onleft(L[i],p[l])) ++l; 62 q[++r]=L[i]; 63 if (dcmp(Cross(q[r].v,q[r-1].v))==0) { 64 --r; 65 if (Onleft(q[r],L[i].p)) 66 q[r]=L[i]; 67 } 68 if (l<r) 69 p[r-1]=GLI(q[r-1].p,q[r-1].v,q[r].p,q[r].v); 70 } 71 while (l<r&&!Onleft(q[l],p[r-1])) 72 --r; 73 if (r-l<=1) return; 74 p[r]=GLI(q[r].p,q[r].v,q[l].p,q[l].v); 75 for (int i=l;i<=r;++i) poly[++cnt]=p[i]; 76 } 77 double Area() { 78 double ans=0; 79 for (int i=2;i<cnt;++i) 80 ans+=Cross(poly[i]-poly[1],poly[i+1]-poly[1]); 81 return fabs(ans/2); 82 } 83 84 int main() { 85 scanf("%d",&n); // 输入点的个数 86 for (int i=1;i<=n;++i) { 87 Point P,Q;double a,b,c,d; // 输入四个点的坐标 x1,y1,x2,y2 88 scanf("%lf%lf%lf%lf",&a,&b,&c,&d); 89 P=Point(a,b);Q=Point(c,d); // 得到点 90 L[i]=Line(P,Q-P); // 通过一个点和线得到 直线 91 } // 开始需要设置一个无限大的区域 92 L[++n]=Line(Point(0,10000),Vector(0,-10000)); 93 L[++n]=Line(Point(0,0),Vector(10000,0)); 94 L[++n]=Line(Point(10000,0),Vector(0,10000)); 95 L[++n]=Line(Point(10000,10000),Vector(-10000,0)); 96 halfp(); 97 printf("%.1lf\n",Area()); 98 return 0; 99 }
真tm难。。。虽然挺有用的