• 计算几何模板( 未测试 )


    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<vector>
    
    using namespace std;
    
    #define mnx 50050
    #define LL long long
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define eps 1e-8
    #define Pi acos(-1.0);
    #define lson l, m, rt << 1
    #define rson m+1, r, rt << 1 | 1
    
    // 角度与弧度转换 
    double todeg( double rad ){
        return rad * 180 / Pi;
    }
    double torad( double deg ){
        return deg / 180 * Pi;
    } 
    
    int dcmp( double x ){
        if( fabs( x ) < eps ) return 0;
        return x < 0 ? -1 : 1; 
    }
    //
    struct point{
        double x, y;
        point( double x = 0, double y = 0 ) : x(x), y(y) {}
        point operator + ( const point &b ) const{
            return point( x + b.x, y + b.y );
        }
        point operator - ( const point &b ) const{
            return point( x - b.x, y - b.y );
        }
        point operator * ( const double &k ) const{
            return point( x * k, y * k );
        }
        point operator / ( const double &k ) const{
            return point( x / k, y / k );
        }
        bool operator < ( const point &b ) const{
            return dcmp( x - b.x ) < 0 || dcmp( x - b.x ) == 0 && dcmp( y - b.y ) < 0;
        }
        bool operator == ( const point &b ) const{
            return dcmp( x - b.x ) == 0 && dcmp( y - b.y ) == 0;
        }
        double len(){
            return sqrt( x * x + y * y );
        }
    }; 
    typedef point Vector;
    // 点积
    double dot( Vector a, Vector b ){
        return a.x * b.x + a.y * b.y; 
    } 
    // 叉积
    double cross( Vector a, Vector b ){
        return a.x * b.y - a.y * b.x;
    } 
    // 向量旋转
    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 = a.len(); 
        return Vector( -a.y / L, a.x / L ); 
    } 
    // 点到直线的距离
    double dis_to_line( point p, point a, point b ){
        Vector v1 = b - a, v2 = p - a;
        return fabs( cross( v1, v2 ) / v1.len() ); 
    } 
    // 点到线段的距离
    double dis_to_segment( point p, point a, point b ){
        if( a == b ) return (p-a).len();
        Vector v1 = b - a, v2 = p - a, v3 = p - b;
        if( dcmp( dot( v1, v2 ) ) < 0 ) return v2.len();
        else if( dcmp( dot( v1, v3 ) ) > 0 ) return v3.len();
        else return fabs( cross( v1, v2 ) ) / v1.len(); 
    } 
    // 点到直线上的投影
    point get_line_projection( point p, point a, point b ){
        Vector v = b - a;
        return a + v * ( dot( v, p - a ) / dot( v, v ) ); 
    } 
    // 线段相交判定 
    bool segment_intersection( point a1, point a2, point b1, point b2 ){
        double c1 = cross( a2 - a1, b1 - a1 ), c2 = cross( a2 - a1, b2 - a1 );
        double c3 = cross( b2 - b1, a1 - b1 ), c4 = cross( b2 - b1, a2 - b1 );
        return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
    }
    // 判断点是否在一条线段上 
    bool on_segment( point p, point a1, point a2 ){
        return dcmp( cross( a1 - p, a2 - p ) ) == 0 && dcmp( dot( a1 - p, a2 - p ) ) < 0; 
    } 
    // 多边形面积 
    double polygon_area( point *p, int n ){
        double area = 0;
        for( int i = 1; i < n - 1; i++ ){
            area += cross( p[i] - p[0], p[i+1] - p[0] );
        }
        return area / 2;
    }
    // 点在多边形内判定
    int point_in( point p, point *poly, int n ){
        int wn = 0;
        poly[n] = poly[0];
        for( int i = 0; i < n; i++ ){
            if( on_segment( p, poly[i], poly[i+1] ) ) return -1;
            int k = dcmp( cross( poly[i+1] - poly[i], p - poly[i] ) );
            int d1 = dcmp( poly[i].y - p.y );
            int d2 = dcmp( poly[i+1].y - p.y );
            if( k > 0 && d1 <= 0 && d2 > 0 ) wn++;
            if( k < 0 && d2 <= 0 && d1 > 0 ) wn--; 
        }
        if( wn != 0 ) return 1;
        return 0;
    } 
    // 多边形重心
    point masscenter( point *p, int n ){
        point ans = point( 0, 0 );
        double sum = polygon_area( p, n );
        if( dcmp( sum ) == 0 ) return ans;
        p[n] = p[0];
        for( int i = 0; i < n; i++ ){
            ans = ans + ( p[i] + p[i+1] ) * cross( p[i+1], p[i] );
        } 
        return ans / sum / 6.0;
    } 
    // 凸包(要去重,边上没有输入点) 
    int convex_hull( point *p, int n, point *ch ){
        sort( p, p + n );
        int b = 0, c = 0;              
        while( c < n ){
            p[b++] = p[c++];
            while( c < n && p[b-1] == p[c] ) c++;
        }
        n = b;
        int m = 0;
        for( int i = 0; i < n; i++ ){
            while( m > 1 && cross( ch[m-1] - ch[m-2], p[i] - ch[m-2] ) <= 0 ) m--;
            ch[m++] = p[i];
        }
        int k = m;
        for( int i = n - 2; i >= 0; i-- ){
            while( m > k && cross( ch[m-1] - ch[m-2], p[i] - ch[m-2] ) <= 0 ) m--;
            ch[m++] = p[i]; 
        }
        if( n > 1 ) m--;
        return m; 
    }
    // 线
    struct Line{
        point p; 
        Vector v;
        double ang;
        Line() {}
        Line( point p, point v ) : p(p), v(v) {
            ang = atan2( v.y - 0.0, v.x - 0.0 );
        }
        bool operator < ( const Line &b ) const{
            return ang < b.ang;
        }
    };
    // 点p在有向直线L的左边(线上不算)
    bool onleft( Line L, point p ){
        return cross( L.v, p - L.p ) > 0; 
    }  
    // 二直线交点
    point get_intersection( Line a, Line b ){
        Vector u = a.p - b.p;
        double t = cross( b.v, u ) / cross( a.v, b.v );
        return a.p + a.v + t;
    } 
    // 半平面交
    int half_plane_intersection( Line *L, int n, point *poly ){
        sort( L, L + n );
        int first, last;
        point *p = new point[n];
        Line *q = new Line[n];
        q[first = last = 0] = L[0];
        for( int i = 1; i < n; i++ ){
            while( first < last && !onleft( L[i], p[last-1] ) ) last--;
            while( first < last && !onleft( L[i], p[first] ) ) first++;
            q[++last] = L[i];
            if( fabs( cross( q[last].v, q[last-1].v ) ) < eps ){
                last--;
                if( onleft( q[last], L[i].p ) ) q[last] = L[i];
            } 
            if( first < last ){
                p[last-1] = get_intersection( q[last-1], q[last] );
            }
        } 
        while( first < last && !onleft( q[first], p[last-1] ) ) last--;
        if( last - first <= 1 ) return 0;
        p[last] = get_intersection( q[last], q[first] );
        int m = 0;
        for( int i = first; i <= last; i++ ) poly[m++] = p[i];
        return m; 
    }
    // 旋转卡壳
    double rotating_calipers( point *ch, int n ){
        int j = 1;
        double ans = 0;
        ch[n] = ch[0];
        for( int i = 0; i < n; i++ ){
            while( fabs( cross( ch[i+1]-ch[i], ch[j+1]-ch[i] ) ) > fabs( cross( ch[i+1]-ch[i], ch[j] - ch[i] ) ) ) 
                j = ( j + 1 ) % n;
            ans = max( ans, max( ( ch[i] - ch[j] ).len(), ( ch[i+1] - ch[j] ).len() ) );
        } 
        return ans;
    } 
    ///
    ///
    ///
    int main(){
        return 0;
    }
  • 相关阅读:
    repo
    manifest
    Gerrit使用简介
    id_rsa id_rsa.pub
    数字签名原理及其应用
    RSA DSA
    ssh(安全协议外壳)
    Numpy基本数据结构
    Numpy
    .bat 批处理
  • 原文地址:https://www.cnblogs.com/LJ-blog/p/3960950.html
Copyright © 2020-2023  润新知