计算几何做题笔记

  计算几何一生之敌!

凸多边形

  凸多边形好啊!根据凸包的性质,凸多边形的核就是它自身。所以我们可以把凸包上的边变成半平面,这样也是表示凸多边形的一种方法吧...半平面可以求交,求出来的就是多边形的交啦。

  
  1 # include <cstdio>
  2 # include <iostream>
  3 # include <cmath>
  4 # include <algorithm>
  5 # define R register int
  6 
  7 using namespace std;
  8 
  9 const int N=1005;
 10 const double eps=1e-13;
 11 int n,m,cnt,x[N],y[N];
 12 struct point 
 13 {
 14     double x,y;
 15     point (double a=0,double b=0) { x=a,y=b; }
 16 };
 17 //感觉点和向量混用...也没什么关系吧
 18 struct line //第一个点是起点,第二个点是终点;
 19 {
 20     point a,b;
 21     line (point x=point(0,0),point y=point(0,0)) { a=x,b=y; }
 22 }a[N],q[N];
 23 point p[N];
 24 
 25 double poa (line x) { return atan2(x.b.y-x.a.y,x.b.x-x.a.x); }
 26 
 27 double cross (point a,point b)
 28 {
 29     return a.x*b.y-a.y*b.x;
 30 }
 31 
 32 point operator + (point a,point b)
 33 {
 34     return point(a.x+b.x,a.y+b.y);
 35 }
 36 
 37 point operator - (point a,point b)
 38 {
 39     return point(a.x-b.x,a.y-b.y);
 40 }
 41 
 42 point operator * (point a,double b)
 43 {
 44     return point(b*a.x,b*a.y);
 45 }
 46 
 47 bool cmp (line a,line b)
 48 {
 49     double p1=poa(a),p2=poa(b);
 50     if(fabs(p1-p2)<eps)
 51         return cross(a.b-a.a,b.b-a.a)>eps; //把最左边的放到最后,这样方便去重
 52     return p1<p2;
 53 }
 54 
 55 point intersection (line a,line b)
 56 {
 57     double s1=cross(b.a-a.a,a.b-a.a),s2=cross(a.b-a.a,b.b-b.a);
 58     double k=s1/s2;
 59     return ((b.b-b.a)*k)+b.a;
 60 }
 61 
 62 bool rig (line a,line b,line c)
 63 {
 64     point x=intersection(b,c);
 65     return (cross(a.b-a.a,x-a.a)<-eps);
 66 }
 67 
 68 double solve()
 69 {
 70     sort(a+1,a+1+cnt,cmp);
 71     int h=1,t=0; n=0;
 72     for (R i=1;i<cnt;++i)
 73     {
 74         if(fabs(poa(a[i])-poa(a[i+1]))<eps) continue;
 75         a[++n]=a[i];
 76     }   a[++n]=a[cnt];
 77     for (R i=1;i<=n;++i)
 78     {
 79         while(t-h+1>=2&&rig(a[i],q[t-1],q[t])) t--;
 80         while(t-h+1>=2&&rig(a[i],q[h],q[h+1])) h++;
 81         q[++t]=a[i];
 82     }
 83     while(t-h+1>=2&&rig(q[h],q[t-1],q[t])) t--;
 84     while(t-h+1>=2&&rig(q[t],q[h],q[h+1])) h++;
 85     if(t-h+1>=3)
 86     {
 87         int tp=0;
 88         q[t+1]=q[h];
 89         for (R i=h;i<=t;++i)
 90             p[++tp]=intersection(q[i],q[i+1]);
 91         double ans=0;
 92         p[tp+1]=p[1];
 93         for (R i=1;i<=tp;++i)
 94             ans+=cross(p[i],p[i+1]);
 95         return max(ans,-ans)/2.0;
 96     }
 97     else return 0;
 98 }
 99 
100 int main()
101 {
102     scanf("%d",&n);
103     for (R i=1;i<=n;++i)
104     {
105         scanf("%d",&m);
106         for (R j=1;j<=m;++j)
107             scanf("%d%d",&x[j],&y[j]);
108         for (R j=2;j<=m;++j)
109             a[++cnt]=line(point(x[j-1],y[j-1]),point(x[j],y[j]));
110         a[++cnt]=line(point(x[m],y[m]),point(x[1],y[1]));
111     }
112     printf("%.3lf\n",solve());
113     return 0;
114 }
凸多边形

 

射箭

 

 

posted @ 2019-12-11 14:58  shzr  阅读(251)  评论(0编辑  收藏  举报