⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 line.h

📁 任意给定三维空间的点集
💻 H
字号:
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* * line.h - *     Represents a line in the plane. Adapted from CGAL.\*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/#ifndef  __LINE__H#define  __LINE__H#ifndef  ___XGENERIC__H//#error must include file "generic.h" before this file#endif  /* ___XGENERIC__H */template <class NT>int Msign(const NT &x){    return (x < NT(0)) ? -1: (x > NT(0)) ? 1 : 0;}#define  DASSERT( X, Y)   {if  ( !(X) ) { fprintf( stderr, Y ); assert(X); }}typedef  double  real;typedef  Vector3d   point;#define  DOUBLE_EPS  1e-10class  segment;class  line;//class  dpoint;/* compute inteersection of two lines */point  intersect_lines( const line  & l1, const line  & l2,                         bool  & f_intersect );point * intersect_lines_ptr( const line  & l1, const line  & l2,                              bool  & f_intersect );class  line {private:    real   arr[ 3 ];    double   d_arr[ 3 ];    int  _id, _true_id;    bool   fSplitter;    inline void   init( const real  & a, const real  & b, const real  & c,                        int  id = -1 )     { #ifdef  EXACT_ARITHMETIC        /*        Integer   lc = a.denominator() * b.denominator() * c.denominator();        Integer   an( a.numerator() * (lc / a.denominator()) );        Integer   bn( b.numerator() * (lc / b.denominator()) );        Integer   cn( c.numerator() * (lc / c.denominator()) );                // We can even do better, by dividing in the gcd of an, bn, cn         Integer   gc( gcd( gcd( an, bn ), cn ) );        if  ( gc == 0 )            gc = 1;        arr[ 0 ] = real( an / gc );        arr[ 1 ] = real( bn / gc );        arr[ 2 ] = real( cn / gc );        */        arr[ 0 ] = a ;        arr[ 1 ] = b ;        arr[ 2 ] = c ;        d_arr[ 0 ] = ( arr[ 0 ] );        d_arr[ 1 ] = ( arr[ 1 ] );        d_arr[ 2 ] = ( arr[ 2 ] );#else                   arr[ 0 ] = a;        arr[ 1 ] = b;        arr[ 2 ] = c;#endif        fSplitter = false;        _id = id;        _true_id = -1;    }public:    const real  & a() const    {        return  arr[ 0 ];    }    const real  & b() const    {        return  arr[ 1 ];    }    const real  & c() const    {        return  arr[ 2 ];    }    const double  & d_a() const    {        return  d_arr[ 0 ];    }    const double  & d_b() const    {        return  d_arr[ 1 ];    }    const double  & d_c() const    {        return  d_arr[ 2 ];    }    inline void   compress()  const    {#ifdef  EXACT_ARITHMETIC        Integer   lc = a().denominator() * b().denominator() * c().denominator();        Integer   an( a().numerator() * (lc / a().denominator()) );        Integer   bn( b().numerator() * (lc / b().denominator()) );        Integer   cn( c().numerator() * (lc / c().denominator()) );                // We can even do better, by dividing in the gcd of an, bn, cn         Integer   gc( gcd( gcd( an, bn ), cn ) );        if  ( gc == 0 )            gc = 1;        *(real *)&(arr[ 0 ]) = real( an / gc );        *(real *)&(arr[ 1 ]) = real( bn / gc );        *(real *)&(arr[ 2 ]) = real( cn / gc );#endif //  EXACT_ARITHMETIC    }    line()     {        init( 0, 0, 0 );    }    line( const point  & p, const point  & q, int  id = -1 )     {        init( p.y - q.y,              q.x - p.x,              p.x*q.y - p.y*q.x, id );    }        line( const real  & _a, const real  & _b, const real  & _c, int  id = -1 )    {        init( _a, _b, _c, id );    }    void  init( const line  & l)    {        arr[ 0 ] = l.arr[ 0 ];        arr[ 1 ] = l.arr[ 1 ];        arr[ 2 ] = l.arr[ 2 ];                d_arr[ 0 ] = l.d_arr[ 0 ];        d_arr[ 1 ] = l.d_arr[ 1 ];        d_arr[ 2 ] = l.d_arr[ 2 ];        _id = l._id;        _true_id = l._true_id;        fSplitter = l.fSplitter;    }    line( const line  & l )     {        init( l );    }    line  & operator=(const line  &l)    {        arr[ 0 ] = l.arr[ 0 ];        arr[ 1 ] = l.arr[ 1 ];        arr[ 2 ] = l.arr[ 2 ];                d_arr[ 0 ] = l.d_arr[ 0 ];        d_arr[ 1 ] = l.d_arr[ 1 ];        d_arr[ 2 ] = l.d_arr[ 2 ];        _id = l._id;        fSplitter = l.fSplitter;        _true_id = l._true_id;                return  *this;    }    int  id() const    {        return  _id;    }    int  true_id() const  {        return  _true_id;    }    void  set_true_id( int  val ) {        _true_id = val;    }    void   _setID( int  id_num ) {        _id = id_num;    }    bool operator==(const line  &l) const    {        int  sc, slc;        sc = slc = 0;        //return ( ( a() == l.a() )  &&  ( b() == l.b() )        //      &&  ( c() == l.c() ) );        if  ( ( l._id > 0 )  &&  ( l._id == _id ) ) {            printf( "bogi!\n" );            return  true;        }                if  ( ( a() * l.c() != l.a() * c() )              ||  ( b() * l.c() != l.b() * c() ) )            return false;        sc  = Msign(c());        slc = Msign(l.c());        if ( sc == slc ) {            return (sc == 0) ?  ( a()*l.b() ==  b()*l.a() )            && (Msign(a() ) == Msign( l.a() ))                 && (Msign(b() ) == Msign( l.b() ))            : true;        } else {             return false;        }     }    bool isRealEqual(const line  &l) const    {        int  sc, slc;        double  res;        sc = slc = 0;        //return ( ( a() == l.a() )  &&  ( b() == l.b() )        //      &&  ( c() == l.c() ) );        if  ( ( l._id > 0 )  &&  ( l._id == _id ) )             return  true;                res = d_a() * l.d_c() - l.d_a() * d_c();        if  ( res < -DOUBLE_EPS )            return  false;        if  ( res > DOUBLE_EPS )            return  false;        res = ( d_b() * l.d_c() - l.d_b() * d_c() );        if  ( res < -DOUBLE_EPS )            return  false;        if  ( res > DOUBLE_EPS )            return  false;        return  *this == l;    }    bool  isSameUpToSign( const line  & l ) {        return  ( ( ( l.a() == a() )  &&  ( l.b() == b() )                      &&  ( l.c() == c() ) )                  ||  ( ( l.a() == -a() )  &&  ( l.b() == -b() )                        &&  ( l.c() == -c() ) ) );    }    bool  isSame( const  line  & l ) const {        if (  (a() * l.c() != l.a() * c())              ||(b() * l.c() != l.b() * c()) )            {                return false;            }        int sc  = Msign(c());        int slc = Msign(l.c());        if ( sc == slc ) {            return (sc == 0) ?  ( a()*l.b() ==  b()*l.a() )                : true;        } else {            if  ( ( sc == -slc )  &&  ( sc != 0 ) )                return  true;            else                return  false;        }    }     bool operator!=( const line  & l ) const    {        return !(*this == l);    }        void  setSplitter( bool  _fSplitter ) {        fSplitter = _fSplitter;    }    bool  isSplitter() const {        return  fSplitter;    }void   print( int  ind )  const{    //print_spaces( ind );    printf( "          " );	printf( "l:(a:%g, b:%g, c:%g) id: %d  rid: %d\n",                ( a() ), ( b() ),                ( c() ),                _id, _true_id                                  );}    real  x_at_y( const real  &y ) const    {                DASSERT( (a() != real(0)),           "Line::x_at_y(const FT &y) is undefined for horizontal line" );        return ( -b()*y - c() ) / a();    }    real  y_at_x( const real  &x ) const    {        if  ( b() == 0 ) {            print( 20 );            printf( "what?\n" );            assert( false );    	}        DASSERT( (b() != real(0)),                 "Line::yat_x(const FT &y) is undefined for vertical line");        return ( ( (-a()*x) - c() ) / b()) ;    }    double  d_y_at_x( const double  &x ) const    {        assert( ( d_b() != 0 ) );        return ( ( (-d_a()*x) - d_c() ) / d_b()) ;    }    line  perpendicular( const point  &p ) const    {        return line( -b() , a() , b() * p.x - a() * p.y  );    }        line  opposite() const    {                return line( -a(), -b(), -c() );    }    point  direction( void ) const    {        return  point( b(), -a(), 0 );    }    point  point_on(int i) const    {        if (i == 0){            return is_vertical() ? point( (-b()-c())/a(), 1, 0 )                : point( 1, -(a()+c())/b(), 0);        }        if (i == 1) {            return is_vertical() ? point( (-b()-c())/a() + b(),                                          1 - a(), 0 )                       : point( 1 + b(),                                -(a()+c())/b() - a(), 0 );        }        // we add i times the direction        if  ( is_vertical() ) {            return point( (-b()-c())/a() + i*b(),                          real(1) - i*a(), 0 );        }        return point( 1 + real(i)*b(),                      -(a()+c())/b() - i*a(), 0 );    }    point point_on() const    {        return is_vertical() ? point( (-b()-c())/a(), real(1), 0 )            : point( real(1), -(a()+c())/b(), 0 );    }    point projection(const point &p) const    {        if (is_horizontal()) {            return point(p.x, -c()/b(), 0 );        }                if (is_vertical()) {            return point( -c()/a(), p.y, 0 );        }        real ab = a()/b(), ba = b()/a(), ca = c()/a();        real y = ( -p.x + ab*p.y - ca ) / ( ba + ab );             return point(-ba * y - ca, y, 0);    }    #define  ON_ORIENTED_BOUNDARY   0    #define  ON_POSITIVE_SIDE  1    #define  ON_NEGATIVE_SIDE - 1    int     oriented_side( const point &p) const    {        real n = a()*p.x + b()*p.y + c();        return (n == real(0)) ? ON_ORIENTED_BOUNDARY            : ( (n > real(0)) ? ON_POSITIVE_SIDE                : ON_NEGATIVE_SIDE);    }    point  intersectx( const line  & l, bool  & f_intersect ) const     {        return  intersect_lines( (*this), l, f_intersect );    }    //int  get_point_signx( const point  & p ) const;    int  get_point_sign( const point  & p ) const;    //int  get_point_sign( const float_point  & p ) const;    //int  get_dpoint_sign( const dpoint  & p ) const;    real  get_point_val( const point  & p ) const    {        return ( a()*p.x + b()*p.y + c() );    }    bool has_on_boundary(const point &p) const    {        return (a()*p.x + b()*p.y + c()) == real(0);    }    inline bool has_on_positive_side( const point &p) const    {        return (a()*p.x + b()*p.y + c()) >  real(0);    }        inline bool has_on_negative_side( const point &p) const    {        return (a()*p.x + b()*p.y + c()) <  real(0);    }    inline bool isSteeper( const line  & l ) const    {        if  ( b() == 0 )             return  true;        if  ( l.b() == 0 )            return  false;        return  ( (-a()*l.b()) > (-l.a()*b()) );    }        bool is_horizontal() const    {                return a() == real(0) ;    }        bool is_vertical() const    {        return b() == real(0) ;    }    bool is_degenerate() const    {        return (a() == real(0)) && (b() == real(0)) ;    }    bool  isContain( const point  & pnt ) const     {        real  val =  (a() * pnt.x + b() * pnt.y + c());        return  ( real_eq( val, 0.0 ) );            }};inline  void  print_spaces( int   count ) {    for   ( int  ind = 0; ind < count; ind++ )        printf( " " );}inline  void   print( int  ind, const line  & l ) {    print_spaces( ind );    printf( "l:(a:%g, b:%g, c:%g)\n", ( l.a() ), ( l.b() ),             ( l.c() ) );}void  line_cache_init();#else   /* __LINE__H */#error  Header file line.h included twice#endif  /* __LINE__H *//*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* *      * line.h - End of File\*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -