00001
00006 #ifndef UTIL_H
00007 #define UTIL_H
00008
00009 #include <iostream>
00010 #include <list>
00011 #include <vector>
00012 #include <cassert>
00013 #include <cmath>
00014 #include <string>
00015 #include <string.h>
00016
00017 #include "persistance-noop.h"
00018
00019 #define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
00020
00021
00022 extern const double ALPHA[7];
00023 extern const double BETA[7];
00024 extern const double WEIGHT[7];
00025
00026 typedef double Radians;
00027 extern const double PI;
00028 extern const double TWOPI;
00029 extern const double HALFPI;
00030
00031 namespace Tumble {
00032 inline bool is_zero(double a) {
00033 return fabs(a) < 1e-15;
00034 }
00035 inline bool are_equal(double a, double b) {
00036 return is_zero(a - b);
00037 }
00038 };
00039
00040
00046 class Point2D {
00047 public:
00048 double coords[ 2 ];
00050
00051 Point2D()
00052 {
00053 coords[ 0 ] = 0.0;
00054 coords[ 1 ] = 0.0;
00055 }
00056
00057 Point2D( double x, double y )
00058 {
00059 coords[ 0 ] = x;
00060 coords[ 1 ] = y;
00061 }
00062
00063 Point2D( const Point2D &o)
00064 {
00065 coords[ 0 ] = o.coords[ 0 ];
00066 coords[ 1 ] = o.coords[ 1 ];
00067 }
00068
00069
00070 Point2D& assign( double x, double y )
00071 {
00072 coords[ 0 ] = x;
00073 coords[ 1 ] = y;
00074 return *this;
00075 }
00076
00077 double operator[] ( int i ) const { return coords[ i ]; }
00078 double x() const { return coords[ 0 ]; }
00079 double y() const { return coords[ 1 ]; }
00080
00081 bool operator<( const Point2D &o ) const
00082 {
00083 return ( magsq() < o.magsq() );
00084 }
00085
00086 bool operator<=( const Point2D &o ) const
00087 {
00088 return ( magsq() <= o.magsq() );
00089 }
00090
00091 bool operator>( const Point2D &o ) const
00092 {
00093 return ( magsq() > o.magsq() );
00094 }
00095
00096 bool operator>=( const Point2D &o ) const
00097 {
00098 return ( magsq() >= o.magsq() );
00099 }
00100
00102 Point2D& operator= ( const Point2D &o )
00103 {
00104 coords[ 0 ] = o.coords[ 0 ];
00105 coords[ 1 ] = o.coords[ 1 ];
00106 return *this;
00107 }
00108
00109
00110 Point2D& operator+=( const Point2D &o )
00111 {
00112 coords[ 0 ] += o.coords[ 0 ];
00113 coords[ 1 ] += o.coords[ 1 ];
00114 return *this;
00115 }
00116
00117 Point2D& operator-=( const Point2D &o )
00118 {
00119 coords[ 0 ] -= o.coords[ 0 ];
00120 coords[ 1 ] -= o.coords[ 1 ];
00121 return *this;
00122 }
00123
00124 Point2D& operator*=( double s )
00125 {
00126 coords[ 0 ] *= s;
00127 coords[ 1 ] *= s;
00128 return *this;
00129 }
00130
00131 Point2D& operator/=( double s )
00132 {
00133 coords[ 0 ] /= s;
00134 coords[ 1 ] /= s;
00135 return *this;
00136 }
00137
00138
00139 Point2D operator+ ( const Point2D &o ) const
00140 {
00141 return Point2D(coords[ 0 ] + o.coords[ 0 ], coords[ 1 ] + o.coords[ 1 ]);
00142 }
00143
00144 Point2D operator- ( const Point2D &o ) const
00145 {
00146 return Point2D(coords[ 0 ] - o.coords[ 0 ], coords[ 1 ] - o.coords[ 1 ]);
00147 }
00148
00149 Point2D operator* ( double s ) const
00150 {
00151 return Point2D(coords[ 0 ] *s, coords[ 1 ] * s);
00152 }
00153
00154 Point2D operator/ ( double s ) const
00155 {
00156 return Point2D(coords[ 0 ] / s, coords[ 1 ] / s);
00157 }
00158
00159
00160 double dot( const Point2D &o ) const
00161 {
00162 return coords[ 0 ] * o.coords[ 0 ] + coords[ 1 ] * o.coords[ 1 ];
00163 }
00164
00165 double magsq() const
00166 {
00167 return coords[ 0 ] * coords[ 0 ] + coords[ 1 ] * coords[ 1 ];
00168 }
00169
00170 double mag() const
00171 {
00172 return sqrt( coords[ 0 ] * coords[ 0 ] + coords[ 1 ] * coords[ 1 ] );
00173 }
00174
00176 double cross( const Point2D &a ) const
00177 {
00178 return coords[ 0 ] * a.coords[ 1 ] - coords[ 1 ] * a.coords[ 0 ];
00179 }
00180
00181
00182
00189 bool machine_equal(const Point2D& other) const {
00190 return x() == other.x() && y() == other.y();
00191 }
00192
00201 bool is_left_of( const Point2D &a, const Point2D &b) const { return line_side_test(a,b)>0.0; }
00202
00211 bool is_right_of( const Point2D &a, const Point2D &b) const { return line_side_test(a,b)<0.0; }
00212
00221 double line_side_test( Point2D a, Point2D b) const;
00222
00232 bool in_circle_test( Point2D a, Point2D b, Point2D c) const;
00233
00235 double dist_from_line(const Point2D &a, const Point2D &b ) const;
00236
00246 double angle(const Point2D &a, const Point2D &c) const
00247 {
00248 Point2D ab = a - *this;
00249 Point2D cb = c - *this;
00250 return (ab.dot(cb) / (ab.mag() * cb.mag()));
00251 }
00252
00253
00254 void print(){ std::cout<<*this;}
00255 friend std::ostream &operator<<( std::ostream&, const Point2D &p );
00256 };
00257
00259 class LinearData {
00260 public:
00261 double *fields;
00262 int length;
00264
00265 LinearData();
00266 LinearData(int len);
00267 LinearData( double *data, int len);
00268 LinearData( const std::vector<double> &data);
00269 LinearData( const LinearData &ld);
00270 ~LinearData();
00272
00273 int update( const std::vector<double> &data );
00274 int update( double *data, int len );
00275 void resize( int len);
00277 void zero();
00280 void set(double d, int i) {
00281 assert(i>=0 && i < length);
00282 fields[i] = d;
00283 }
00284
00286 double operator[]( int i ) const {
00287 assert(i>=0 && i<length);
00288 return fields[ i ];
00289 }
00290
00292 double get(int i) const {
00293 assert(i>=0 && i < length);
00294 return fields[i];
00295 }
00296
00298 LinearData& operator= ( const LinearData& d);
00299
00300
00301 LinearData& operator+= ( const LinearData& d);
00302 LinearData& operator-= ( const LinearData& d);
00303 LinearData& operator*= ( double s);
00304 LinearData& operator/= ( double s);
00305
00306
00307 LinearData operator+ ( const LinearData& d) const;
00308 LinearData operator- ( const LinearData& d) const;
00309 LinearData operator* ( double s) const;
00310 LinearData operator/ ( double s) const;
00311
00312
00313 void print(){ std::cout<<*this;}
00314 friend std::ostream &operator<<( std::ostream&, const LinearData& );
00315 };
00316
00323 typedef PersistantList<Point2D>::iterator ControlPoint;
00324 std::ostream& operator << (std::ostream& os, const ControlPoint& cp);
00325
00332 typedef PersistantList<LinearData>::iterator DataPoint;
00333 std::ostream& operator << (std::ostream& os, const DataPoint& cp);
00334
00336 class Vec3D {
00337 public:
00338 double coords[ 3 ];
00340
00341 Vec3D()
00342 {
00343 coords[0] = 0;
00344 coords[1] = 0;
00345 coords[2] = 0;
00346 }
00347
00348 Vec3D( double x, double y, double z )
00349 {
00350 coords[ 0 ] = x;
00351 coords[ 1 ] = y;
00352 coords[ 2 ] = z;
00353 }
00354
00356 Vec3D( const Point2D &p, double z=0.0)
00357 {
00358 coords[ 0 ] = p.x();
00359 coords[ 1 ] = p.y();
00360 coords[ 2 ] = z;
00361 }
00362
00363 Vec3D( const Vec3D &o)
00364 {
00365 coords[0] = o.coords[0];
00366 coords[1] = o.coords[1];
00367 coords[2] = o.coords[2];
00368 }
00369
00370
00371 Vec3D& assign( double x, double y, double z )
00372 {
00373 coords[ 0 ] = x;
00374 coords[ 1 ] = y;
00375 coords[ 2 ] = z;
00376 return *this;
00377 }
00378
00380 Vec3D& assign( const Point2D &p, double z )
00381 {
00382 coords[ 0 ] = p.x();
00383 coords[ 1 ] = p.y();
00384 coords[ 2 ] = z;
00385 return *this;
00386 }
00387
00388 double operator[] ( int i ) const { return coords[ i ]; }
00389 double x() const { return coords[ 0 ]; }
00390 double y() const { return coords[ 1 ]; }
00391 double z() const { return coords[ 2 ]; }
00392
00393 bool operator<( const Vec3D &o ) const
00394 {
00395 return ( magsq() < o.magsq() );
00396 }
00397
00398 bool operator<=( const Vec3D &o ) const
00399 {
00400 return ( magsq() <= o.magsq() );
00401 }
00402
00403 bool operator>( const Vec3D &o ) const
00404 {
00405 return ( magsq() > o.magsq() );
00406 }
00407
00408 bool operator>=( const Vec3D &o ) const
00409 {
00410 return ( magsq() >= o.magsq() );
00411 }
00412
00413
00414 Vec3D& operator= ( const Vec3D &o )
00415 {
00416 coords [0] = o.coords[0];
00417 coords [1] = o.coords[1];
00418 coords [2] = o.coords[2];
00419 return *this;
00420 }
00421
00422
00423 Vec3D& operator+=( const Vec3D &o )
00424 {
00425 coords[ 0 ] += o.coords[ 0 ];
00426 coords[ 1 ] += o.coords[ 1 ];
00427 coords[ 2 ] += o.coords[ 2 ];
00428 return *this;
00429 }
00430
00431 Vec3D& operator-=( const Vec3D &o )
00432 {
00433 coords[ 0 ] -= o.coords[ 0 ];
00434 coords[ 1 ] -= o.coords[ 1 ];
00435 coords[ 2 ] -= o.coords[ 2 ];
00436 return *this;
00437 }
00438
00439 Vec3D& operator*=( double s )
00440 {
00441 coords[ 0 ] *= s;
00442 coords[ 1 ] *= s;
00443 coords[ 2 ] *= s;
00444 return *this;
00445 }
00446
00447 Vec3D& operator/=( double s )
00448 {
00449 coords[ 0 ] /= s;
00450 coords[ 1 ] /= s;
00451 coords[ 2 ] /= s;
00452 return *this;
00453 }
00454
00455
00456 Vec3D operator+ ( const Vec3D &o ) const
00457 {
00458 return Vec3D(coords[ 0 ] + o.coords[ 0 ], coords[ 1 ] + o.coords[ 1 ], coords[ 2 ] + o.coords[ 2 ]);
00459 }
00460
00461 Vec3D operator- ( const Vec3D &o ) const
00462 {
00463 return Vec3D(coords[ 0 ] - o.coords[ 0 ], coords[ 1 ] - o.coords[ 1 ], coords[ 2 ] - o.coords[ 2 ]);
00464 }
00465
00466 Vec3D operator* ( double s ) const
00467 {
00468 return Vec3D(coords[ 0 ] *s, coords[ 1 ] * s, coords[ 2 ] * s);
00469 }
00470
00471 Vec3D operator/ ( double s ) const
00472 {
00473 return Vec3D(coords[ 0 ] / s, coords[ 1 ] / s, coords[ 2 ] / s);
00474 }
00475
00476
00477 double dot( const Vec3D &o ) const
00478 {
00479 return coords[ 0 ] * o.coords[ 0 ] + coords[ 1 ] * o.coords[ 1 ] + coords[ 2 ] * o.coords[ 2 ];
00480 }
00481
00482
00483 double operator*( const Vec3D &o ) const
00484 {
00485 return coords[ 0 ] * o.coords[ 0 ] + coords[ 1 ] * o.coords[ 1 ] + coords[ 2 ] * o.coords[ 2 ];
00486 }
00487
00488 double magsq() const
00489 {
00490 return coords[ 0 ] * coords[ 0 ] + coords[ 1 ] * coords[ 1 ] + coords[ 2 ] * coords[ 2 ];
00491 }
00492
00493 double mag() const
00494 {
00495 return sqrt( coords[ 0 ] * coords[ 0 ] + coords[ 1 ] * coords[ 1 ] + coords[ 2 ] * coords[ 2 ]);
00496 }
00497
00498 double norm() const { return mag(); }
00499
00501 Vec3D cross( const Vec3D &o ) const
00502 {
00503 return Vec3D( coords[1]*o.coords[2]-coords[2]*o.coords[1],
00504 coords[0]*o.coords[2]-coords[2]*o.coords[0],
00505 coords[0]*o.coords[1]-coords[1]*o.coords[0]);
00506 }
00507
00509 double angle(const Vec3D &o)
00510 {
00511 double n = norm();
00512 double on = o.norm();
00513 if ((0.0==n) || (0.0==on)) return PI;
00514 double costheta = dot(o) / (n*on);
00515 if (costheta <= -1.0) return PI;
00516 if (costheta >= 1.0 ) return 0;
00517 return acos(costheta);
00518 }
00519
00520
00521 void print(){ std::cout<<*this;}
00522 friend std::ostream &operator<<( std::ostream&, const Vec3D &p );
00523 };
00524
00526 class Matrix {
00527 private:
00528
00529 Matrix* submat( int i, int j );
00530
00531 double matminor( int i, int j );
00532 double cofactor( int i, int j );
00533 int lu_decompose(int *P );
00534 public:
00535 double** m;
00536 int rows, cols;
00537
00538
00539 Matrix( int, int );
00540 Matrix( const Matrix& );
00541 ~Matrix();
00542
00543
00544 double operator() (const int i,const int j) const {
00545 return m[i][j];
00546 }
00547 void set(int i, int j, double val){
00548 if(i>=0 && j>=0 && i<rows && j<cols) m[i][j]=val;
00549 }
00550
00551
00552 double det();
00553
00554
00555
00556
00557
00558
00559 Matrix* transpose_times_self();
00560 Matrix* inverse();
00561 double* transpose_times_vector( double* );
00562 double* times_vector( double* );
00563
00564
00565 void print(){ std::cout<<*this<<std::endl; }
00566 friend std::ostream& operator<<( std::ostream&, Matrix );
00567 };
00568
00569
00571 class Matrix5 {
00572 private:
00573 void factor();
00574 public:
00575 int size;
00576 double *d1, *d2, *d3, *d4, *d5;
00577 bool factored;
00578 Matrix5( const Matrix& );
00579 Matrix5( const Matrix5& );
00580 Matrix5( int );
00581 ~Matrix5();
00582 double* LUsolve( double* );
00583
00584 };
00585
00586
00587
00588
00590 template <class T>
00591 class PQueueEntry {
00592 public:
00593 T i;
00594 double p;
00595 PQueueEntry *prev, *next;
00596 PQueueEntry( const T &_i, double _p ) : i( _i ), p( _p ), prev( NULL ), next( NULL ) {}
00597 };
00598
00599
00607 template <class T>
00608 class PQueue {
00609 public:
00610 int sz;
00611 PQueueEntry<T> *front, *back;
00612
00613 PQueue() {
00614 sz=0;
00615 front = NULL;
00616 back = NULL;
00617 }
00618 int size() {
00619 return sz;
00620 }
00621 bool pop( T &val );
00622 void push( const T &val, double p );
00623 bool remove( const T &val );
00624 void print(){
00625 std::cout<<"PQueue: [";
00626 PQueueEntry<T> *temp=front;
00627 while(temp && temp->next!=NULL){
00628 std::cout<<"{"<<temp->i<<", "<<temp->p<<"}, ";
00629 temp=temp->next;
00630 }
00631 if(temp!=NULL) std::cout<<"{"<<temp->i<<", "<<temp->p<<"}";
00632 std::cout<<"]"<<std::endl;
00633 }
00634 };
00635
00636 template<class T>
00637 bool PQueue<T>::pop( T &val ) {
00638 PQueueEntry<T> * e = front;
00639 if ( e == NULL ) return false;
00640 val = e->i;
00641 front = e->next;
00642 if ( front == NULL ) back = NULL;
00643 else front->prev = NULL;
00644 sz--;
00645 delete e;
00646 return true;
00647 }
00648
00649 template<class T>
00650 void PQueue<T>::push( const T &val, double p ) {
00651 PQueueEntry<T> * n = new PQueueEntry<T>( val, p );
00652 PQueueEntry<T> * temp;
00653 sz++;
00654 if ( front == NULL ) {
00655 front = n;
00656 back = n;
00657 } else if ( p <= front->p ) {
00658 n->next = front;
00659 front->prev = n;
00660 front = n;
00661 } else {
00662 temp = front;
00663 while ( temp && p > temp->p ) {temp = temp->next;}
00664 n->next = temp;
00665 if ( temp ){
00666 assert(temp != front);
00667 n->prev = temp->prev;
00668 temp->prev = n;
00669 }
00670 else{
00671 assert(back != NULL);
00672 n->prev = back;
00673 back = n;
00674 }
00675 assert(n->prev != NULL);
00676 n->prev->next = n;
00677 }
00678 }
00679
00680 template<class T>
00681 bool PQueue<T>::remove( const T &val ) {
00682 PQueueEntry<T> * temp=front;
00683 while ( temp && temp->i != val ) temp = temp->next;
00684 if ( temp == NULL ) return false;
00685 sz--;
00686 if ( front == temp ) {
00687 front = temp->next;
00688 if ( front != NULL ) front->prev = NULL;
00689 } else {
00690 temp->prev->next = temp->next;
00691 }
00692
00693 if ( back == temp ) {
00694 back = temp->prev;
00695 if ( back != NULL ) back->next = NULL;
00696 } else {
00697 temp->next->prev = temp->prev;
00698 }
00699
00700 delete temp;
00701 return true;
00702 }
00703
00705 int add_filename_extension(char *filename, const char *ext, char *buf, int buf_len);
00706
00717 bool poly_convex(Point2D poly[], int size);
00718
00731 bool point_in_poly_kernel(Point2D poly[], int size, const Point2D &point);
00732
00733 #endif