zoukankan      html  css  js  c++  java
  • [转]计算几何模板

    Repost

    1.

       1 #include<vector>
       2 #include<list>
       3 #include<map>
       4 #include<set>
       5 #include<deque>
       6 #include<queue>
       7 #include<stack>
       8 #include<bitset>
       9 #include<algorithm>
      10 #include<functional>
      11 #include<numeric>
      12 #include<utility>
      13 #include<iostream>
      14 #include<sstream>
      15 #include<iomanip>
      16 #include<cstdio>
      17 #include<cmath>
      18 #include<cstdlib>
      19 #include<cctype>
      20 #include<string>
      21 #include<cstring>
      22 #include<cstdio>
      23 #include<cmath>
      24 #include<cstdlib>
      25 #include<ctime>
      26 #include<climits>
      27 #include<complex>
      28 #define mp make_pair
      29 #define pb push_back
      30 using namespace std;
      31 const double eps=1e-8;
      32 const double pi=acos(-1.0);
      33 const double inf=1e20;
      34 const int maxp=1111;
      35 int dblcmp(double d)
      36 {
      37     if (fabs(d)<eps)return 0;
      38     return d>eps?1:-1;
      39 }
      40 inline double sqr(double x){return x*x;}
      41 struct point
      42 {
      43     double x,y;
      44     point(){}
      45     point(double _x,double _y):
      46     x(_x),y(_y){};
      47     void input()
      48     {
      49         scanf("%lf%lf",&x,&y);
      50     }
      51     void output()
      52     {
      53         printf("%.2f %.2f
    ",x,y);
      54     }
      55     bool operator==(point a)const
      56     {
      57         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0;
      58     }
      59     bool operator<(point a)const
      60     {
      61         return dblcmp(a.x-x)==0?dblcmp(y-a.y)<0:x<a.x;
      62     }
      63     double len()
      64     {
      65         return hypot(x,y);
      66     }
      67     double len2()
      68     {
      69         return x*x+y*y;
      70     }
      71     double distance(point p)
      72     {
      73         return hypot(x-p.x,y-p.y);
      74     }
      75     point add(point p)
      76     {
      77         return point(x+p.x,y+p.y);
      78     }
      79     point sub(point p)
      80     {
      81         return point(x-p.x,y-p.y);
      82     }
      83     point mul(double b)
      84     {
      85         return point(x*b,y*b);
      86     }
      87     point div(double b)
      88     {
      89         return point(x/b,y/b);
      90     }
      91     double dot(point p)
      92     {
      93         return x*p.x+y*p.y;
      94     }
      95     double det(point p)
      96     {
      97         return x*p.y-y*p.x;
      98     }
      99     double rad(point a,point b)
     100     {
     101         point p=*this;
     102         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
     103     }
     104     point trunc(double r)
     105     {
     106         double l=len();
     107         if (!dblcmp(l))return *this;
     108         r/=l;
     109         return point(x*r,y*r);
     110     }
     111     point rotleft()
     112     {
     113         return point(-y,x);
     114     }
     115     point rotright()
     116     {
     117         return point(y,-x);
     118     }
     119     point rotate(point p,double angle)//绕点p逆时针旋转angle角度
     120     {
     121         point v=this->sub(p);
     122         double c=cos(angle),s=sin(angle);
     123         return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
     124     }
     125 };
     126 struct line
     127 {
     128     point a,b;
     129     line(){}
     130     line(point _a,point _b)
     131     {
     132         a=_a;
     133         b=_b;
     134     }
     135     bool operator==(line v)
     136     {
     137         return (a==v.a)&&(b==v.b);
     138     }
     139     //倾斜角angle
     140     line(point p,double angle)
     141     {
     142         a=p;
     143         if (dblcmp(angle-pi/2)==0)
     144         {
     145             b=a.add(point(0,1));
     146         }
     147         else
     148         {
     149             b=a.add(point(1,tan(angle)));
     150         }
     151     }
     152     //ax+by+c=0
     153     line(double _a,double _b,double _c)
     154     {
     155         if (dblcmp(_a)==0)
     156         {
     157             a=point(0,-_c/_b);
     158             b=point(1,-_c/_b);
     159         }
     160         else if (dblcmp(_b)==0)
     161         {
     162             a=point(-_c/_a,0);
     163             b=point(-_c/_a,1);
     164         }
     165         else
     166         {
     167             a=point(0,-_c/_b);
     168             b=point(1,(-_c-_a)/_b);
     169         }
     170     }
     171     void input()
     172     {
     173         a.input();
     174         b.input();
     175     }
     176     void adjust()
     177     {
     178         if (b<a)swap(a,b);
     179     }
     180     double length()
     181     {
     182         return a.distance(b);
     183     }
     184     double angle()//直线倾斜角 0<=angle<180
     185     {
     186         double k=atan2(b.y-a.y,b.x-a.x);
     187         if (dblcmp(k)<0)k+=pi;
     188         if (dblcmp(k-pi)==0)k-=pi;
     189         return k;
     190     }
     191     //点和线段关系
     192     //1 在逆时针
     193     //2 在顺时针
     194     //3 平行
     195     int relation(point p)
     196     {
     197         int c=dblcmp(p.sub(a).det(b.sub(a)));
     198         if (c<0)return 1;
     199         if (c>0)return 2;
     200         return 3;
     201     }
     202     bool pointonseg(point p)
     203     {
     204         return dblcmp(p.sub(a).det(b.sub(a)))==0&&dblcmp(p.sub(a).dot(p.sub(b)))<=0;
     205     }
     206     bool parallel(line v)
     207     {
     208         return dblcmp(b.sub(a).det(v.b.sub(v.a)))==0;
     209     }
     210     //2 规范相交
     211     //1 非规范相交
     212     //0 不相交
     213     int segcrossseg(line v)
     214     {
     215         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
     216         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
     217         int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
     218         int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
     219         if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
     220         return (d1==0&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=0||
     221                 d2==0&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=0||
     222                 d3==0&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=0||
     223                 d4==0&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=0);
     224     }
     225     int linecrossseg(line v)//*this seg v line
     226     {
     227         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
     228         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
     229         if ((d1^d2)==-2)return 2;
     230         return (d1==0||d2==0);
     231     }
     232     //0 平行
     233     //1 重合
     234     //2 相交
     235     int linecrossline(line v)
     236     {
     237         if ((*this).parallel(v))
     238         {
     239             return v.relation(a)==3;
     240         }
     241         return 2;
     242     }
     243     point crosspoint(line v)
     244     {
     245         double a1=v.b.sub(v.a).det(a.sub(v.a));
     246         double a2=v.b.sub(v.a).det(b.sub(v.a));
     247         return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
     248     }
     249     double dispointtoline(point p)
     250     {
     251         return fabs(p.sub(a).det(b.sub(a)))/length();
     252     }
     253     double dispointtoseg(point p)
     254     {
     255         if (dblcmp(p.sub(b).dot(a.sub(b)))<0||dblcmp(p.sub(a).dot(b.sub(a)))<0)
     256         {
     257             return min(p.distance(a),p.distance(b));
     258         }
     259         return dispointtoline(p);
     260     }
     261     point lineprog(point p)
     262     {
     263         return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
     264     }
     265     point symmetrypoint(point p)
     266     {
     267         point q=lineprog(p);
     268         return point(2*q.x-p.x,2*q.y-p.y);
     269     }
     270 };
     271 struct circle
     272 {
     273     point p;
     274     double r;
     275     circle(){}
     276     circle(point _p,double _r):
     277     p(_p),r(_r){};
     278     circle(double x,double y,double _r):
     279     p(point(x,y)),r(_r){};
     280     circle(point a,point b,point c)//三角形的外接圆
     281     {
     282         p=line(a.add(b).div(2),a.add(b).div(2).add(b.sub(a).rotleft())).crosspoint(line(c.add(b).div(2),c.add(b).div(2).add(b.sub(c).rotleft())));
     283         r=p.distance(a);
     284     }
     285     circle(point a,point b,point c,bool t)//三角形的内切圆
     286     {
     287         line u,v;
     288         double m=atan2(b.y-a.y,b.x-a.x),n=atan2(c.y-a.y,c.x-a.x);
     289         u.a=a;
     290         u.b=u.a.add(point(cos((n+m)/2),sin((n+m)/2)));
     291         v.a=b;
     292         m=atan2(a.y-b.y,a.x-b.x),n=atan2(c.y-b.y,c.x-b.x);
     293         v.b=v.a.add(point(cos((n+m)/2),sin((n+m)/2)));
     294         p=u.crosspoint(v);
     295         r=line(a,b).dispointtoseg(p);
     296     }
     297     void input()
     298     {
     299         p.input();
     300         scanf("%lf",&r);
     301     }
     302     void output()
     303     {
     304         printf("%.2lf %.2lf %.2lf
    ",p.x,p.y,r);
     305     }
     306     bool operator==(circle v)
     307     {
     308         return ((p==v.p)&&dblcmp(r-v.r)==0);
     309     }
     310     bool operator<(circle v)const
     311     {
     312         return ((p<v.p)||(p==v.p)&&dblcmp(r-v.r)<0);
     313     }
     314     double area()
     315     {
     316         return pi*sqr(r);
     317     }
     318     double circumference()
     319     {
     320         return 2*pi*r;
     321     }
     322     //0 圆外
     323     //1 圆上
     324     //2 圆内
     325     int relation(point b)
     326     {
     327         double dst=b.distance(p);
     328         if (dblcmp(dst-r)<0)return 2;
     329         if (dblcmp(dst-r)==0)return 1;
     330         return 0;
     331     }
     332     int relationseg(line v)
     333     {
     334         double dst=v.dispointtoseg(p);
     335         if (dblcmp(dst-r)<0)return 2;
     336         if (dblcmp(dst-r)==0)return 1;
     337         return 0;
     338     }
     339     int relationline(line v)
     340     {
     341         double dst=v.dispointtoline(p);
     342         if (dblcmp(dst-r)<0)return 2;
     343         if (dblcmp(dst-r)==0)return 1;
     344         return 0;
     345     }
     346     //过a b两点 半径r的两个圆
     347     int getcircle(point a,point b,double r,circle&c1,circle&c2)
     348     {
     349         circle x(a,r),y(b,r);
     350         int t=x.pointcrosscircle(y,c1.p,c2.p);
     351         if (!t)return 0;
     352         c1.r=c2.r=r;
     353         return t;
     354     }
     355     //与直线u相切 过点q 半径r1的圆
     356     int getcircle(line u,point q,double r1,circle &c1,circle &c2)
     357     {
     358         double dis=u.dispointtoline(q);
     359         if (dblcmp(dis-r1*2)>0)return 0;
     360         if (dblcmp(dis)==0)
     361         {
     362             c1.p=q.add(u.b.sub(u.a).rotleft().trunc(r1));
     363             c2.p=q.add(u.b.sub(u.a).rotright().trunc(r1));
     364             c1.r=c2.r=r1;
     365             return 2;
     366         }
     367         line u1=line(u.a.add(u.b.sub(u.a).rotleft().trunc(r1)),u.b.add(u.b.sub(u.a).rotleft().trunc(r1)));
     368         line u2=line(u.a.add(u.b.sub(u.a).rotright().trunc(r1)),u.b.add(u.b.sub(u.a).rotright().trunc(r1)));
     369         circle cc=circle(q,r1);
     370         point p1,p2;
     371         if (!cc.pointcrossline(u1,p1,p2))cc.pointcrossline(u2,p1,p2);
     372         c1=circle(p1,r1);
     373         if (p1==p2)
     374         {
     375             c2=c1;return 1;
     376         }
     377         c2=circle(p2,r1);
     378         return 2;
     379     }
     380     //同时与直线u,v相切 半径r1的圆
     381     int getcircle(line u,line v,double r1,circle &c1,circle &c2,circle &c3,circle &c4)
     382     {
     383         if (u.parallel(v))return 0;
     384         line u1=line(u.a.add(u.b.sub(u.a).rotleft().trunc(r1)),u.b.add(u.b.sub(u.a).rotleft().trunc(r1)));
     385         line u2=line(u.a.add(u.b.sub(u.a).rotright().trunc(r1)),u.b.add(u.b.sub(u.a).rotright().trunc(r1)));
     386         line v1=line(v.a.add(v.b.sub(v.a).rotleft().trunc(r1)),v.b.add(v.b.sub(v.a).rotleft().trunc(r1)));
     387         line v2=line(v.a.add(v.b.sub(v.a).rotright().trunc(r1)),v.b.add(v.b.sub(v.a).rotright().trunc(r1)));
     388         c1.r=c2.r=c3.r=c4.r=r1;
     389         c1.p=u1.crosspoint(v1);
     390         c2.p=u1.crosspoint(v2);
     391         c3.p=u2.crosspoint(v1);
     392         c4.p=u2.crosspoint(v2);
     393         return 4;
     394     }
     395     //同时与不相交圆cx,cy相切 半径为r1的圆
     396     int getcircle(circle cx,circle cy,double r1,circle&c1,circle&c2)
     397     {
     398         circle x(cx.p,r1+cx.r),y(cy.p,r1+cy.r);
     399         int t=x.pointcrosscircle(y,c1.p,c2.p);
     400         if (!t)return 0;
     401         c1.r=c2.r=r1;
     402         return t;
     403     }
     404     int pointcrossline(line v,point &p1,point &p2)//求与线段交要先判断relationseg
     405     {
     406         if (!(*this).relationline(v))return 0;
     407         point a=v.lineprog(p);
     408         double d=v.dispointtoline(p);
     409         d=sqrt(r*r-d*d);
     410         if (dblcmp(d)==0)
     411         {
     412             p1=a;
     413             p2=a;
     414             return 1;
     415         }
     416         p1=a.sub(v.b.sub(v.a).trunc(d));
     417         p2=a.add(v.b.sub(v.a).trunc(d));
     418         return 2;
     419     }
     420     //5 相离
     421     //4 外切
     422     //3 相交
     423     //2 内切
     424     //1 内含
     425     int relationcircle(circle v)
     426     {
     427         double d=p.distance(v.p);
     428         if (dblcmp(d-r-v.r)>0)return 5;
     429         if (dblcmp(d-r-v.r)==0)return 4;
     430         double l=fabs(r-v.r);
     431         if (dblcmp(d-r-v.r)<0&&dblcmp(d-l)>0)return 3;
     432         if (dblcmp(d-l)==0)return 2;
     433         if (dblcmp(d-l)<0)return 1;
     434     }
     435     int pointcrosscircle(circle v,point &p1,point &p2)
     436     {
     437         int rel=relationcircle(v);
     438         if (rel==1||rel==5)return 0;
     439         double d=p.distance(v.p);
     440         double l=(d+(sqr(r)-sqr(v.r))/d)/2;
     441         double h=sqrt(sqr(r)-sqr(l));
     442         p1=p.add(v.p.sub(p).trunc(l).add(v.p.sub(p).rotleft().trunc(h)));
     443         p2=p.add(v.p.sub(p).trunc(l).add(v.p.sub(p).rotright().trunc(h)));
     444         if (rel==2||rel==4)
     445         {
     446             return 1;
     447         }
     448         return 2;
     449     }
     450     //过一点做圆的切线 (先判断点和圆关系)
     451     int tangentline(point q,line &u,line &v)
     452     {
     453         int x=relation(q);
     454         if (x==2)return 0;
     455         if (x==1)
     456         {
     457             u=line(q,q.add(q.sub(p).rotleft()));
     458             v=u;
     459             return 1;
     460         }
     461         double d=p.distance(q);
     462         double l=sqr(r)/d;
     463         double h=sqrt(sqr(r)-sqr(l));
     464         u=line(q,p.add(q.sub(p).trunc(l).add(q.sub(p).rotleft().trunc(h))));
     465         v=line(q,p.add(q.sub(p).trunc(l).add(q.sub(p).rotright().trunc(h))));
     466         return 2;
     467     }
     468     double areacircle(circle v)
     469     {
     470         int rel=relationcircle(v);
     471         if (rel>=4)return 0.0;
     472         if (rel<=2)return min(area(),v.area());
     473         double d=p.distance(v.p);
     474         double hf=(r+v.r+d)/2.0;
     475         double ss=2*sqrt(hf*(hf-r)*(hf-v.r)*(hf-d));
     476         double a1=acos((r*r+d*d-v.r*v.r)/(2.0*r*d));
     477         a1=a1*r*r;
     478         double a2=acos((v.r*v.r+d*d-r*r)/(2.0*v.r*d));
     479         a2=a2*v.r*v.r;
     480         return a1+a2-ss;
     481     }
     482     double areatriangle(point a,point b)
     483     {
     484         if (dblcmp(p.sub(a).det(p.sub(b))==0))return 0.0;
     485         point q[5];
     486         int len=0;
     487         q[len++]=a;
     488         line l(a,b);
     489         point p1,p2;
     490         if (pointcrossline(l,q[1],q[2])==2)
     491         {
     492             if (dblcmp(a.sub(q[1]).dot(b.sub(q[1])))<0)q[len++]=q[1];
     493             if (dblcmp(a.sub(q[2]).dot(b.sub(q[2])))<0)q[len++]=q[2];
     494         }
     495         q[len++]=b;
     496         if (len==4&&(dblcmp(q[0].sub(q[1]).dot(q[2].sub(q[1])))>0))swap(q[1],q[2]);
     497         double res=0;
     498         int i;
     499         for (i=0;i<len-1;i++)
     500         {
     501             if (relation(q[i])==0||relation(q[i+1])==0)
     502             {
     503                 double arg=p.rad(q[i],q[i+1]);
     504                 res+=r*r*arg/2.0;
     505             }
     506             else
     507             {
     508                 res+=fabs(q[i].sub(p).det(q[i+1].sub(p))/2.0);
     509             }
     510         }
     511         return res;
     512     }
     513 };
     514 struct polygon
     515 {
     516     int n;
     517     point p[maxp];
     518     line l[maxp];
     519     void input()
     520     {
     521         n=4;
     522         for (int i=0;i<n;i++)
     523         {
     524             p[i].input();
     525         }
     526     }
     527     void add(point q)
     528     {
     529         p[n++]=q;
     530     }
     531     void getline()
     532     {
     533         for (int i=0;i<n;i++)
     534         {
     535             l[i]=line(p[i],p[(i+1)%n]);
     536         }
     537     }
     538     struct cmp
     539     {
     540         point p;
     541         cmp(const point &p0){p=p0;}
     542         bool operator()(const point &aa,const point &bb)
     543         {
     544             point a=aa,b=bb;
     545             int d=dblcmp(a.sub(p).det(b.sub(p)));
     546             if (d==0)
     547             {
     548                 return dblcmp(a.distance(p)-b.distance(p))<0;
     549             }
     550             return d>0;
     551         }
     552     };
     553     void norm()
     554     {
     555         point mi=p[0];
     556         for (int i=1;i<n;i++)mi=min(mi,p[i]);
     557         sort(p,p+n,cmp(mi));
     558     }
     559     void getconvex(polygon &convex)
     560     {
     561         int i,j,k;
     562         sort(p,p+n);
     563         convex.n=n;
     564         for (i=0;i<min(n,2);i++)
     565         {
     566             convex.p[i]=p[i];
     567         }
     568         if (n<=2)return;
     569         int &top=convex.n;
     570         top=1;
     571         for (i=2;i<n;i++)
     572         {
     573             while (top&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
     574                 top--;
     575             convex.p[++top]=p[i];
     576         }
     577         int temp=top;
     578         convex.p[++top]=p[n-2];
     579         for (i=n-3;i>=0;i--)
     580         {
     581             while (top!=temp&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
     582                 top--;
     583             convex.p[++top]=p[i];
     584         }
     585     }
     586     bool isconvex()
     587     {
     588         bool s[3];
     589         memset(s,0,sizeof(s));
     590         int i,j,k;
     591         for (i=0;i<n;i++)
     592         {
     593             j=(i+1)%n;
     594             k=(j+1)%n;
     595             s[dblcmp(p[j].sub(p[i]).det(p[k].sub(p[i])))+1]=1;
     596             if (s[0]&&s[2])return 0;
     597         }
     598         return 1;
     599     }
     600     //3 点上
     601     //2 边上
     602     //1 内部
     603     //0 外部
     604     int relationpoint(point q)
     605     {
     606         int i,j;
     607         for (i=0;i<n;i++)
     608         {
     609             if (p[i]==q)return 3;
     610         }
     611         getline();
     612         for (i=0;i<n;i++)
     613         {
     614             if (l[i].pointonseg(q))return 2;
     615         }
     616         int cnt=0;
     617         for (i=0;i<n;i++)
     618         {
     619             j=(i+1)%n;
     620             int k=dblcmp(q.sub(p[j]).det(p[i].sub(p[j])));
     621             int u=dblcmp(p[i].y-q.y);
     622             int v=dblcmp(p[j].y-q.y);
     623             if (k>0&&u<0&&v>=0)cnt++;
     624             if (k<0&&v<0&&u>=0)cnt--;
     625         }
     626         return cnt!=0;
     627     }
     628     //1 在多边形内长度为正
     629     //2 相交或与边平行
     630     //0 无任何交点
     631     int relationline(line u)
     632     {
     633         int i,j,k=0;
     634         getline();
     635         for (i=0;i<n;i++)
     636         {
     637             if (l[i].segcrossseg(u)==2)return 1;
     638             if (l[i].segcrossseg(u)==1)k=1;
     639         }
     640         if (!k)return 0;
     641         vector<point>vp;
     642         for (i=0;i<n;i++)
     643         {
     644             if (l[i].segcrossseg(u))
     645             {
     646                 if (l[i].parallel(u))
     647                 {
     648                     vp.pb(u.a);
     649                     vp.pb(u.b);
     650                     vp.pb(l[i].a);
     651                     vp.pb(l[i].b);
     652                     continue;
     653                 }
     654                 vp.pb(l[i].crosspoint(u));
     655             }
     656         }
     657         sort(vp.begin(),vp.end());
     658         int sz=vp.size();
     659         for (i=0;i<sz-1;i++)
     660         {
     661             point mid=vp[i].add(vp[i+1]).div(2);
     662             if (relationpoint(mid)==1)return 1;
     663         }
     664         return 2;
     665     }
     666     //直线u切割凸多边形左侧
     667     //注意直线方向
     668     void convexcut(line u,polygon &po)
     669     {
     670         int i,j,k;
     671         int &top=po.n;
     672         top=0;
     673         for (i=0;i<n;i++)
     674         {
     675             int d1=dblcmp(p[i].sub(u.a).det(u.b.sub(u.a)));
     676             int d2=dblcmp(p[(i+1)%n].sub(u.a).det(u.b.sub(u.a)));
     677             if (d1>=0)po.p[top++]=p[i];
     678             if (d1*d2<0)po.p[top++]=u.crosspoint(line(p[i],p[(i+1)%n]));
     679         }
     680     }
     681     double getcircumference()
     682     {
     683         double sum=0;
     684         int i;
     685         for (i=0;i<n;i++)
     686         {
     687             sum+=p[i].distance(p[(i+1)%n]);
     688         }
     689         return sum;
     690     }
     691     double getarea()
     692     {
     693         double sum=0;
     694         int i;
     695         for (i=0;i<n;i++)
     696         {
     697             sum+=p[i].det(p[(i+1)%n]);
     698         }
     699         return fabs(sum)/2;
     700     }
     701     bool getdir()//1代表逆时针 0代表顺时针
     702     {
     703         double sum=0;
     704         int i;
     705         for (i=0;i<n;i++)
     706         {
     707             sum+=p[i].det(p[(i+1)%n]);
     708         }
     709         if (dblcmp(sum)>0)return 1;
     710         return 0;
     711     }
     712     point getbarycentre()
     713     {
     714         point ret(0,0);
     715         double area=0;
     716         int i;
     717         for (i=1;i<n-1;i++)
     718         {
     719             double tmp=p[i].sub(p[0]).det(p[i+1].sub(p[0]));
     720             if (dblcmp(tmp)==0)continue;
     721             area+=tmp;
     722             ret.x+=(p[0].x+p[i].x+p[i+1].x)/3*tmp;
     723             ret.y+=(p[0].y+p[i].y+p[i+1].y)/3*tmp;
     724         }
     725         if (dblcmp(area))ret=ret.div(area);
     726         return ret;
     727     }
     728     double areaintersection(polygon po)
     729     {
     730     }
     731     double areaunion(polygon po)
     732     {
     733         return getarea()+po.getarea()-areaintersection(po);
     734     }
     735     double areacircle(circle c)
     736     {
     737         int i,j,k,l,m;
     738         double ans=0;
     739         for (i=0;i<n;i++)
     740         {
     741             int j=(i+1)%n;
     742             if (dblcmp(p[j].sub(c.p).det(p[i].sub(c.p)))>=0)
     743             {
     744                 ans+=c.areatriangle(p[i],p[j]);
     745             }
     746             else
     747             {
     748                 ans-=c.areatriangle(p[i],p[j]);
     749             }
     750         }
     751         return fabs(ans);
     752     }
     753     //多边形和圆关系
     754     //0 一部分在圆外
     755     //1 与圆某条边相切
     756     //2 完全在圆内
     757     int relationcircle(circle c)
     758     {
     759         getline();
     760         int i,x=2;
     761         if (relationpoint(c.p)!=1)return 0;
     762         for (i=0;i<n;i++)
     763         {
     764             if (c.relationseg(l[i])==2)return 0;
     765             if (c.relationseg(l[i])==1)x=1;
     766         }
     767         return x;
     768     }
     769     void find(int st,point tri[],circle &c)
     770     {
     771         if (!st)
     772         {
     773             c=circle(point(0,0),-2);
     774         }
     775         if (st==1)
     776         {
     777             c=circle(tri[0],0);
     778         }
     779         if (st==2)
     780         {
     781             c=circle(tri[0].add(tri[1]).div(2),tri[0].distance(tri[1])/2.0);
     782         }
     783         if (st==3)
     784         {
     785             c=circle(tri[0],tri[1],tri[2]);
     786         }
     787     }
     788     void solve(int cur,int st,point tri[],circle &c)
     789     {
     790         find(st,tri,c);
     791         if (st==3)return;
     792         int i;
     793         for (i=0;i<cur;i++)
     794         {
     795             if (dblcmp(p[i].distance(c.p)-c.r)>0)
     796             {
     797                 tri[st]=p[i];
     798                 solve(i,st+1,tri,c);
     799             }
     800         }
     801     }
     802     circle mincircle()//点集最小圆覆盖
     803     {
     804         random_shuffle(p,p+n);
     805         point tri[4];
     806         circle c;
     807         solve(n,0,tri,c);
     808         return c;
     809     }
     810     int circlecover(double r)//单位圆覆盖
     811     {
     812         int ans=0,i,j;
     813         vector<pair<double,int> >v;
     814         for (i=0;i<n;i++)
     815         {
     816             v.clear();
     817             for (j=0;j<n;j++)if (i!=j)
     818             {
     819                 point q=p[i].sub(p[j]);
     820                 double d=q.len();
     821                 if (dblcmp(d-2*r)<=0)
     822                 {
     823                     double arg=atan2(q.y,q.x);
     824                     if (dblcmp(arg)<0)arg+=2*pi;
     825                     double t=acos(d/(2*r));
     826                     v.push_back(make_pair(arg-t+2*pi,-1));
     827                     v.push_back(make_pair(arg+t+2*pi,1));
     828                 }
     829             }
     830             sort(v.begin(),v.end());
     831             int cur=0;
     832             for (j=0;j<v.size();j++)
     833             {
     834                 if (v[j].second==-1)++cur;
     835                 else --cur;
     836                 ans=max(ans,cur);
     837             }
     838         }
     839         return ans+1;
     840     }
     841     int pointinpolygon(point q)//点在凸多边形内部的判定
     842     {
     843         if (getdir())reverse(p,p+n);
     844         if (dblcmp(q.sub(p[0]).det(p[n-1].sub(p[0])))==0)
     845         {
     846             if (line(p[n-1],p[0]).pointonseg(q))return n-1;
     847             return -1;
     848         }
     849         int low=1,high=n-2,mid;
     850         while (low<=high)
     851         {
     852             mid=(low+high)>>1;
     853             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>=0&&dblcmp(q.sub(p[0]).det(p[mid+1].sub(p[0])))<0)
     854             {
     855                 polygon c;
     856                 c.p[0]=p[mid];
     857                 c.p[1]=p[mid+1];
     858                 c.p[2]=p[0];
     859                 c.n=3;
     860                 if (c.relationpoint(q))return mid;
     861                 return -1;
     862             }
     863             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>0)
     864             {
     865                 low=mid+1;
     866             }
     867             else
     868             {
     869                 high=mid-1;
     870             }
     871         }
     872         return -1;
     873     }
     874 };
     875 struct polygons
     876 {
     877     vector<polygon>p;
     878     polygons()
     879     {
     880         p.clear();
     881     }
     882     void clear()
     883     {
     884         p.clear();
     885     }
     886     void push(polygon q)
     887     {
     888         if (dblcmp(q.getarea()))p.pb(q);
     889     }
     890     vector<pair<double,int> >e;
     891     void ins(point s,point t,point X,int i)
     892     {
     893         double r=fabs(t.x-s.x)>eps?(X.x-s.x)/(t.x-s.x):(X.y-s.y)/(t.y-s.y);
     894         r=min(r,1.0);r=max(r,0.0);
     895         e.pb(mp(r,i));
     896     }
     897     double polyareaunion()
     898     {
     899         double ans=0.0;
     900         int c0,c1,c2,i,j,k,w;
     901         for (i=0;i<p.size();i++)
     902         {
     903             if (p[i].getdir()==0)reverse(p[i].p,p[i].p+p[i].n);
     904         }
     905         for (i=0;i<p.size();i++)
     906         {
     907             for (k=0;k<p[i].n;k++)
     908             {
     909                 point &s=p[i].p[k],&t=p[i].p[(k+1)%p[i].n];
     910                 if (!dblcmp(s.det(t)))continue;
     911                 e.clear();
     912                 e.pb(mp(0.0,1));
     913                 e.pb(mp(1.0,-1));
     914                 for (j=0;j<p.size();j++)if (i!=j)
     915                 {
     916                     for (w=0;w<p[j].n;w++)
     917                     {
     918                         point a=p[j].p[w],b=p[j].p[(w+1)%p[j].n],c=p[j].p[(w-1+p[j].n)%p[j].n];
     919                         c0=dblcmp(t.sub(s).det(c.sub(s)));
     920                         c1=dblcmp(t.sub(s).det(a.sub(s)));
     921                         c2=dblcmp(t.sub(s).det(b.sub(s)));
     922                         if (c1*c2<0)ins(s,t,line(s,t).crosspoint(line(a,b)),-c2);
     923                         else if (!c1&&c0*c2<0)ins(s,t,a,-c2);
     924                         else if (!c1&&!c2)
     925                         {
     926                             int c3=dblcmp(t.sub(s).det(p[j].p[(w+2)%p[j].n].sub(s)));
     927                             int dp=dblcmp(t.sub(s).dot(b.sub(a)));
     928                             if (dp&&c0)ins(s,t,a,dp>0?c0*((j>i)^(c0<0)):-(c0<0));
     929                             if (dp&&c3)ins(s,t,b,dp>0?-c3*((j>i)^(c3<0)):c3<0);
     930                         }
     931                     }
     932                 }
     933                 sort(e.begin(),e.end());
     934                 int ct=0;
     935                 double tot=0.0,last;
     936                 for (j=0;j<e.size();j++)
     937                 {
     938                     if (ct==2)tot+=e[j].first-last;
     939                     ct+=e[j].second;
     940                     last=e[j].first;
     941                 }
     942                 ans+=s.det(t)*tot;
     943             }
     944         }
     945         return fabs(ans)*0.5;
     946     }
     947 };
     948 const int maxn=500;
     949 struct circles
     950 {
     951     circle c[maxn];
     952     double ans[maxn];//ans[i]表示被覆盖了i次的面积
     953     double pre[maxn];
     954     int n;
     955     circles(){}
     956     void add(circle cc)
     957     {
     958         c[n++]=cc;
     959     }
     960     bool inner(circle x,circle y)
     961     {
     962         if (x.relationcircle(y)!=1)return 0;
     963         return dblcmp(x.r-y.r)<=0?1:0;
     964     }
     965     void init_or()//圆的面积并去掉内含的圆
     966     {
     967         int i,j,k=0;
     968         bool mark[maxn]={0};
     969         for (i=0;i<n;i++)
     970         {
     971             for (j=0;j<n;j++)if (i!=j&&!mark[j])
     972             {
     973                 if ((c[i]==c[j])||inner(c[i],c[j]))break;
     974             }
     975             if (j<n)mark[i]=1;
     976         }
     977         for (i=0;i<n;i++)if (!mark[i])c[k++]=c[i];
     978         n=k;
     979     }
     980     void init_and()//圆的面积交去掉内含的圆
     981     {
     982         int i,j,k=0;
     983         bool mark[maxn]={0};
     984         for (i=0;i<n;i++)
     985         {
     986             for (j=0;j<n;j++)if (i!=j&&!mark[j])
     987             {
     988                 if ((c[i]==c[j])||inner(c[j],c[i]))break;
     989             }
     990             if (j<n)mark[i]=1;
     991         }
     992         for (i=0;i<n;i++)if (!mark[i])c[k++]=c[i];
     993         n=k;
     994     }
     995     double areaarc(double th,double r)
     996     {
     997         return 0.5*sqr(r)*(th-sin(th));
     998     }
     999     void getarea()
    1000     {
    1001         int i,j,k;
    1002         memset(ans,0,sizeof(ans));
    1003         vector<pair<double,int> >v;
    1004         for (i=0;i<n;i++)
    1005         {
    1006             v.clear();
    1007             v.push_back(make_pair(-pi,1));
    1008             v.push_back(make_pair(pi,-1));
    1009             for (j=0;j<n;j++)if (i!=j)
    1010             {
    1011                 point q=c[j].p.sub(c[i].p);
    1012                 double ab=q.len(),ac=c[i].r,bc=c[j].r;
    1013                 if (dblcmp(ab+ac-bc)<=0)
    1014                 {
    1015                     v.push_back(make_pair(-pi,1));
    1016                     v.push_back(make_pair(pi,-1));
    1017                     continue;
    1018                 }
    1019                 if (dblcmp(ab+bc-ac)<=0)continue;
    1020                 if (dblcmp(ab-ac-bc)>0) continue;
    1021                 double th=atan2(q.y,q.x),fai=acos((ac*ac+ab*ab-bc*bc)/(2.0*ac*ab));
    1022                 double a0=th-fai;
    1023                 if (dblcmp(a0+pi)<0)a0+=2*pi;
    1024                 double a1=th+fai;
    1025                 if (dblcmp(a1-pi)>0)a1-=2*pi;
    1026                 if (dblcmp(a0-a1)>0)
    1027                 {
    1028                     v.push_back(make_pair(a0,1));
    1029                     v.push_back(make_pair(pi,-1));
    1030                     v.push_back(make_pair(-pi,1));
    1031                     v.push_back(make_pair(a1,-1));
    1032                 }
    1033                 else
    1034                 {
    1035                     v.push_back(make_pair(a0,1));
    1036                     v.push_back(make_pair(a1,-1));
    1037                 }
    1038             }
    1039             sort(v.begin(),v.end());
    1040             int cur=0;
    1041             for (j=0;j<v.size();j++)
    1042             {
    1043                 if (cur&&dblcmp(v[j].first-pre[cur]))
    1044                 {
    1045                     ans[cur]+=areaarc(v[j].first-pre[cur],c[i].r);
    1046                     ans[cur]+=0.5*point(c[i].p.x+c[i].r*cos(pre[cur]),c[i].p.y+c[i].r*sin(pre[cur])).det(point(c[i].p.x+c[i].r*cos(v[j].first),c[i].p.y+c[i].r*sin(v[j].first)));
    1047                 }
    1048                 cur+=v[j].second;
    1049                 pre[cur]=v[j].first;
    1050             }
    1051         }
    1052         for (i=1;i<=n;i++)
    1053         {
    1054             ans[i]-=ans[i+1];
    1055         }
    1056     }
    1057 };
    1058 struct halfplane:public line
    1059 {
    1060     double angle;
    1061     halfplane(){}
    1062     //表示向量 a->b逆时针(左侧)的半平面
    1063     halfplane(point _a,point _b)
    1064     {
    1065         a=_a;
    1066         b=_b;
    1067     }
    1068     halfplane(line v)
    1069     {
    1070         a=v.a;
    1071         b=v.b;
    1072     }
    1073     void calcangle()
    1074     {
    1075         angle=atan2(b.y-a.y,b.x-a.x);
    1076     }
    1077     bool operator<(const halfplane &b)const
    1078     {
    1079         return angle<b.angle;
    1080     }
    1081 };
    1082 struct halfplanes
    1083 {
    1084     int n;
    1085     halfplane hp[maxp];
    1086     point p[maxp];
    1087     int que[maxp];
    1088     int st,ed;
    1089     void push(halfplane tmp)
    1090     {
    1091         hp[n++]=tmp;
    1092     }
    1093     void unique()
    1094     {
    1095         int m=1,i;
    1096         for (i=1;i<n;i++)
    1097         {
    1098             if (dblcmp(hp[i].angle-hp[i-1].angle))hp[m++]=hp[i];
    1099             else if (dblcmp(hp[m-1].b.sub(hp[m-1].a).det(hp[i].a.sub(hp[m-1].a))>0))hp[m-1]=hp[i];
    1100         }
    1101         n=m;
    1102     }
    1103     bool halfplaneinsert()
    1104     {
    1105         int i;
    1106         for (i=0;i<n;i++)hp[i].calcangle();
    1107         sort(hp,hp+n);
    1108         unique();
    1109         que[st=0]=0;
    1110         que[ed=1]=1;
    1111         p[1]=hp[0].crosspoint(hp[1]);
    1112         for (i=2;i<n;i++)
    1113         {
    1114             while (st<ed&&dblcmp((hp[i].b.sub(hp[i].a).det(p[ed].sub(hp[i].a))))<0)ed--;
    1115             while (st<ed&&dblcmp((hp[i].b.sub(hp[i].a).det(p[st+1].sub(hp[i].a))))<0)st++;
    1116             que[++ed]=i;
    1117             if (hp[i].parallel(hp[que[ed-1]]))return false;
    1118             p[ed]=hp[i].crosspoint(hp[que[ed-1]]);
    1119         }
    1120         while (st<ed&&dblcmp(hp[que[st]].b.sub(hp[que[st]].a).det(p[ed].sub(hp[que[st]].a)))<0)ed--;
    1121         while (st<ed&&dblcmp(hp[que[ed]].b.sub(hp[que[ed]].a).det(p[st+1].sub(hp[que[ed]].a)))<0)st++;
    1122         if (st+1>=ed)return false;
    1123         return true;
    1124     }
    1125     void getconvex(polygon &con)
    1126     {
    1127         p[st]=hp[que[st]].crosspoint(hp[que[ed]]);
    1128         con.n=ed-st+1;
    1129         int j=st,i=0;
    1130         for (;j<=ed;i++,j++)
    1131         {
    1132             con.p[i]=p[j];
    1133         }
    1134     }
    1135 };
    1136 struct point3
    1137 {
    1138     double x,y,z;
    1139     point3(){}
    1140     point3(double _x,double _y,double _z):
    1141     x(_x),y(_y),z(_z){};
    1142     void input()
    1143     {
    1144         scanf("%lf%lf%lf",&x,&y,&z);
    1145     }
    1146     void output()
    1147     {
    1148         printf("%.2lf %.2lf %.2lf
    ",x,y,z);
    1149     }
    1150     bool operator==(point3 a)
    1151     {
    1152         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0&&dblcmp(a.z-z)==0;
    1153     }
    1154     bool operator<(point3 a)const
    1155     {
    1156         return dblcmp(a.x-x)==0?dblcmp(y-a.y)==0?dblcmp(z-a.z)<0:y<a.y:x<a.x;
    1157     }
    1158     double len()
    1159     {
    1160         return sqrt(len2());
    1161     }
    1162     double len2()
    1163     {
    1164         return x*x+y*y+z*z;
    1165     }
    1166     double distance(point3 p)
    1167     {
    1168         return sqrt((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y)+(p.z-z)*(p.z-z));
    1169     }
    1170     point3 add(point3 p)
    1171     {
    1172         return point3(x+p.x,y+p.y,z+p.z);
    1173     }
    1174     point3 sub(point3 p)
    1175     {
    1176         return point3(x-p.x,y-p.y,z-p.z);
    1177     }
    1178     point3 mul(double d)
    1179     {
    1180         return point3(x*d,y*d,z*d);
    1181     }
    1182     point3 div(double d)
    1183     {
    1184         return point3(x/d,y/d,z/d);
    1185     }
    1186     double dot(point3 p)
    1187     {
    1188         return x*p.x+y*p.y+z*p.z;
    1189     }
    1190     point3 det(point3 p)
    1191     {
    1192         return point3(y*p.z-p.y*z,p.x*z-x*p.z,x*p.y-p.x*y);
    1193     }
    1194     double rad(point3 a,point3 b)
    1195     {
    1196         point3 p=(*this);
    1197         return acos(a.sub(p).dot(b.sub(p))/(a.distance(p)*b.distance(p)));
    1198     }
    1199     point3 trunc(double r)
    1200     {
    1201         r/=len();
    1202         return point3(x*r,y*r,z*r);
    1203     }
    1204     point3 rotate(point3 o,double r)
    1205     {
    1206     }
    1207 };
    1208 struct line3
    1209 {
    1210     point3 a,b;
    1211     line3(){}
    1212     line3(point3 _a,point3 _b)
    1213     {
    1214         a=_a;
    1215         b=_b;
    1216     }
    1217     bool operator==(line3 v)
    1218     {
    1219         return (a==v.a)&&(b==v.b);
    1220     }
    1221     void input()
    1222     {
    1223         a.input();
    1224         b.input();
    1225     }
    1226     double length()
    1227     {
    1228         return a.distance(b);
    1229     }
    1230     bool pointonseg(point3 p)
    1231     {
    1232         return dblcmp(p.sub(a).det(p.sub(b)).len())==0&&dblcmp(a.sub(p).dot(b.sub(p)))<=0;
    1233     }
    1234     double dispointtoline(point3 p)
    1235     {
    1236         return b.sub(a).det(p.sub(a)).len()/a.distance(b);
    1237     }
    1238     double dispointtoseg(point3 p)
    1239     {
    1240         if (dblcmp(p.sub(b).dot(a.sub(b)))<0||dblcmp(p.sub(a).dot(b.sub(a)))<0)
    1241         {
    1242             return min(p.distance(a),p.distance(b));
    1243         }
    1244         return dispointtoline(p);
    1245     }
    1246     point3 lineprog(point3 p)
    1247     {
    1248         return a.add(b.sub(a).trunc(b.sub(a).dot(p.sub(a))/b.distance(a)));
    1249     }
    1250     point3 rotate(point3 p,double ang)//p绕此向量逆时针arg角度
    1251     {
    1252         if (dblcmp((p.sub(a).det(p.sub(b)).len()))==0)return p;
    1253         point3 f1=b.sub(a).det(p.sub(a));
    1254         point3 f2=b.sub(a).det(f1);
    1255         double len=fabs(a.sub(p).det(b.sub(p)).len()/a.distance(b));
    1256         f1=f1.trunc(len);f2=f2.trunc(len);
    1257         point3 h=p.add(f2);
    1258         point3 pp=h.add(f1);
    1259         return h.add((p.sub(h)).mul(cos(ang*1.0))).add((pp.sub(h)).mul(sin(ang*1.0)));
    1260     }
    1261 };
    1262 struct plane
    1263 {
    1264     point3 a,b,c,o;
    1265     plane(){}
    1266     plane(point3 _a,point3 _b,point3 _c)
    1267     {
    1268         a=_a;
    1269         b=_b;
    1270         c=_c;
    1271         o=pvec();
    1272     }
    1273     plane(double _a,double _b,double _c,double _d)
    1274     {
    1275         //ax+by+cz+d=0
    1276         o=point3(_a,_b,_c);
    1277         if (dblcmp(_a)!=0)
    1278         {
    1279             a=point3((-_d-_c-_b)/_a,1,1);
    1280         }
    1281         else if (dblcmp(_b)!=0)
    1282         {
    1283             a=point3(1,(-_d-_c-_a)/_b,1);
    1284         }
    1285         else if (dblcmp(_c)!=0)
    1286         {
    1287             a=point3(1,1,(-_d-_a-_b)/_c);
    1288         }
    1289     }
    1290     void input()
    1291     {
    1292         a.input();
    1293         b.input();
    1294         c.input();
    1295         o=pvec();
    1296     }
    1297     point3 pvec()
    1298     {
    1299         return b.sub(a).det(c.sub(a));
    1300     }
    1301     bool pointonplane(point3 p)//点是否在平面上
    1302     {
    1303         return dblcmp(p.sub(a).dot(o))==0;
    1304     }
    1305     //0 不在
    1306     //1 在边界上
    1307     //2 在内部
    1308     int pointontriangle(point3 p)//点是否在空间三角形abc上
    1309     {
    1310         if (!pointonplane(p))return 0;
    1311         double s=a.sub(b).det(c.sub(b)).len();
    1312         double s1=p.sub(a).det(p.sub(b)).len();
    1313         double s2=p.sub(a).det(p.sub(c)).len();
    1314         double s3=p.sub(b).det(p.sub(c)).len();
    1315         if (dblcmp(s-s1-s2-s3))return 0;
    1316         if (dblcmp(s1)&&dblcmp(s2)&&dblcmp(s3))return 2;
    1317         return 1;
    1318     }
    1319     //判断两平面关系
    1320     //0 相交
    1321     //1 平行但不重合
    1322     //2 重合
    1323     bool relationplane(plane f)
    1324     {
    1325         if (dblcmp(o.det(f.o).len()))return 0;
    1326         if (pointonplane(f.a))return 2;
    1327         return 1;
    1328     }
    1329     double angleplane(plane f)//两平面夹角
    1330     {
    1331         return acos(o.dot(f.o)/(o.len()*f.o.len()));
    1332     }
    1333     double dispoint(point3 p)//点到平面距离
    1334     {
    1335         return fabs(p.sub(a).dot(o)/o.len());
    1336     }
    1337     point3 pttoplane(point3 p)//点到平面最近点
    1338     {
    1339         line3 u=line3(p,p.add(o));
    1340         crossline(u,p);
    1341         return p;
    1342     }
    1343     int crossline(line3 u,point3 &p)//平面和直线的交点
    1344     {
    1345         double x=o.dot(u.b.sub(a));
    1346         double y=o.dot(u.a.sub(a));
    1347         double d=x-y;
    1348         if (dblcmp(fabs(d))==0)return 0;
    1349         p=u.a.mul(x).sub(u.b.mul(y)).div(d);
    1350         return 1;
    1351     }
    1352     int crossplane(plane f,line3 &u)//平面和平面的交线
    1353     {
    1354         point3 oo=o.det(f.o);
    1355         point3 v=o.det(oo);
    1356         double d=fabs(f.o.dot(v));
    1357         if (dblcmp(d)==0)return 0;
    1358         point3 q=a.add(v.mul(f.o.dot(f.a.sub(a))/d));
    1359         u=line3(q,q.add(oo));
    1360         return 1;
    1361     }
    1362 };
    View Code

    2.

      1 #include<vector>
      2 #include<list>
      3 #include<map>
      4 #include<set>
      5 #include<deque>
      6 #include<queue>
      7 #include<stack>
      8 #include<bitset>
      9 #include<algorithm>
     10 #include<functional>
     11 #include<numeric>
     12 #include<utility>
     13 #include<iostream>
     14 #include<sstream>
     15 #include<iomanip>
     16 #include<cstdio>
     17 #include<cmath>
     18 #include<cstdlib>
     19 #include<cctype>
     20 #include<string>
     21 #include<cstring>
     22 #include<cstdio>
     23 #include<cmath>
     24 #include<cstdlib>
     25 #include<ctime>
     26 #include<climits>
     27 #include<complex>
     28 #define mp make_pair
     29 #define pb push_back
     30 using namespace std;
     31 const double eps=1e-8;//精度
     32 const double pi=acos(-1.0);//π
     33 const double inf=1e20;//无穷大
     34 const int maxp=1111;//最大点数
     35 /*
     36     判断d是否在精度内等于0
     37 */
     38 int dblcmp(double d)
     39 {
     40     if (fabs(d)<eps)return 0;
     41     return d>eps?1:-1;
     42 }
     43 /*
     44     求x的平方
     45 */
     46 inline double sqr(double x){return x*x;}
     47 /*
     48     点/向量
     49 */
     50 struct point
     51 {
     52     double x,y;
     53     point(){}
     54     point(double _x,double _y):x(_x),y(_y){};
     55     //读入一个点
     56     void input()
     57     {
     58         scanf("%lf%lf",&x,&y);
     59     }
     60     //输出一个点
     61     void output()
     62     {
     63         printf("%.2f %.2f
    ",x,y);
     64     }
     65     //判断两点是否相等
     66     bool operator==(point a)const
     67     {
     68         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0;
     69     }
     70     //判断两点大小
     71     bool operator<(point a)const
     72     {
     73         return dblcmp(a.x-x)==0?dblcmp(y-a.y)<0:x<a.x;
     74     }
     75     //点到源点的距离/向量的长度
     76     double len()
     77     {
     78         return hypot(x,y);
     79     }
     80     //点到源点距离的平方
     81     double len2()
     82     {
     83         return x*x+y*y;
     84     }
     85     //两点间的距离
     86     double distance(point p)
     87     {
     88         return hypot(x-p.x,y-p.y);
     89     }
     90     //向量加
     91     point add(point p)
     92     {
     93         return point(x+p.x,y+p.y);
     94     }
     95     //向量减
     96     point sub(point p)
     97     {
     98         return point(x-p.x,y-p.y);
     99     }
    100     //向量乘
    101     point mul(double b)
    102     {
    103         return point(x*b,y*b);
    104     }
    105     //向量除
    106     point div(double b)
    107     {
    108         return point(x/b,y/b);
    109     }
    110     //点乘
    111     double dot(point p)
    112     {
    113         return x*p.x+y*p.y;
    114     }
    115     //叉乘
    116     double det(point p)
    117     {
    118         return x*p.y-y*p.x;
    119     }
    120     //XXXXXXX
    121     double rad(point a,point b)
    122     {
    123         point p=*this;
    124         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
    125     }
    126     //截取长度r
    127     point trunc(double r)
    128     {
    129         double l=len();
    130         if (!dblcmp(l))return *this;
    131         r/=l;
    132         return point(x*r,y*r);
    133     }
    134     //左转90度
    135     point rotleft()
    136     {
    137         return point(-y,x);
    138     }
    139     //右转90度
    140     point rotright()
    141     {
    142         return point(y,-x);
    143     }
    144     //绕点p逆时针旋转angle角度
    145     point rotate(point p,double angle)
    146     {
    147         point v=this->sub(p);
    148         double c=cos(angle),s=sin(angle);
    149         return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
    150     }
    151 };
    152 /*
    153     线段/直线
    154 */
    155 struct line
    156 {
    157     point a,b;
    158     line(){}
    159     line(point _a,point _b)
    160     {
    161         a=_a;
    162         b=_b;
    163     }
    164     //判断线段相等
    165     bool operator==(line v)
    166     {
    167         return (a==v.a)&&(b==v.b);
    168     }
    169     //点p做倾斜角为angle的射线
    170     line(point p,double angle)
    171     {
    172         a=p;
    173         if (dblcmp(angle-pi/2)==0)
    174         {
    175             b=a.add(point(0,1));
    176         }
    177         else
    178         {
    179             b=a.add(point(1,tan(angle)));
    180         }
    181     }
    182     //直线一般式ax+by+c=0
    183     line(double _a,double _b,double _c)
    184     {
    185         if (dblcmp(_a)==0)
    186         {
    187             a=point(0,-_c/_b);
    188             b=point(1,-_c/_b);
    189         }
    190         else if (dblcmp(_b)==0)
    191         {
    192             a=point(-_c/_a,0);
    193             b=point(-_c/_a,1);
    194         }
    195         else
    196         {
    197             a=point(0,-_c/_b);
    198             b=point(1,(-_c-_a)/_b);
    199         }
    200     }
    201     //读入一个线段
    202     void input()
    203     {
    204         a.input();
    205         b.input();
    206     }
    207     //校准线段两点
    208     void adjust()
    209     {
    210         if (b<a)swap(a,b);
    211     }
    212     //线段长度
    213     double length()
    214     {
    215         return a.distance(b);
    216     }
    217     //直线倾斜角 0<=angle<180
    218     double angle()
    219     {
    220         double k=atan2(b.y-a.y,b.x-a.x);
    221         if (dblcmp(k)<0)k+=pi;
    222         if (dblcmp(k-pi)==0)k-=pi;
    223         return k;
    224     }
    225     //点和线段关系
    226     //1 在逆时针
    227     //2 在顺时针
    228     //3 平行
    229     int relation(point p)
    230     {
    231         int c=dblcmp(p.sub(a).det(b.sub(a)));
    232         if (c<0)return 1;
    233         if (c>0)return 2;
    234         return 3;
    235     }
    236     //点是否在线段上
    237     bool pointonseg(point p)
    238     {
    239         return dblcmp(p.sub(a).det(b.sub(a)))==0&&dblcmp(p.sub(a).dot(p.sub(b)))<=0;
    240     }
    241     //两线是否平行
    242     bool parallel(line v)
    243     {
    244         return dblcmp(b.sub(a).det(v.b.sub(v.a)))==0;
    245     }
    246     //线段和线段关系
    247     //0 不相交
    248     //1 非规范相交
    249     //2 规范相交
    250     int segcrossseg(line v)
    251     {
    252         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
    253         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
    254         int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
    255         int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
    256         if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
    257         return (d1==0&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=0||
    258                 d2==0&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=0||
    259                 d3==0&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=0||
    260                 d4==0&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=0);
    261     }
    262     //线段和直线v关系
    263     int linecrossseg(line v)//*this seg v line
    264     {
    265         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
    266         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
    267         if ((d1^d2)==-2)return 2;
    268         return (d1==0||d2==0);
    269     }
    270     //直线和直线关系
    271     //0 平行
    272     //1 重合
    273     //2 相交
    274     int linecrossline(line v)
    275     {
    276         if ((*this).parallel(v))
    277         {
    278             return v.relation(a)==3;
    279         }
    280         return 2;
    281     }
    282     //求两线交点
    283     point crosspoint(line v)
    284     {
    285         double a1=v.b.sub(v.a).det(a.sub(v.a));
    286         double a2=v.b.sub(v.a).det(b.sub(v.a));
    287         return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
    288     }
    289     //点p到直线的距离
    290     double dispointtoline(point p)
    291     {
    292         return fabs(p.sub(a).det(b.sub(a)))/length();
    293     }
    294     //点p到线段的距离
    295     double dispointtoseg(point p)
    296     {
    297         if (dblcmp(p.sub(b).dot(a.sub(b)))<0||dblcmp(p.sub(a).dot(b.sub(a)))<0)
    298         {
    299             return min(p.distance(a),p.distance(b));
    300         }
    301         return dispointtoline(p);
    302     }
    303     //XXXXXXXX
    304     point lineprog(point p)
    305     {
    306         return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
    307     }
    308     //点p关于直线的对称点
    309     point symmetrypoint(point p)
    310     {
    311         point q=lineprog(p);
    312         return point(2*q.x-p.x,2*q.y-p.y);
    313     }
    314 };
    315 
    316 /*
    317     多边形
    318 */
    319 struct polygon
    320 {
    321     int n;//点个数
    322     point p[maxp];//顶点
    323     line l[maxp];//324     //读入一个多边形
    325     void input(int n=4)
    326     {
    327         for (int i=0;i<n;i++)
    328         {
    329             p[i].input();
    330         }
    331     }
    332     //添加一个点
    333     void add(point q)
    334     {
    335         p[n++]=q;
    336     }
    337     //取得边
    338     void getline()
    339     {
    340         for (int i=0;i<n;i++)
    341         {
    342             l[i]=line(p[i],p[(i+1)%n]);
    343         }
    344     }
    345     struct cmp
    346     {
    347         point p;
    348         cmp(const point &p0){p=p0;}
    349         bool operator()(const point &aa,const point &bb)
    350         {
    351             point a=aa,b=bb;
    352             int d=dblcmp(a.sub(p).det(b.sub(p)));
    353             if (d==0)
    354             {
    355                 return dblcmp(a.distance(p)-b.distance(p))<0;
    356             }
    357             return d>0;
    358         }
    359     };
    360     void norm()
    361     {
    362         point mi=p[0];
    363         for (int i=1;i<n;i++)mi=min(mi,p[i]);
    364         sort(p,p+n,cmp(mi));
    365     }
    366     //求凸包存入多边形convex
    367     void getconvex(polygon &convex)
    368     {
    369         int i,j,k;
    370         sort(p,p+n);
    371         convex.n=n;
    372         for (i=0;i<min(n,2);i++)
    373         {
    374             convex.p[i]=p[i];
    375         }
    376         if (n<=2)return;
    377         int &top=convex.n;
    378         top=1;
    379         for (i=2;i<n;i++)
    380         {
    381             while (top&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
    382                 top--;
    383             convex.p[++top]=p[i];
    384         }
    385         int temp=top;
    386         convex.p[++top]=p[n-2];
    387         for (i=n-3;i>=0;i--)
    388         {
    389             while (top!=temp&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
    390                 top--;
    391             convex.p[++top]=p[i];
    392         }
    393     }
    394     //判断是否凸多边形
    395     bool isconvex()
    396     {
    397         bool s[3];
    398         memset(s,0,sizeof(s));
    399         int i,j,k;
    400         for (i=0;i<n;i++)
    401         {
    402             j=(i+1)%n;
    403             k=(j+1)%n;
    404             s[dblcmp(p[j].sub(p[i]).det(p[k].sub(p[i])))+1]=1;
    405             if (s[0]&&s[2])return 0;
    406         }
    407         return 1;
    408     }
    409     //点与多边形关系
    410     //0 外部
    411     //1 内部
    412     //2 边上
    413     //3 点上
    414     int relationpoint(point q)
    415     {
    416         int i,j;
    417         for (i=0;i<n;i++)
    418         {
    419             if (p[i]==q)return 3;
    420         }
    421         getline();
    422         for (i=0;i<n;i++)
    423         {
    424             if (l[i].pointonseg(q))return 2;
    425         }
    426         int cnt=0;
    427         for (i=0;i<n;i++)
    428         {
    429             j=(i+1)%n;
    430             int k=dblcmp(q.sub(p[j]).det(p[i].sub(p[j])));
    431             int u=dblcmp(p[i].y-q.y);
    432             int v=dblcmp(p[j].y-q.y);
    433             if (k>0&&u<0&&v>=0)cnt++;
    434             if (k<0&&v<0&&u>=0)cnt--;
    435         }
    436         return cnt!=0;
    437     }
    438     //线段与多边形关系
    439     //0 无任何交点
    440     //1 在多边形内长度为正
    441     //2 相交或与边平行
    442     int relationline(line u)
    443     {
    444         int i,j,k=0;
    445         getline();
    446         for (i=0;i<n;i++)
    447         {
    448             if (l[i].segcrossseg(u)==2)return 1;
    449             if (l[i].segcrossseg(u)==1)k=1;
    450         }
    451         if (!k)return 0;
    452         vector<point>vp;
    453         for (i=0;i<n;i++)
    454         {
    455             if (l[i].segcrossseg(u))
    456             {
    457                 if (l[i].parallel(u))
    458                 {
    459                     vp.pb(u.a);
    460                     vp.pb(u.b);
    461                     vp.pb(l[i].a);
    462                     vp.pb(l[i].b);
    463                     continue;
    464                 }
    465                 vp.pb(l[i].crosspoint(u));
    466             }
    467         }
    468         sort(vp.begin(),vp.end());
    469         int sz=vp.size();
    470         for (i=0;i<sz-1;i++)
    471         {
    472             point mid=vp[i].add(vp[i+1]).div(2);
    473             if (relationpoint(mid)==1)return 1;
    474         }
    475         return 2;
    476     }
    477     //直线u切割凸多边形左侧
    478     //注意直线方向
    479     void convexcut(line u,polygon &po)
    480     {
    481         int i,j,k;
    482         int &top=po.n;
    483         top=0;
    484         for (i=0;i<n;i++)
    485         {
    486             int d1=dblcmp(p[i].sub(u.a).det(u.b.sub(u.a)));
    487             int d2=dblcmp(p[(i+1)%n].sub(u.a).det(u.b.sub(u.a)));
    488             if (d1>=0)po.p[top++]=p[i];
    489             if (d1*d2<0)po.p[top++]=u.crosspoint(line(p[i],p[(i+1)%n]));
    490         }
    491     }
    492     //取得周长
    493     double getcircumference()
    494     {
    495         double sum=0;
    496         int i;
    497         for (i=0;i<n;i++)
    498         {
    499             sum+=p[i].distance(p[(i+1)%n]);
    500         }
    501         return sum;
    502     }
    503     //取得面积
    504     double getarea()
    505     {
    506         double sum=0;
    507         int i;
    508         for (i=0;i<n;i++)
    509         {
    510             sum+=p[i].det(p[(i+1)%n]);
    511         }
    512         return fabs(sum)/2;
    513     }
    514     bool getdir()//1代表逆时针 0代表顺时针
    515     {
    516         double sum=0;
    517         int i;
    518         for (i=0;i<n;i++)
    519         {
    520             sum+=p[i].det(p[(i+1)%n]);
    521         }
    522         if (dblcmp(sum)>0)return 1;
    523         return 0;
    524     }
    525     //取得重心
    526     point getbarycentre()
    527     {
    528         point ret(0,0);
    529         double area=0;
    530         int i;
    531         for (i=1;i<n-1;i++)
    532         {
    533             double tmp=p[i].sub(p[0]).det(p[i+1].sub(p[0]));
    534             if (dblcmp(tmp)==0)continue;
    535             area+=tmp;
    536             ret.x+=(p[0].x+p[i].x+p[i+1].x)/3*tmp;
    537             ret.y+=(p[0].y+p[i].y+p[i+1].y)/3*tmp;
    538         }
    539         if (dblcmp(area))ret=ret.div(area);
    540         return ret;
    541     }
    542     //点在凸多边形内部的判定
    543     int pointinpolygon(point q)
    544     {
    545         if (getdir())reverse(p,p+n);
    546         if (dblcmp(q.sub(p[0]).det(p[n-1].sub(p[0])))==0)
    547         {
    548             if (line(p[n-1],p[0]).pointonseg(q))return n-1;
    549             return -1;
    550         }
    551         int low=1,high=n-2,mid;
    552         while (low<=high)
    553         {
    554             mid=(low+high)>>1;
    555             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>=0&&dblcmp(q.sub(p[0]).det(p[mid+1].sub(p[0])))<0)
    556             {
    557                 polygon c;
    558                 c.p[0]=p[mid];
    559                 c.p[1]=p[mid+1];
    560                 c.p[2]=p[0];
    561                 c.n=3;
    562                 if (c.relationpoint(q))return mid;
    563                 return -1;
    564             }
    565             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>0)
    566             {
    567                 low=mid+1;
    568             }
    569             else
    570             {
    571                 high=mid-1;
    572             }
    573         }
    574         return -1;
    575     }
    576 };
    View Code

    3.

      1 计算几何模板
      2   1 #include<math.h>
      3   2 #define MAXN 1000
      4   3 #define offset 10000
      5   4 #define eps 1e-8
      6   5 #define PI acos(-1.0)//3.14159265358979323846
      7   6 //判断一个数是否为0,是则返回true,否则返回false
      8   7 #define zero(x)(((x)>0?(x):-(x))<eps)
      9   8 //返回一个数的符号,正数返回1,负数返回2,否则返回0
     10   9 #define _sign(x)((x)>eps?1:((x)<-eps?2:0))
     11  10 struct point 
     12  11 {
     13  12     double x,y;
     14  13 };
     15  14 struct line
     16  15 {
     17  16     point a,b;
     18  17 };//直线通过的两个点,而不是一般式的三个系数
     19  18 //求矢量[p0,p1],[p0,p2]的叉积
     20  19 //p0是顶点
     21  20 //若结果等于0,则这三点共线
     22  21 //若结果大于0,则p0p2在p0p1的逆时针方向
     23  22 //若结果小于0,则p0p2在p0p1的顺时针方向
     24  23 double xmult(point p1,point p2,point p0)
     25  24 {
     26  25     return(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
     27  26 }
     28  27 //计算dotproduct(P1-P0).(P2-P0)
     29  28 double dmult(point p1,point p2,point p0)
     30  29 {
     31  30     return(p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
     32  31 }
     33  32 //两点距离
     34  33 double distance(point p1,point p2)
     35  34 {
     36  35     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
     37  36 }
     38  37 //判三点共线
     39  38 int dots_inline(point p1,point p2,point p3)
     40  39 {
     41  40     return zero(xmult(p1,p2,p3));
     42  41 }
     43  42 //判点是否在线段上,包括端点
     44  43 int dot_online_in(point p,line l)
     45  44 {
     46  45     return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;
     47  46 }
     48  47 //判点是否在线段上,不包括端点
     49  48 int dot_online_ex(point p,line l)
     50  49 {
     51  50     return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));
     52  51 }
     53  52 //判两点在线段同侧,点在线段上返回0
     54  53 int same_side(point p1,point p2,line l)
     55  54 {
     56  55     return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
     57  56 }
     58  57 //判两点在线段异侧,点在线段上返回0
     59  58 int opposite_side(point p1,point p2,line l)
     60  59 {
     61  60     return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
     62  61 }
     63  62 //判两直线平行
     64  63 int parallel(line u,line v)
     65  64 {
     66  65     return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));
     67  66 }
     68  67 //判两直线垂直
     69  68 int perpendicular(line u,line v)
     70  69 {
     71  70     return zero((u.a.x-u.b.x)*(v.a.x-v.b.x)+(u.a.y-u.b.y)*(v.a.y-v.b.y));
     72  71 }
     73  72 //判两线段相交,包括端点和部分重合
     74  73 int intersect_in(line u,line v)
     75  74 {
     76  75     if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
     77  76         return!same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
     78  77     return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);
     79  78 }
     80  79 //判两线段相交,不包括端点和部分重合
     81  80 int intersect_ex(line u,line v)
     82  81 {
     83  82     return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
     84  83 }
     85  84 //计算两直线交点,注意事先判断直线是否平行!
     86  85 //线段交点请另外判线段相交(同时还是要判断是否平行!)
     87  86 point intersection(line u,line v)
     88  87 {
     89  88     point ret=u.a;
     90  89     double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
     91  90     ret.x+=(u.b.x-u.a.x)*t;
     92  91     ret.y+=(u.b.y-u.a.y)*t;
     93  92     return ret;
     94  93 }
     95  94 //点到直线上的最近点
     96  95 point ptoline(point p,line l)
     97  96 {
     98  97     point t=p;
     99  98     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
    100  99     return intersection(p,t,l.a,l.b);
    101 100 }
    102 101 //点到直线距离
    103 102 double disptoline(point p,line l)
    104 103 {
    105 104     return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
    106 105 }
    107 106 //点到线段上的最近点
    108 107 point ptoseg(point p,line l)
    109 108 {
    110 109     point t=p;
    111 110     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
    112 111     if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
    113 112         return distance(p,l.a)<distance(p,l.b)?l.a:l.b;
    114 113     return intersection(p,t,l.a,l.b);
    115 114 }
    116 115 //点到线段距离
    117 116 double disptoseg(point p,line l)
    118 117 {
    119 118     point t=p;
    120 119     t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
    121 120     if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
    122 121         return distance(p,l.a)<distance(p,l.b)?distance(p,l.a):distance(p,l.b);
    123 122     return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
    124 123 }
    125 124 struct TPoint
    126 125 {
    127 126     double x,y;
    128 127     TPoint operator-(TPoint&a)
    129 128     {
    130 129         TPoint p1;
    131 130         p1.x=x-a.x;
    132 131         p1.y=y-a.y;
    133 132         return p1;
    134 133     }
    135 134 };
    136 135 
    137 136 struct TLine
    138 137 {
    139 138     double a,b,c;
    140 139 };
    141 140 
    142 141 //求p1关于p2的对称点
    143 142 TPoint symmetricalPoint(TPoint p1,TPoint p2)
    144 143 {
    145 144     TPoint p3;
    146 145     p3.x=2*p2.x-p1.x;
    147 146     p3.y=2*p2.y-p1.y;
    148 147     return p3;
    149 148 }
    150 149 //p点关于直线L的对称点
    151 150 TPoint symmetricalPointofLine(TPoint p,TLine L)
    152 151 {
    153 152     TPoint p2;
    154 153     double d;
    155 154     d=L.a*L.a+L.b*L.b;
    156 155     p2.x=(L.b*L.b*p.x-L.a*L.a*p.x-2*L.a*L.b*p.y-2*L.a*L.c)/d;
    157 156     p2.y=(L.a*L.a*p.y-L.b*L.b*p.y-2*L.a*L.b*p.x-2*L.b*L.c)/d;
    158 157     return p2;
    159 158 }
    160 159 //求线段所在直线,返回直线方程的三个系数
    161 160 //两点式化为一般式
    162 161 TLine lineFromSegment(TPoint p1,TPoint p2)
    163 162 {
    164 163     TLine tmp;
    165 164     tmp.a=p2.y-p1.y;
    166 165     tmp.b=p1.x-p2.x;
    167 166     tmp.c=p2.x*p1.y-p1.x*p2.y;
    168 167     return tmp;
    169 168 }
    170 169 //求直线的交点
    171 170 //求直线的交点,注意平行的情况无解,避免RE
    172 171 TPoint LineInter(TLine l1,TLine l2)
    173 172 {
    174 173     //求两直线得交点坐标
    175 174     TPoint tmp;
    176 175     double a1=l1.a;
    177 176     double b1=l1.b;
    178 177     double c1=l1.c;
    179 178     double a2=l2.a;
    180 179     double b2=l2.b;
    181 180     double c2=l2.c;
    182 181     //注意这里b1=0
    183 182     if(fabs(b1)<eps){
    184 183         tmp.x=-c1/a1;
    185 184         tmp.y=(-c2-a2*tmp.x)/b2;
    186 185     }
    187 186     else{
    188 187         tmp.x=(c1*b2-b1*c2)/(b1*a2-b2*a1);
    189 188         tmp.y=(-c1-a1*tmp.x)/b1;
    190 189     }
    191 190     //cout<<"交点坐标"<<endl;
    192 191     //cout<<a1*tmp.x+b1*tmp.y+c1<<endl;
    193 192     //cout<<a2*tmp.x+b2*tmp.y+c2<<endl;
    194 193     return tmp;
    195 194 }
    196 195 //矢量(点)V以P为顶点逆时针旋转angle(弧度)并放大scale倍
    197 196 point rotate(point v,point p,double angle,double scale){
    198 197     point ret=p;
    199 198     v.x-=p.x,v.y-=p.y;
    200 199     p.x=scale*cos(angle);
    201 200     p.y=scale*sin(angle);
    202 201     ret.x+=v.x*p.x-v.y*p.y;
    203 202     ret.y+=v.x*p.y+v.y*p.x;
    204 203     return ret;
    205 204 }
    206 205 //矢量(点)V以P为顶点逆时针旋转angle(弧度)
    207 206 point rotate(point v,point p,double angle){
    208 207     double cs=cos(angle),sn=sin(angle);
    209 208     v.x-=p.x,v.y-=p.y;
    210 209     p.x+=v.x*cs-v.y*sn;
    211 210     p.y+=v.x*sn+v.y*cs;
    212 211     return p;
    213 212 }
    View Code
  • 相关阅读:
    使用Python开发IOT Edge应用(2)
    使用Python开发IOT Edge应用(1)
    使用Harbor+Auzre IOT Edge构建智能边界(2)
    使用Harbor+Auzre IOT Edge构建智能边界
    Linux开发人员玩转HDInsight集群上的MapReduce
    将人工智能带到物联网边界设备(2)
    将人工智能带到物联网边界设备(1)
    oracle误删存储过程
    ORACLE审计
    ESXI将虚拟机厚置备转换成精简置备
  • 原文地址:https://www.cnblogs.com/pdev/p/4190210.html
Copyright © 2011-2022 走看看