計算幾何 學習
手敲備用
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 }