#include "bbox.h" #include #include #include // enable invariant checking #define SEGMENT_TREE_CHECK_INVARIANTS 1 #include #include "Timer.h" #include #include #include #include #include #include #include using namespace std; typedef Bbox_3< int > Box; typedef Bbox_3_Adapter< Box > BoxAdapter; typedef Default_Box_Traits< BoxAdapter > Traits; typedef vector< Box > BoxContainer; typedef pair< Box, Box > BoxPair; typedef vector< BoxPair > ResultContainer; static void readBoxesFromFile( FILE *infile, BoxContainer& boxes ) { int numBoxes, numDim; int numMatched; int boxNum, dim; fscanf(infile, "%d %d\n", &numBoxes, &numDim); vector< int > lo( numDim ), hi( numDim ); /* Read boxes */ for(boxNum = 0; boxNum < numBoxes; boxNum++) { for(dim = 0; dim < numDim; dim++) fscanf( infile, "[%d, %d) ", &lo[dim], &hi[dim] ); boxes.push_back( Box( lo[0], lo[1], lo[2], hi[0], hi[1], hi[2] ) ); fscanf(infile, "\n"); } } static void assertIntersection( const Box& a, const Box& b ) { for( unsigned int dim = 0; dim < 3; ++dim ) { if( Traits::does_intersect( a, b, dim ) == false ) { cout << "does not intersect!" << endl; //cout << a << endl << b << endl; exit(-1); } } } template< class Storage > struct StorageCallback { unsigned int counter; Storage& storage; StorageCallback( Storage& storage ) : counter( 0 ), storage( storage ) {} void operator()( const Box& a, const Box& b ) { assertIntersection( a, b ); ++counter; storage.push_back( make_pair( a, b ) ); } }; bool operator==( const Box& a, const Box& b ) { for( unsigned int dim = 0; dim < 3; ++dim ) if( Traits::get_lo( a, dim ) != Traits::get_lo( b, dim ) || Traits::get_hi( a, dim ) != Traits::get_hi( b, dim ) ) return false; return true; } bool operator==( const BoxPair& a, const BoxPair& b ) { return( a.first == b.first && a.second == b.second || a.first == b.second && a.second == b.first ); } template< class Storage > unsigned int countMissingItems( Storage& a, Storage& b ) { unsigned int missing = 0; for( typename Storage::iterator it = a.begin(); it != a.end(); ++it ) { if( find( b.begin(), b.end(), *it ) == b.end() ) { ++missing; //cout << it->first << it->second << endl; } } return missing; } template< class Storage > unsigned int countDuplicates( Storage& storage ) { unsigned int counter = 0; typedef typename Storage::iterator IT; for( IT it = storage.begin(); it != storage.end(); ++it ) for( IT it2 = it; it2 != storage.end(); ++it2 ) if( it != it2 && *it == *it2 ) { //cout << it->first.num() << " <-> " // << it->second.num() << endl; ++counter; } return counter; } static void test( const char* filename1, const char* filename2 ) { BoxContainer boxes1, boxes2; ResultContainer result_all_pairs, result_tree; FILE *infile1, *infile2; infile1 = fopen( filename1, "r"); infile2 = fopen( filename2, "r"); readBoxesFromFile( infile1, boxes1 ); readBoxesFromFile( infile2, boxes2 ); cout << endl; StorageCallback< ResultContainer > callback1( result_all_pairs ), callback2( result_tree ); cout << "all pairs ...... " << flush; Timer timer; timer.start(); all_pairs( boxes1.begin(), boxes1.end(), boxes2.begin(), boxes2.end(), callback1, Traits(), 2 ); timer.stop(); cout << "got " << callback1.counter << " intersections in " << timer.t << " seconds." << endl; cout << "segment tree ... " << flush; timer.reset(); timer.start(); unsigned int n = boxes1.size(); Traits::cutoff = n < 2000 ? 6 : n / 100; segment_tree( boxes1.begin(), boxes1.end(), boxes2.begin(), boxes2.end(), callback2, Traits(), 2 ); timer.stop(); cout << "got " << callback2.counter << " intersections in " << timer.t << " seconds." <