計算幾何 學習

手敲備用

 

 1 const double esp=1e-8;
 2 const double PI=3.141592653589793;
 3 struct Pnt
 4 {
 5     double x,y;
 6     Pnt(double _x=0.0,double _y=0.0):x(_x),y(_y){}
 7     Pnt(Pnt &a,Pnt &b)
 8     {
 9         x=b.x-a.x;
10         y=b.y-a.y;
11     }
12     bool operator==(const Pnt &t){return (fabs(x-t.x)<esp&&fabs(y-t.y)<esp);}
13     double operator^(Pnt &t){return x*t.y-y*t.x;}    //叉積
14     double operator*(Pnt &t){return x*t.x+y*t.y;}    //點積
15     Pnt operator*(double t){Pnt ret=*this;ret.x*=t,ret.y*=t;return ret;}//乘浮點數
16     Pnt operator+(Pnt &t){return Pnt(x+t.x,y+t.y);}
17     Pnt operator-(Pnt &t){return Pnt(x-t.x,y-t.y);}
18     Pnt normal(){return Pnt(-y/len(),x/len());}//法向量
19     double len(){return sqrt(x*x+y*y);}//向量模
20 };
21 typedef Pnt Vec;
22 
23 int dcmp(double x)//判斷:正,負,零
24 {
25     if(fabs(x)<esp)
26         return 0;
27     else
28         return x<0?-1:1;
29 }
30 
31 inline bool equ(const double &a,const double &b)//誤差內相等
32 {
33     return fabs(a-b)<esp;
34 }
35 
36 bool cmp1(Pnt &a,Pnt &b)//極角排序(速度快)
37 {
38     double ta=atan2(a.y,a.x);
39     double tb=atan2(b.y,b.x);
40     if(equ(ta,tb))
41         return a.x<b.x;
42     return ta<tb;
43 }
44 
45 bool cmp2(Pnt &a,Pnt &b)//極角排序(精度高)
46 {
47     Pnt o;
48     Vec va(o,a);
49     Vec vb(o,b);
50     double j=va^vb;
51     if(j==0)
52         return a.x<b.x;
53     return j>0;
54 }
55 
56 double displ(Pnt &p,Pnt &a,Pnt &b)//(點到直線的距離)
57 {
58     Vec v(a,p);
59     Vec u(a,b);
60     return fabs(u^v)/u.len();
61 }
62 double disps(Pnt &p,Pnt &a,Pnt &b)//點到線段的距離
63 {
64     if(a==b)
65         return Vec(a,p).len();
66     Vec v1(a,b),v2(a,p),v3(b,p);
67     if(dcmp(v1*v2)<0)
68         return v2.len();
69     else if(dcmp(v1*v3)>0)
70         return v3.len();
71     return displ(p,a,b);
72 }
73 
74 bool s_sint(Pnt &a,Pnt &b,Pnt &c,Pnt &d)//判斷線段相交
75 {
76     Vec v1(a,c),v2(a,d),v3(b,c),v4(b,d);
77     double j1=v1^v2;
78     double j2=v3^v4;
79     Vec v5(c,a),v6(c,b),v7(d,a),v8(d,b);
80     double j3=v5^v6;
81     double j4=v7^v8;
82     return j1*j2<0&&j3*j4<0;
83 }
84 
85 bool s_lint(Pnt &a,Pnt &b,Pnt &c,Pnt &d)//判斷線段與直線相交(a,b為線段)
86 {
87     Vec v1(a,c),v2(a,d),v3(b,c),v4(b,d);
88     double j1=v1^v2;
89     double j2=v3^v4;
90     return j1*j2<0;
91 }
92 
93 Pnt l_lint(Pnt &a,Pnt &b,Pnt &c,Pnt &d)//兩直線交點
94 {
95     Vec v(a,b),w(c,d),u(c,a);
96     double t=(w^u)/(v^w);
97     w=v*t;
98     return a+w;
99 }
模板

 

posted @ 2018-12-21 16:28  Lin88  阅读(140)  评论(0编辑  收藏  举报