计算几何模板啦啦啦啦

来源:互联网 发布:数控折弯机编程操作 编辑:程序博客网 时间:2024/05/17 17:42

计算几何模板啦啦啦

别的不多说.. 给出计算几何模板..
(这个模板大多数都是从刘汝佳《算法竞赛入门经典》中摘录的..)

#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>#include <cmath>#include <vector>#include <queue>#include <complex>#include <deque>using namespace std;struct Point {    double x, y;    Point ( double x=0, double y=0 ) : x(x), y(y) {} //构造函数,方便代码编写};typedef Point Vector;//向量+向量=向量 点+向量=点Vector operator + ( Vector A, Vector B ){ return Vector ( A.x+B.x, A.y+B.y ); }//点-点=向量Vector operator - ( Vector A, Vector B ){ return Vector ( A.x-B.x, A.y-B.y ); }//向量*数=向量Vector operator * ( Vector A, double p ){ return Vector ( A.x*p, A.y*p ); }//向量/数=向量Vector operator / ( Vector A, double p ){ return Vector ( A.x/p, A.y/p ); }//精度const double eps = 1e-10;double _max ( double x, double y ){ return x > y ? x : y; }double _min ( double x, double y ){ return x < y ? x : y; }double _abs ( double x ){ return x < 0 ? -x : x; }int zero ( double x ){ return _abs (x) < eps ? 1 : 0; }int dcmp ( double x ){    if ( zero (x) == 1 ) return 0;    return x < 0 ? -1 : 1;}bool operator == ( const Point &a, const Point &b ){    return zero (a.x-b.x) && zero (a.y-b.y);}double Dot ( Vector A, Vector B ){ return A.x*B.x + A.y*B.y; }double Length ( Vector A ){ return sqrt ( Dot ( A, A ) ); }//acos返回余弦弧度double Angle ( Vector A, Vector B ){ return acos ( Dot ( A, B ) / Length (A) / Length (B) ); }double Cross ( Vector A, Vector B ){ return A.x*B.y - A.y*B.x; }double Area2 ( Point A, Point B, Point C ){ return Cross ( B-A, C-A ); }//rad是弧度Vector Rotate ( Vector A, double rad ){    return Vector ( A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad) );}//向量的单位法向量Vector Normal ( Vector A ){    double L = Length (A);    return Vector ( -A.y/L, A.x/L );}//求直线P+tv和Q+tw的交点(参数式)Point GetLineIntersection ( Point P, Vector v, Point Q, Vector w ){    Vector u = P-Q;    double t = Cross ( w, u ) / Cross ( v, w );    return P+v*t;}//求p1、p2构成的直线和p3、p4构成的直线的交点(两点式)Point GetLineIntersectionB ( Point p1, Point p2, Point p3, Point p4 ){    double a1, b1, c1, a2, b2, c2;    a1 = p1.y-p2.y;    b1 = p2.x-p1.x;    c1 = p1.x*p2.y-p1.y*p2.x;    a2 = p3.y-p4.y;    b2 = p4.x-p3.x;    c2 = p3.x*p4.y-p3.y*p4.x;    return Point ( (c1*b2-c2*b1)/(a2*b1-a1*b2), (c2*a1-c1*a2)/(a2*b1-a1*b2) );}//求点到直线的距离double DistanceToLine ( Point P, Point A, Point B ){    Vector v1 = B-A, v2 = P-A;    return _abs ( Cross ( v1, v2 ) ) / Length (v1);}//求点到线段的距离double DistanceToSegment ( Point P, Point A, Point B ){    if ( A == B ) return Length (P-A);    Vector v1 = B-A, v2 = P-A, v3 = P-B;    if ( dcmp ( Dot ( v1, v2 ) ) < 0 ) return Length (v2);    else if ( dcmp ( Dot ( v1, v3 ) ) > 0 ) return Length (v3);    else return _abs ( Cross ( v1, v2  ) ) / Length (v1);}//求点在直线上的投影Point GetLineProjection ( Point P, Point A, Point B ){    Vector v = B-A;    return A+v*( Dot ( v, P-A ) / Dot ( v, v ) );}//判断线段相交(规范相交)bool SegmentProperIntersection ( Point p1, Point p2, Point p3, Point p4 ){    if ( Cross ( p1-p3, p2-p3 ) * Cross ( p1-p4, p2-p4 ) < 0 && Cross ( p3-p1, p4-p1 ) * Cross ( p3-p2, p4-p2 ) < 0 ) return true;    return false;}//判断线段相交(非规范相交)bool SegmentImproperIntersection ( Point p1, Point p2, Point p3, Point p4 ){    //正常相交    if ( Cross ( p1-p3, p2-p3 ) * Cross ( p1-p4, p2-p4 ) < 0 && Cross ( p3-p1, p4-p1 ) * Cross ( p3-p2, p4-p2 ) < 0 ) return true;    //p1在y上    if ( Cross ( p3-p1, p4-p1 ) == 0 && _min(p3.x,p4.x) <= p1.x && p1.x <= _max(p3.x,p4.x) && _min(p3.y,p4.y) <= p1.y && p1.y <= _max(p3.y,p4.y) ) return true;    //p2在y上    if ( Cross ( p3-p2, p4-p2 ) == 0 && _min(p3.x,p4.x) <= p2.x && p2.x <= _max(p3.x,p4.x) && _min(p3.y,p4.y) <= p2.y && p2.y <= _max(p3.y,p4.y) ) return true;    //p3在x上    if ( Cross ( p1-p3, p2-p3 ) == 0 && _min(p1.x,p2.x) <= p3.x && p3.x <= _max(p1.x,p2.x) && _min(p1.y,p2.y) <= p3.y && p3.y <= _max(p1.y,p2.y) ) return true;    //p4在x上    if ( Cross ( p1-p4, p2-p4 ) == 0 && _min(p1.x,p2.x) <= p4.x && p4.x <= _max(p1.x,p2.x) && _min(p1.y,p2.y) <= p4.y && p4.y <= _max(p1.y,p2.y) ) return true;    return false;}//多边形的有向面积double PolygonArea ( Point *p, int n ){    double area = 0.0;    for ( int i = 2; i < n; i ++ ){        area += Cross ( p[i]-p[1], p[i+1]-p[1] );    }    return area/2.0;}struct Circle {    Point c;    double r;    Circle ( Point c=0, double r=0 ) : c(c), r(r) {}    Point point ( double a ){ //知道极角求圆上坐标        return Point ( c.x+cos(a)*r, c.y+sin(a)*r );    }};struct Line {    Point p1, p2;};vector <Point> sol;//求直线和圆的交点,返回交点的个数int GetLineCircleIntersection ( Line L, Circle C ){    Point p, p1, p2;    p = GetLineProjection ( C.c, L.p1, L.p2 );    double dis = Length ( C.c-p );    if ( zero(dis-C.r) == 1 ){ sol.push_back (p); return 1; }    if ( dis > C.r ) return 0;    Vector v = (L.p2-L.p1) / Length (L.p2-L.p1);    double t = sqrt ( C.r*C.r - dis*dis );    p1 = p+v*t;    p2 = p-v*t;    sol.push_back (p1);    sol.push_back (p2);    return 2;}//求极角double angle ( Vector v ){ return atan2 ( v.y, v.x ); }//两圆相交,返回交点个数int GetCircleCircleIntersection ( Circle C1, Circle C2 ){    double d = Length (C1.c-C2.c);    if ( dcmp (d) == 0 ){        if ( dcmp (C1.r-C2.r) == 0 ) return -1; //两圆重合        return 0;    }    if ( dcmp (C1.r+C2.r-d) < 0 ) return 0;    if ( dcmp ( _abs (C1.r-C2.r)-d ) > 0 ) return 0;    double a = angle (C2.c-C1.c);    double da = acos ( (C1.r*C1.r+d*d-C2.r*C2.r) / (2*C1.r*d) );    Point p1 = C1.point (a-da), p2 = C1.point (a+da);    sol.push_back (p1);    if ( p1 == p2 ) return 1;    sol.push_back (p2);    return 2;}const double PI = acos (-1);Vector v[2];//过p作圆C的切线int GetTarget ( Point p, Circle C ){    Vector u = C.c - p;    double dis = Length (u);    if ( dis < C.r ) return 0;    else if ( dcmp (dis-C.r) == 0 ){        v[0] = Rotate ( u, PI/2 );        return 1;    }    else {        double ang = asin (C.r/dis);        v[0] = Rotate ( u, -ang );        v[1] = Rotate ( u, +ang );        return 2;    }}//求两圆的公切线Point a[10], b[10];int GetTangents ( Circle A, Circle B ){    int cnt = 0;    if ( A.r < B.r ){ swap ( A, B ); swap ( a, b ); }    double d2 = (A.c.x-B.c.x)*(A.c.x-B.c.x) + (A.c.y-B.c.y)*(A.c.y-B.c.y);    double rdiff = A.r-B.r;    double rsum = A.r+B.r;    if ( d2 < rdiff*rdiff ) return 0;    double base = atan2 ( B.c.y-A.c.y, B.c.x-A.c.x );    if ( zero (d2) && A.r == B.r ) return -1;    if ( zero ( rdiff*rdiff-d2 ) ){        cnt ++;        a[cnt] = A.point (base); b[cnt] = B.point (base);        return 1;    }    double ang = acos ((A.r-B.r)/sqrt(d2));    cnt ++; a[cnt] = A.point (base+ang); b[cnt] = B.point (base+ang);    cnt ++; a[cnt] = A.point (base-ang); b[cnt] = B.point (base-ang);    if ( zero ( rsum*rsum-d2 ) ){        cnt ++; a[cnt] = A.point (base); b[cnt] = B.point (PI+base);    }    else if ( d2 > rsum*rsum ){        double ang = acos ((A.r+B.r)/sqrt(d2));        cnt ++; a[cnt] = A.point (base+ang); b[cnt] = B.point (PI+base+ang);        cnt ++; a[cnt] = A.point (base-ang); b[cnt] = B.point (PI+base-ang);    }    return cnt;}int main (){    return 0;}
0 0
原创粉丝点击