计算几何模板( 未测试 )

#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;
}

 

posted @ 2014-09-07 23:29  L__J  阅读(144)  评论(0编辑  收藏  举报