util.C

Go to the documentation of this file.
00001 
00006 #ifdef HAVE_CONFIG_H
00007 #include <tumble-conf.h>
00008 #endif /* HAVE_CONFIG_H */
00009 
00010 #include <iostream>
00011 #include <cmath>
00012 #include <cassert>
00013 #include "util.h"
00014 #include "predicates.h"
00015 
00016 using namespace std;
00017 
00018 const double ALPHA[7]={0.33333333333333,
00019                        0.05971587178978,
00020                        0.47014206410511,
00021                        0.47014206410511,
00022                        0.79742698535310,
00023                        0.10128650732345,
00024                        0.10128650732345};
00025 
00026 const double BETA[7]={ 0.33333333333333,
00027                        0.47014206410511,
00028                        0.05971587178978,
00029                        0.47014206410511,
00030                        0.10128650732345,
00031                        0.79742698535310,
00032                        0.10128650732345};
00033 
00034 const double WEIGHT[7]={0.11250000000000,
00035                         0.06619707639425,
00036                         0.06619707639425,
00037                         0.06619707639425,
00038                         0.06296959027241,
00039                         0.06296959027241,
00040                         0.06296959027241};
00041 
00042 const double PI = 3.1415926535898;
00043 const double TWOPI = 2.0 * 3.1415926535898;
00044 const double HALFPI = 0.5 * 3.1415926535898;
00045 
00046 
00047 double Point2D::line_side_test(Point2D b, Point2D c) const
00048 {
00049     //Create a temp because i'm not sure if orient2d will mess up my values
00050     Point2D temp(*this);
00051     return orient2d(temp.coords, b.coords, c.coords);
00052 }
00053 
00054 
00055 bool Point2D::in_circle_test( Point2D a, Point2D b, Point2D c ) const
00056 {
00057     //Create a temp because i'm not sure if incircle will mess up my values
00058     Point2D temp(*this);
00059 
00060     // a->b->c must be in CCW order
00061     if(a.is_left_of(b, c))
00062         return incircle(a.coords, b.coords, c.coords, temp.coords) > 0.0;
00063     else
00064         return incircle(a.coords, c.coords, b.coords, temp.coords) > 0.0;
00065 }
00066 
00067 
00068 
00069 double Point2D::dist_from_line( const Point2D &a, const Point2D &b ) const {
00070     Point2D n( a[ 1 ] - b[ 1 ], b[ 0 ] - a[ 0 ] );
00071     Point2D diff;
00072     double norm = n.mag();
00073     diff = ( *this ) - a;
00074     if ( norm > 0 ) {
00075         n *= 1.0 / norm;
00076         return abs( n.dot( diff ) );
00077     } else {
00078         return diff.mag();
00079     }
00080 }
00081 
00082 
00083 ostream &operator<<( ostream &stream, const Point2D &p ) {
00084     stream << "<" << p.coords[ 0 ] << "," << p.coords[ 1 ] << ">";
00085     return stream;
00086 }
00087 
00088 
00089 ostream &operator<<( ostream &stream, const Vec3D &p )
00090 {
00091     stream << "<" << p.coords[ 0 ] << "," << p.coords[ 1 ] << "," << p.coords[2] <<">";
00092     return stream;
00093 }
00094 
00095 /* LinearData Constructors */
00096 LinearData::LinearData()
00097 {
00098     length = 0;
00099     fields = NULL;
00100 }
00101 
00102 LinearData::LinearData(int l)
00103 {
00104     //assert(l >= 0);
00105     if(l <=0){
00106         length=0;
00107         fields = NULL;
00108         return;
00109     }
00110 
00111     length = l;
00112     if(length > 0){
00113         fields = new double[length];
00114         for(int i=0; i<length; i++) fields[i] = 0.0;
00115     } else {
00116         fields = NULL;
00117     }
00118 }
00119 
00120 LinearData::LinearData( double* f, int l )
00121 {
00122     //assert( l >= 0);
00123     //assert( f != NULL);
00124     if( l <=0 || f==NULL){
00125         length = 0;
00126         fields = NULL;
00127     }
00128 
00129 
00130     length = l;
00131     if( length > 0){
00132         fields = new double[ length ];
00133         for ( int i = 0; i < length; i++ ) fields[ i ] = f[ i ];
00134     } else {
00135         fields = NULL;
00136     }
00137 }
00138 
00139 LinearData::LinearData( const vector<double> &data)
00140 {
00141     length = data.size();
00142     if( length > 0){
00143         fields = new double[ length ];
00144         for( int i = 0; i < length; i++ ) fields[ i ] = data[ i ];
00145     } else {
00146         fields = NULL;
00147     }
00148 }
00149 
00150 LinearData::LinearData( const LinearData &s )
00151 {
00152     assert(this != &s);
00153     if( this != &s ){
00154         length = s.length;
00155         if ( length == 0 ) {
00156             fields = NULL;
00157         } else {
00158             fields = new double[ length ];
00159             for ( int i = 0; i < length; i++ ) fields[ i ] = s.fields[ i ];
00160         }
00161     }
00162 }
00163 
00164 LinearData::~LinearData() {
00165     if( fields != NULL && length > 0 ) delete[] fields;
00166 }
00167 
00168 
00169 /* LinearData Modifiers */
00170 LinearData& LinearData::operator=( const LinearData &r )
00171 {
00172     assert(this != &r);
00173     if(this != &r) {
00174         if( fields != NULL && length > 0 ) delete[] fields;
00175         length = r.length;
00176         fields = new double[length];
00177         for ( int i = 0; i < length; i++ ) fields[ i ] = r.fields[ i ];
00178     }
00179     return *this;
00180 }
00181 
00182 int LinearData::update( const vector<double> &data )
00183 {
00184     if(data.size() != (unsigned)length){
00185         if ( fields != NULL ) delete[] fields;
00186         length = data.size();
00187         fields = new double[ length ];
00188     }
00189     for ( int i = 0; i < length; i++ ) fields[ i ] = data[ i ];
00190     return length;
00191 }
00192 
00193 int LinearData::update( double *f, int l ) {
00194     if(l != length){
00195         if ( fields != NULL ) delete[] fields;
00196         length = l;
00197         fields = new double[ length ];
00198     }
00199     for ( int i = 0; i < length; i++ )  fields[ i ] = f[ i ];
00200     return length;
00201 }
00202 
00203 void LinearData::resize( int len)
00204 {
00205     if(len == length ) return;
00206     if( fields != 0 ) delete[] fields;
00207     length = len;
00208     if(length <= 0){
00209         length = 0;
00210         fields = NULL;
00211     } else {
00212         fields = new double[length];
00213         zero();
00214     }
00215 }
00216 
00217 void LinearData::zero() {
00218     for(int i=0; i<length; i++) fields[i] = 0.0;
00219 }
00220 
00221 
00222 /* Linear Data in place operations */
00223 LinearData& LinearData::operator+= ( const LinearData &r ) {
00224     assert(r.length == length );
00225     for ( int i = 0; i < length; i++ )  fields[ i ] += r[ i ];
00226     return *this;
00227 }
00228 
00229 LinearData& LinearData::operator-= ( const LinearData &r ) {
00230     assert(r.length == length );
00231     for ( int i = 0; i < length; i++ ) fields[ i ] -= r[ i ];
00232     return *this;
00233 }
00234 
00235 LinearData& LinearData::operator*= ( double s ) {
00236     for ( int i = 0; i < length; i++ ) fields[ i ] *= s;
00237     return *this;
00238 }
00239 
00240 LinearData& LinearData::operator/= ( double s ) {
00241     for ( int i = 0; i < length; i++ ) fields[ i ] /= s;
00242     return *this;
00243 }
00244 
00245 
00246 /* Linear Data temporary generating operations */
00247 LinearData LinearData::operator+ ( const LinearData &r ) const {
00248     assert(r.length == length );
00249     LinearData temp(fields,length);
00250     for ( int i = 0; i < temp.length; i++ ) temp.fields[ i ] += r.fields[ i ];
00251     return temp;
00252 }
00253 
00254 LinearData LinearData::operator- ( const LinearData &r ) const {
00255     assert(r.length == length );
00256     LinearData temp(fields,length);
00257     for ( int i = 0; i < temp.length; i++ ) temp.fields[ i ] -= r.fields[ i ];
00258     return temp;
00259 }
00260 
00261 LinearData LinearData::operator* ( double s ) const {
00262     LinearData temp(fields,length);
00263     for ( int i = 0; i < temp.length; i++ ) temp.fields[ i ] *= s;
00264     return temp;
00265 }
00266 
00267 LinearData LinearData::operator/ ( double s ) const {
00268     LinearData temp(fields,length);
00269     for ( int i = 0; i < temp.length; i++ ) temp.fields[ i ] /= s;
00270     return temp;
00271 }
00272 
00273 /* Linear Data printing */
00274 ostream& operator<<( ostream& stream, const LinearData &d ) {
00275   if ( d.length == 0) {
00276         stream << "<nil>";
00277         return stream;
00278     }
00279 
00280   // TODO : This is a hack
00281   //assert(d.length == 3 || d.length == 5);
00282 
00283     stream << "<";
00284     for ( int i = 0;i < d.length - 1;i++ ) 
00285       {
00286     stream << d[ i ] << ",";
00287       }
00288     stream << d[ d.length - 1 ] << ">";
00289     return stream;
00290 }
00291 
00292 
00293 
00294 
00295 Matrix::Matrix( int r, int c ) {
00296     rows = r;
00297     cols = c;
00298     int i, j;
00299     m = new double*[ rows ];
00300     for ( i = 0;i < rows;i++ ) {
00301         m[ i ] = new double[ cols ];
00302     }
00303     for ( i = 0;i < rows;i++ ) {
00304         for ( j = 0;j < cols;j++ ) {
00305             m[ i ][ j ] = 0.0;
00306         }
00307     }
00308 }
00309 
00310 Matrix::Matrix( const Matrix& A ) {
00311     rows = A.rows;
00312     cols = A.cols;
00313 
00314     int i, j;
00315     m = new double*[ rows ];
00316     for ( i = 0;i < rows;i++ ) {
00317         m[ i ] = new double[ cols ];
00318     }
00319     for ( i = 0;i < rows;i++ ) {
00320         for ( j = 0;j < cols;j++ ) {
00321             m[ i ][ j ] = A.m[ i ][ j ];
00322         }
00323     }
00324 }
00325 
00326 
00327 Matrix::~Matrix() {
00328     for ( int i = 0;i < rows;i++ ) {
00329         delete[] m[ i ];
00330     }
00331     delete[] m;
00332 }
00333 
00334 Matrix* Matrix::transpose_times_self() {
00335 
00336     int i, j, k;
00337     double sum;
00338     Matrix *N = new Matrix( cols, cols );
00339 
00340     /* i=rows of n and rows of A^T */
00341     /* j=cols of n and cols of A*/
00342     /* k=cols of A^T and rows of A */
00343     for ( i = 0;i < cols;i++ ) {
00344         for ( j = 0;j < cols;j++ ) {
00345             sum = 0.0;
00346             for ( k = 0;k < rows;k++ ) {
00347                 sum += m[ k ][ i ] * m[ k ][ j ];
00348             }
00349             N->m[ i ][ j ] = sum;
00350         }
00351     }
00352     return N;
00353 }
00354 
00355 //this is only used for matricies smaller than 4x4 because the fast factoring
00356 //methods don't work on matricies that small and the inverse doesn't take
00357 //much time on a 4x4 matrix.
00358 Matrix* Matrix::inverse() {
00359     if ( rows != cols ) {
00360         cout << "error cannot take inverse of non square matrix!" << endl;
00361         return this;
00362     }
00363     Matrix *N = new Matrix( *this );
00364     int i, j, k;
00365     double q;
00366     double tol = 10e-16;
00367     for ( i = 0;i < cols;i++ ) {
00368         if ( fabs( N->m[ i ][ i ] ) <= tol ) {
00369             return N;
00370         }
00371         q = 1.0 / ( N->m[ i ][ i ] );
00372         N->m[ i ][ i ] = 1.0;
00373         for ( j = 0;j < cols;j++ ) {
00374             N->m[ i ][ j ] *= q;
00375         }
00376         for ( j = 0;j < cols;j++ ) {
00377             if ( i != j ) {
00378                 q = N->m[ j ][ i ];
00379                 N->m[ j ][ i ] = 0.0;
00380                 for ( k = 0;k < cols;k++ ) {
00381                     N->m[ j ][ k ] -= q * ( N->m[ i ][ k ] );
00382                 }
00383             }
00384         }
00385     }
00386     return N;
00387 }
00388 
00389 static double signa[2] = {1.0, -1.0};
00390 
00391 Matrix* Matrix::submat( int i, int j ) {
00392     int n, n1, p, p1;
00393     Matrix *S = new Matrix( rows - 1, cols - 1 );
00394 
00395     for ( n = n1 = 0; n < rows; n++ ) {
00396         if ( n == i ) continue;
00397         for ( p = p1 = 0; p < cols; p++ ) {
00398             if ( p == j ) continue;
00399             S->m[ n1 ][ p1 ] = m[ n ][ p ];
00400             p1++;
00401         }
00402         n1++;
00403     }
00404     return S;
00405 }
00406 
00407 
00408 double Matrix::matminor( int i, int j ) {
00409     Matrix * S;
00410     double result;
00411 
00412     S = submat( i, j );
00413     result = S->det();
00414     delete S;
00415     return result;
00416 }
00417 
00418 double Matrix::cofactor( int i, int j ) {
00419     double result;
00420     result = signa[ ( i + j ) % 2 ] * m[ i ][ j ] * matminor( i, j );
00421     return result;
00422 }
00423 
00424 int Matrix::lu_decompose(int *P )
00425 {
00426     int i, j, k, n;
00427     int maxi, tmp;
00428     double c, c1;
00429     int p;
00430 
00431     n = cols;
00432     for ( p = 0, i = 0; i < n; i++ ) P[ i ] = i;
00433 
00434     for ( k = 0; k < n; k++ ) {
00435         for ( i = k, maxi = k, c = 0.0; i < n; i++ ) {
00436             c1 = fabs( m[ P[ i ] ][ k ] );
00437             if ( c1 > c ) {
00438                 c = c1;
00439                 maxi = i;
00440             }
00441         }
00442 
00443         if ( k != maxi ) {
00444             p++;
00445             tmp = P[ k ];
00446             P[ k ] = P[ maxi ];
00447             P[ maxi ] = tmp;
00448         }
00449 
00450         /*
00451         *   suspected singular matrix
00452         */
00453         if ( m[ P[ k ] ][ k ] == 0.0 ) return ( -1 );
00454 
00455         for ( i = k + 1; i < n; i++ ) {
00456             /*
00457             * --- calculate m(i,j) ---
00458             */
00459             m[ P[ i ] ][ k ] = m[ P[ i ] ][ k ] / m[ P[ k ] ][ k ];
00460 
00461             /*
00462             * --- elimination ---
00463             */
00464             for ( j = k + 1; j < n; j++ ) {
00465                 m[ P[ i ] ][ j ] -= m[ P[ i ] ][ k ] * m[ P[ k ] ][ j ];
00466             }
00467         }
00468     }
00469     return  p;
00470 }
00471 
00472 double Matrix::det() {
00473     Matrix A(*this);
00474     int *P=new int[rows];
00475     int i, j;
00476     double result;
00477 
00478     /*
00479     * take a LUP-decomposition
00480     */
00481     i = A.lu_decompose( P );
00482     if( i == -1 ){
00483         result = 0.0;
00484     } else {
00485         /*
00486         * normal case: |A| = |L||U||P|
00487         * |L| = 1,
00488         * |U| = multiplication of the diagonal
00489         * |P| = +-1
00490         */
00491         result = 1.0;
00492         for ( j = 0; j < rows; j++ ) {
00493             result *= A.m[ P[ j ] ][ j ];
00494         }
00495         result *= signa[ i % 2 ];
00496     }
00497     delete[] P;
00498     return result;
00499 }
00500 
00501 /* v must be the same size as */
00502 double* Matrix::transpose_times_vector( double *v ) {
00503     int i, j;
00504     double *x = new double[ cols ];
00505     double sum;
00506 
00507     for ( i = 0;i < cols;i++ ) {
00508         sum = 0.0;
00509         for ( j = 0;j < rows;j++ ) {
00510             sum += m[ j ][ i ] * v[ j ];
00511         }
00512         x[ i ] = sum;
00513     }
00514     return x;
00515 }
00516 
00517 double* Matrix::times_vector( double *v ) {
00518     int i, j;
00519     double *x = new double[ rows ];
00520     double sum;
00521     for ( i = 0;i < rows;i++ ) {
00522         sum = 0.0;
00523         for ( j = 0;j < cols;j++ ) {
00524             sum += m[ i ][ j ] * v[ j ];
00525         }
00526         x[ i ] = sum;
00527     }
00528     return x;
00529 }
00530 
00531 
00532 Matrix5::Matrix5( int n ) {
00533     size = n;
00534     d1 = new double[ n - 2 ];
00535     d2 = new double[ n - 1 ];
00536     d3 = new double[ n ];
00537     d4 = new double[ n - 1 ];
00538     d5 = new double[ n - 2 ];
00539     factored = false;
00540 }
00541 
00542 Matrix5::Matrix5( const Matrix5& A ) {
00543     size = A.size;
00544     d1 = new double[ size - 2 ];
00545     d2 = new double[ size - 1 ];
00546     d3 = new double[ size ];
00547     d4 = new double[ size - 1 ];
00548     d5 = new double[ size - 2 ];
00549     factored = A.factored;
00550     for ( int i = 0;i < size - 2;i++ ) {
00551         d1[ i ] = A.d1[ i ];
00552         d2[ i ] = A.d2[ i ];
00553         d3[ i ] = A.d3[ i ];
00554         d4[ i ] = A.d4[ i ];
00555         d5[ i ] = A.d5[ i ];
00556     }
00557     d2[ size - 2 ] = A.d2[ size - 2 ];
00558     d3[ size - 2 ] = A.d3[ size - 2 ];
00559     d4[ size - 2 ] = A.d4[ size - 2 ];
00560     d3[ size - 1 ] = A.d3[ size - 1 ];
00561     cout << "Matrix5: copy constructor called!" << endl;
00562 }
00563 
00564 Matrix5::~Matrix5() {
00565     delete[] d1;
00566     delete[] d2;
00567     delete[] d3;
00568     delete[] d4;
00569     delete[] d5;
00570 }
00571 
00572 Matrix5::Matrix5( const Matrix& M ) {
00573     if ( M.rows != M.cols ) {
00574         cout << "Matrix5::Matrix5(Matrix): Error recieved non square matrix, exiting" << endl;
00575         exit( 1 );
00576     }
00577     int i;
00578     size = M.rows;
00579     factored = false;
00580     d1 = new double[ size - 2 ];
00581     d2 = new double[ size - 1 ];
00582     d3 = new double[ size ];
00583     d4 = new double[ size - 1 ];
00584     d5 = new double[ size - 2 ];
00585 
00586 
00587     /* Row = 0 */
00588     d3[ 0 ] = M.m[ 0 ][ 0 ];
00589     d2[ 0 ] = M.m[ 0 ][ 1 ];
00590     d1[ 0 ] = M.m[ 0 ][ 2 ];
00591 
00592     /* Row = 1 */
00593     d4[ 0 ] = M.m[ 1 ][ 0 ];
00594     d3[ 1 ] = M.m[ 1 ][ 1 ];
00595     d2[ 1 ] = M.m[ 1 ][ 2 ];
00596     d1[ 1 ] = M.m[ 1 ][ 3 ];
00597 
00598     /* Row = 2 .. size-3 */
00599     for ( i = 2;i < size - 2;i++ ) {
00600         d5[ i - 2 ] = M.m[ i ][ i - 2 ];
00601         d4[ i - 1 ] = M.m[ i ][ i - 1 ];
00602         d3[ i ] = M.m[ i ][ i ];
00603         d2[ i ] = M.m[ i ][ i + 1 ];
00604         d1[ i ] = M.m[ i ][ i + 2 ];
00605     }
00606 
00607     /* Row = size-2 */
00608     d5[ size - 4 ] = M.m[ size - 2 ][ size - 4 ];
00609     d4[ size - 3 ] = M.m[ size - 2 ][ size - 3 ];
00610     d3[ size - 2 ] = M.m[ size - 2 ][ size - 2 ];
00611     d2[ size - 2 ] = M.m[ size - 2 ][ size - 1 ];
00612 
00613     /* Row = size-1 */
00614     d5[ size - 3 ] = M.m[ size - 1 ][ size - 3 ];
00615     d4[ size - 2 ] = M.m[ size - 1 ][ size - 2 ];
00616     d3[ size - 1 ] = M.m[ size - 1 ][ size - 1 ];
00617 }
00618 
00619 void Matrix5::factor() {
00620     int i;
00621     factored = true;
00622     /* j=1 */
00623     d4[ 0 ] = d4[ 0 ] / d3[ 0 ];
00624     d5[ 0 ] = d5[ 0 ] / d3[ 0 ];
00625 
00626     /* j=2 */
00627     d3[ 1 ] = d3[ 1 ] - d4[ 0 ] * d2[ 0 ];
00628     d4[ 1 ] = ( d4[ 1 ] - d5[ 0 ] * d2[ 0 ] ) / d3[ 1 ];
00629     d5[ 1 ] = d5[ 1 ] / d3[ 1 ];
00630 
00631     /* j=3..size-2 */
00632     for ( i = 2;i < ( size - 2 );i++ ) {
00633         d2[ i - 1 ] = d2[ i - 1 ] - d4[ i - 2 ] * d1[ i - 2 ];
00634         d3[ i ] = d3[ i ] - d5[ i - 2 ] * d1[ i - 2 ] - d4[ i - 1 ] * d2[ i - 1 ];
00635         d4[ i ] = ( d4[ i ] - d5[ i - 1 ] * d2[ i - 1 ] ) / d3[ i ];
00636         d5[ i ] = d5[ i ] / d3[ i ];
00637     }
00638 
00639     /* j=size-1 */
00640     d2[ size - 3 ] = d2[ size - 3 ] - d4[ size - 4 ] * d1[ size - 4 ];
00641     d3[ size - 2 ] = d3[ size - 2 ] - d5[ size - 4 ] * d1[ size - 4 ] - d4[ size - 3 ] * d2[ size - 3 ];
00642     d4[ size - 2 ] = ( d4[ size - 2 ] - d5[ size - 3 ] * d2[ size - 3 ] ) / d3[ size - 2 ];
00643 
00644     /* j=size */
00645     d2[ size - 2 ] = d2[ size - 2 ] - d4[ size - 3 ] * d1[ size - 3 ];
00646     d3[ size - 1 ] = d3[ size - 1 ] - d5[ size - 3 ] * d1[ size - 3 ] - d4[ size - 2 ] * d2[ size - 2 ];
00647 }
00648 
00649 /*b must be same size ast Matrix5.
00650 This function mutates b and returns it*/
00651 
00652 double* Matrix5::LUsolve( double *b ) {
00653     double * y = new double[ size ];
00654     int i;
00655 
00656     if ( !factored ) {
00657         factor();
00658     }
00659 
00660     y[ 0 ] = b[ 0 ];
00661     y[ 1 ] = b[ 1 ] - y[ 0 ] * d4[ 0 ];
00662     for ( i = 2;i < size;i++ ) {
00663         y[ i ] = b[ i ] - y[ i - 2 ] * d5[ i - 2 ] - y[ i - 1 ] * d4[ i - 1 ];
00664     }
00665 
00666 
00667     b[ size - 1 ] = y[ size - 1 ] / d3[ size - 1 ];
00668     b[ size - 2 ] = ( y[ size - 2 ] - d2[ size - 2 ] * b[ size - 1 ] ) / d3[ size - 2 ];
00669     for ( i = size - 3;i >= 0;i-- ) {
00670         b[ i ] = ( y[ i ] - d2[ i ] * b[ i + 1 ] - d1[ i ] * b[ i + 2 ] ) / d3[ i ];
00671     }
00672 
00673     delete[] y;
00674     return b;
00675 }
00676 
00677 /*
00678 ostream& operator<<( ostream& stream, Matrix5 M ) {
00679     stream << "Matrix5: [not implimented yet]";
00680     return stream;
00681 }
00682 */
00683 
00684 ostream& operator<<( ostream& stream, Matrix M ) {
00685     int i, j;
00686     stream << "Matrix:\n";
00687     for ( i = 0;i < M.rows;i++ ) {
00688         stream << "ROW" << i << ": [[";
00689         for ( j = 0;j < M.cols;j++ ) {
00690             stream << M.m[ i ][ j ] << ", ";
00691         }
00692         stream << "]]\n";
00693     }
00694     return stream;
00695 }
00696 
00697 /* filename extensions handeler */
00698 int add_filename_extension(char *filename, const char *ext, char *buf, int buf_len)
00699 {
00700     if(!filename || !ext || !buf) return -1;
00701     int ext_len = strlen(ext);
00702     if(buf_len < 2+ext_len) return -1;
00703     if(strlen(filename) + ext_len + 1 > (unsigned) buf_len ) return -1;
00704     bzero(buf, buf_len);
00705 
00706     char *e = strrchr(filename,'.');
00707 
00708     /* if no extensions at all, then add it */
00709     if(!e){
00710         snprintf(buf,buf_len,"%s.%s",filename, ext);
00711         return 0;
00712     }
00713     e++;
00714 
00715     /* check if extensions is correct, if not add it */
00716     if(strncmp(e,ext,ext_len)){
00717         snprintf(buf,buf_len,"%s.%s",filename, ext);
00718     } else {
00719         /* otherwise OK */
00720         strncpy(buf, filename, buf_len);
00721     }
00722     return 0;
00723 }
00724 
00725 bool poly_convex(Point2D poly[], int size)
00726 {
00727     for(int i=0; i<size; i++){
00728         if(i < size-2){
00729             if( !poly[i+2].is_left_of(poly[i], poly[i+1]) ) return false;
00730         }else if(i == size-2){
00731             if(   !poly[0].is_left_of(poly[i], poly[i+1]) ) return false;
00732         }else{
00733             if(   !poly[1].is_left_of(poly[i], poly[0])   ) return false;
00734         }
00735     }
00736     return true;
00737 }
00738 
00739 bool point_in_poly_kernel(Point2D poly[], int size, const Point2D &point)
00740 {
00741     for(int i=0; i<size; i++){
00742         if(i < size-1){
00743             if( !point.is_left_of(poly[i], poly[i+1]) ) return false;
00744         }else{
00745             if( !point.is_left_of(poly[i], poly[0])   ) return false;
00746         }
00747     }
00748     return true;
00749 }
00750 
00751 
00752 ostream& operator << (ostream& os, const ControlPoint& cp)
00753 {
00754   return os << "[CP->" << (void*)(&*cp) << " " << *cp << "]";
00755 }
00756 
00757 ostream& operator << (ostream& os, const DataPoint& dp)
00758 {
00759   return os << "[DP->" << (void*)(&*dp) << " " << *dp << "]";
00760 }

Generated on Mon May 24 09:53:31 2010 for TUMBLE by  doxygen 1.5.2