【模板】计几常用函数
1 struct Line{ 2 double a,b,c; 3 }; 4 struct Point{ 5 double x,y; 6 Point(){x=y=0;} 7 8 Point(double a,double b){x=a,y=b;} 9 10 Point operator - (const Point& b)const 11 {return Point(x-b.x,y-b.y);} 12 13 Point operator + (const Point& b)const 14 {return Point(x+b.x,y+b.y);} 15 16 Point operator * (const double& b)const 17 {return Point(x*b,y*b);} 18 19 //点看做向量,然后向量逆时针旋转 b (是弧度制) 20 Point rotate(const double& b)const 21 {return Point( x*cos(b) - y*sin(b) , x*sin(b) + y*cos(b) );} 22 23 //求点关于直线l对称的点 24 Point corPoint(Line l)const{ 25 Point p2; 26 double d = l.a*l.a + l.b*l.b; 27 p2.x = ( (l.b*l.b - l.a*l.a)*x - 2 * l.a * l.b * y - 2*l.a*l.c) /d; 28 p2.y = ( (l.a*l.a - l.b*l.b)*y - 2 * l.a * l.b * x - 2*l.b*l.c) /d; 29 return p2; 30 } 31 32 double dot (const Point& b)const 33 {return x*b.x+y*b.y;} 34 35 double cross (const Point& b,const Point& c)const 36 {return (b.x - x)*(c.y - y) - (c.x - x)*(b.y - y);} 37 38 double ToPdis (const Point& b)const 39 {return sqrt( (x-b.x)*(x-b.x) + (y-b.y)*(y-b.y) );} 40 41 //点到直线距离 42 double ToLdis (Line l)const{ 43 return fabs(l.a * x + l.b * y + l.c) / sqrt(l.a*l.a + l.b*l.b); 44 } 45 46 bool OnLine (const Point& st,Point& ed)const 47 {return !sgn(cross(st,ed));} 48 49 bool OnSeg (const Point& st,Point& ed)const 50 {return OnLine(st,ed) && (*this - ed).dot(*this - st) < eps;} 51 };
1 //两线段是否相交 2 bool insert(Line l1,Line l2){ 3 return 4 max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) && 5 max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) && 6 max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) && 7 max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) && 8 sgn((l2.s-l1.s)^(l1.e-l1.s))*sgn((l2.e-l1.s)^(l1.e-l1.s))<=0 && 9 sgn((l1.s-l2.s)^(l2.e-l2.s))*sgn((l1.e-l2.s)^(l2.e-l2.s))<=0; 10 } 11 //两点求出直线 12 Line twoPoLine(Point p1,Point p2){ 13 Line l; 14 l.a = p2.y - p1.y; 15 l.b = p1.x - p2.x; 16 l.c = p2.x * p1.y - p1.x * p2.y; 17 return l; 18 } 19 20 Point LineCross(Point a,Point b,Point c,Point d){ 21 double u = a.cross(b,c), v = b.cross(a,d); 22 return Point( (c.x*v + d.x*u)/(u+v) , (c.y*v + d.y*u)/(u+v) ); 23 } 24 //求垂足 25 Point footOfPerpendicular(const Line& l, const Point& p) 26 { 27 double t = (l.a * p.x + l.b * p.y + l.c) / (l.a * l.a + l.b * l.b); 28 return p + Point(l.a, l.b) * t; 29 }
1 Point GetLineIntersection(Point a, Point va, Point b, Point vb) { 2 Point u = a - b; 3 double t = (vb ^ u) / (va ^ vb); 4 return a + va * t; 5 }
极角排序
1 int Quadrant(Point b)//象限排序 2 { 3 Point a = b - p0; 4 if(a.x>=0&&a.y>=0) return 1; 5 if(a.x<=0&&a.y>=0) return 2; 6 if(a.x<=0&&a.y<=0) return 3; 7 return 4; 8 } 9 10 11 bool cmp(Point a,Point b) //先按象限从小到大排序 再按极角从小到大排序 12 { 13 if(Quadrant(a)==Quadrant(b)){ 14 if( p0.cross(a,b) == 0) return p0.dis(a) < p0.dis(b); 15 return p0.cross(a,b) > 0; 16 } 17 else return Quadrant(a)<Quadrant(b); 18 }