bbox developed to package Bounding_box_d

This commit is contained in:
Peter Hachenberger 2006-02-16 14:37:03 +00:00
parent 5c20f9ff39
commit 0fb5698b5d
12 changed files with 0 additions and 2903 deletions

View File

@ -1 +0,0 @@
Andreas Meyer <ameyer@mpi-sb.mpg.de>

View File

@ -1,32 +0,0 @@
#ifndef TIMER_HXX
#define TIMER_HXX
#include <unistd.h>
#include <sys/time.h>
struct Timer
{
public:
struct timeval t1,t2;
double t;
void start()
{
gettimeofday (&t1, NULL);
}
void stop()
{
gettimeofday (&t2, NULL);
t = (t2.tv_sec - t1.tv_sec) + (t2.tv_usec - t1.tv_usec) / 1000000.0;
}
void reset()
{
t = 0.0;
}
};
#endif

View File

@ -1,172 +0,0 @@
#include "bbox.h"
#include <bbox/box_traits.h>
#include <bbox/all_pairs.h>
#include <bbox/one_way_scan.h>
// enable invariant checking
#define SEGMENT_TREE_CHECK_INVARIANTS 1
#include <bbox/segment_tree.h>
#include "Timer.h"
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <iterator>
#include <vector>
#include <cstdio>
#include <cmath>
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." <<endl;
if( callback1.counter != callback2.counter ) {
unsigned int missing = countMissingItems( result_all_pairs,
result_tree );
unsigned int duplicates = countDuplicates( result_tree );
cout << "!! failed !! " << missing << " missing and "
<< duplicates << " duplicate intersections in tree result."
<< endl;
}
else
cout << "--- passed --- " << endl;
fclose( infile1 );
fclose( infile2 );
}
int main( int argc, char ** argv ) {
for( unsigned int n = 1; n <= 6; ++n ) {
stringstream file1, file2;
file1 << "test" << n << "_set1.box" << ends;
file2 << "test" << n << "_set2.box" << ends;
test( file1.str().c_str(), file2.str().c_str() );
}
}

View File

@ -1,127 +0,0 @@
#ifndef CGAL_BBOX_3_ADAPTER_H
#define CGAL_BBOX_3_ADAPTER_H
#include <algorithm>
#include <functional>
/*
class Bbox_3
{
double x_lo, y_lo, z_lo;
double x_hi, y_hi, z_hi;
public:
Bbox_3(double x_lo, double y_lo, double z_lo,
double x_hi, double y_hi, double z_hi)
: x_lo( x_lo ), y_lo( y_lo ), z_lo( z_lo ),
x_hi( x_hi ), y_hi( y_hi ), z_hi( z_hi )
{}
double xlo() const { return x_lo; }
double ylo() const { return y_lo; }
double zlo() const { return z_lo; }
double xhi() const { return x_hi; }
double yhi() const { return y_hi; }
double zhi() const { return z_hi; }
Bbox_3 operator+(const Bbox_3& b) const {
return Bbox_3(std::lo( xlo(), b.xlo() ),
std::lo( ylo(), b.ylo() ),
std::lo( zlo(), b.zlo() ),
std::hi( xhi(), b.xhi() ),
std::hi( yhi(), b.yhi() ),
std::hi( zhi(), b.zhi() ));
}
};
class Bbox_3_Adapter : public Bbox_3 {
public:
Bbox_3_Adapter( double x_lo, double y_lo, double z_lo,
double x_hi, double y_hi, double z_hi )
: Bbox_3( x_lo, y_lo, z_lo, x_hi, y_hi, z_hi )
{}
double get_lo( unsigned int n ) const {
switch( n ) {
case 0: return xlo();
case 1: return ylo();
case 2: return zlo();
default: return 0;
}
}
double get_hi( unsigned int n ) const {
switch( n ) {
case 0: return xhi();
case 1: return yhi();
case 2: return zhi();
default: return 0;
}
}
};
*/
template< class T >
class Bbox_3
{
T __lo[3], __hi[3];
unsigned int __num;
public:
typedef T NumberType;
Bbox_3() {}
Bbox_3( T x_lo, T y_lo, T z_lo,
T x_hi, T y_hi, T z_hi )
{
__lo[0]= x_lo; __lo[1]= y_lo; __lo[2]= z_lo;
__hi[0]= x_hi; __hi[1]= y_hi; __hi[2]= z_hi;
__num = getCounter();
}
static unsigned int getCounter( bool reset = false ) {
static unsigned int counter = 0;
if( reset )
counter = 0;
else
++counter;
return counter;
}
T lo( unsigned int dim ) const { return __lo[dim]; }
T hi( unsigned int dim ) const { return __hi[dim]; }
unsigned int num() const { return __num; }
//unsigned int num() const { return (unsigned int )this; }
};
template< class _Box >
struct Bbox_3_Adapter {
typedef _Box Box;
typedef typename _Box::NumberType NumberType;
static NumberType get_lo( const Box& b, unsigned int dim )
{ return b.lo( dim ); }
static NumberType get_hi( const Box& b, unsigned int dim )
{ return b.hi( dim ); }
static unsigned int get_num( const Box& b )
{ return b.num(); }
};
template< class _Box >
struct Bbox_3_Pointer_Adapter {
typedef _Box* Box;
typedef typename _Box::NumberType NumberType;
static NumberType get_lo( const Box b, unsigned int dim )
{ return b->lo( dim ); }
static NumberType get_hi( const Box b, unsigned int dim )
{ return b->hi( dim ); }
static unsigned int get_num( const Box b )
{ return b->num(); }
};
#endif

View File

@ -1,31 +0,0 @@
#ifndef CGAL_BBOX_ALL_PAIRS_H
#define CGAL_BBOX_ALL_PAIRS_H
#include <algorithm>
template< class RandomAccessIter, class Callback, class Traits >
void all_pairs( RandomAccessIter p_begin, RandomAccessIter p_end,
RandomAccessIter i_begin, RandomAccessIter i_end,
Callback& callback, Traits traits, int last_dim,
bool in_order = true )
{
for( RandomAccessIter p = p_begin; p != p_end; ++p ) {
for( RandomAccessIter i = i_begin; i != i_end; ++i ) {
bool does_intersect = true;
for( unsigned int dim = 0; dim <= last_dim; ++dim )
if( !Traits::does_intersect( *p, *i, dim ) )
goto no_intersection;
if( in_order )
callback( *p, *i );
else
callback( *i, *p );
no_intersection:
;
}
}
}
#endif

View File

@ -1,84 +0,0 @@
#ifndef CGAL_BBOX_BOX_TRAITS_H
#define CGAL_BBOX_BOX_TRAITS_H
#include <algorithm>
#include <functional>
// BoxAdapter has to provide following static members:
// NumberType get_lo( Box, int dim )
// NumberType get_hi( Box, int dim )
// unsigned int get_num( Box )
// Box may be of type immediate, reference, or pointer
template< class BoxAdapter >
struct Default_Box_Traits : public BoxAdapter {
typedef typename BoxAdapter::Box Box;
typedef typename BoxAdapter::NumberType NumberType;
typedef Default_Box_Traits< BoxAdapter > Traits;
static unsigned int cutoff;
class Compare : public std::binary_function< Box, Box, bool > {
unsigned int dim;
public:
Compare( unsigned int dim ) : dim( dim ) {}
bool operator()( const Box& a, const Box& b ) const
{ return Traits::is_lo_less_lo( a, b, dim ); }
};
class Lo_Less : public std::unary_function< Box, bool > {
NumberType value;
unsigned int dim;
public:
Lo_Less( NumberType value, unsigned int dim )
: value( value ), dim( dim ) {}
bool operator() ( const Box& box ) const
{ return get_lo( box, dim ) < value; }
};
class Hi_Greater : public std::unary_function< Box, bool > {
NumberType value;
unsigned int dim;
public:
Hi_Greater( NumberType value, unsigned int dim )
: value( value ), dim( dim ) {}
bool operator() ( const Box& box ) const
{ return get_hi( box, dim ) > value; }
};
// lambda( box ).(get_lo(box,dim) < lo && get_hi(box,dim) > hi ) )
class Interval_Spanning_Predicate : public std::unary_function<Box,bool> {
NumberType lo, hi;
unsigned int dim;
public:
Interval_Spanning_Predicate( NumberType lo, NumberType hi,
unsigned int dim )
: lo( lo ), hi( hi ), dim( dim ) {}
// returns true <=> box spans [lo,hi) in dimension dim
bool operator() ( const Box& box ) const
{ return get_lo( box, dim ) < lo && get_hi( box, dim ) > hi; }
};
static bool is_lo_less_lo( const Box& a, const Box& b, unsigned int dim ) {
return get_lo(a,dim) < get_lo(b,dim) ||
get_lo(a,dim) == get_lo(b,dim) && get_num(a) < get_num(b);
}
static bool is_lo_less_hi( const Box& a, const Box& b, unsigned int dim )
{ return get_lo(a,dim ) < get_hi(b,dim); }
static bool does_intersect ( const Box& a, const Box& b, unsigned int dim )
{ return get_hi(a,dim) > get_lo(b,dim) && get_hi(b,dim) > get_lo(a,dim); }
static bool contains_lo_point(const Box& a, const Box& b, unsigned int dim)
{ return !is_lo_less_lo( b, a, dim ) && is_lo_less_hi( b, a, dim ); }
static unsigned int get_cutoff()
{ return cutoff; }
};
template< class BoxAdapter >
unsigned int
Default_Box_Traits<BoxAdapter>::cutoff = 3000;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,63 +0,0 @@
#ifndef CGAL_BBOX_MODIFIED_TWO_WAY_SCAN_H
#define CGAL_BBOX_MODIFIED_TWO_WAY_SCAN_H
#include <algorithm>
template< class RandomAccessIter,
class Callback,
class Traits >
void modified_two_way_scan( RandomAccessIter p_begin, RandomAccessIter p_end,
RandomAccessIter i_begin, RandomAccessIter i_end,
Callback& callback, Traits traits, unsigned int last_dim,
bool in_order = true )
{
typedef typename Traits::Compare Compare;
std::sort( p_begin, p_end, Compare( 0 ) );
std::sort( i_begin, i_end, Compare( 0 ) );
// for each box viewed as interval i
while( i_begin != i_end && p_begin != p_end ) {
if( Traits::is_lo_less_lo( *i_begin, *p_begin, 0 ) ) {
for( RandomAccessIter p = p_begin;
p != p_end && Traits::is_lo_less_hi( *p, *i_begin, 0 );
++p )
{
for( unsigned int dim = 1; dim <= last_dim; ++dim )
if( !Traits::does_intersect( *p, *i_begin, dim ) )
goto no_intersection1;
if( Traits::contains_lo_point( *i_begin, *p, last_dim ) ) {
if( in_order )
callback( *p, *i_begin );
else
callback( *i_begin, *p );
}
no_intersection1:
;
}
++i_begin;
} else {
for( RandomAccessIter i = i_begin;
i != i_end && Traits::is_lo_less_hi( *i, *p_begin, 0 );
++i )
{
for( unsigned int dim = 1; dim <= last_dim; ++dim )
if( !Traits::does_intersect( *p_begin, *i, dim ) )
goto no_intersection2;
if( Traits::contains_lo_point( *i, *p_begin, last_dim ) ) {
if( in_order )
callback( *p_begin, *i );
else
callback( *i, *p_begin );
}
no_intersection2:
;
}
++p_begin;
}
}
}
#endif

View File

@ -1,43 +0,0 @@
#ifndef CGAL_BBOX_ONE_WAY_SCAN_H
#define CGAL_BBOX_ONE_WAY_SCAN_H
#include <algorithm>
template< class RandomAccessIter, class Callback, class Traits >
void one_way_scan( RandomAccessIter p_begin, RandomAccessIter p_end,
RandomAccessIter i_begin, RandomAccessIter i_end,
Callback& callback, Traits traits, unsigned int last_dim,
bool in_order = true )
{
typedef typename Traits::Compare Compare;
std::sort( p_begin, p_end, Compare( 0 ) );
std::sort( i_begin, i_end, Compare( 0 ) );
// for each box viewed as interval i
for( RandomAccessIter i = i_begin; i != i_end; ++i ) {
// look for the first box b with i.min <= p.min
for( ; p_begin != p_end && Traits::is_lo_less_lo( *p_begin, *i, 0 );
++p_begin );
// look for all boxes with p.min < i.max
for( RandomAccessIter p = p_begin;
p != p_end && Traits::is_lo_less_hi( *p, *i, 0 );
++p )
{
for( unsigned int dim = 1; dim <= last_dim; ++dim )
if( !Traits::does_intersect( *p, *i, dim ) )
goto no_intersection;
if( in_order )
callback( *p, *i );
else
callback( *i, *p );
no_intersection:
;
}
}
}
#endif

View File

@ -1,245 +0,0 @@
#ifndef CGAL_BBOX_SEGMENT_TREE_H
#define CGAL_BBOX_SEGMENT_TREE_H
#include <bbox/one_way_scan.h>
#include <bbox/modified_two_way_scan.h>
#include <algorithm>
#include <iterator>
#include <cstdlib>
#include <cmath>
#include <functional>
#include <cassert>
#ifdef USE_MY_NUMERIC_LIMITS
#include <bbox/limits>
#else
#include <limits>
#endif
#define DEBUG 0
template< class RandomAccessIter, class Traits >
RandomAccessIter
median_of_three( RandomAccessIter a, RandomAccessIter b, RandomAccessIter c,
Traits traits, unsigned int dim )
{
if( Traits::is_lo_less_lo( *a, *b, dim ) )
if( Traits::is_lo_less_lo( *b, *c, dim ) )
return b;
else if( Traits::is_lo_less_lo( *a, *c, dim ) )
return c;
else
return a;
else if( Traits::is_lo_less_lo( *a, *c, dim ) )
return a;
else if( Traits::is_lo_less_lo( *b, *c, dim ) )
return c;
else
return b;
}
template< class RandomAccessIter, class Traits >
RandomAccessIter
iterative_radon( RandomAccessIter begin, RandomAccessIter end,
Traits traits, unsigned int dim, int num_levels )
{
if( num_levels < 0 )
return begin + lrand48() % std::distance( begin, end );
return median_of_three(
iterative_radon( begin, end, traits, dim, num_levels - 1 ),
iterative_radon( begin, end, traits, dim, num_levels - 1 ),
iterative_radon( begin, end, traits, dim, num_levels - 1 ),
traits, dim );
}
// returns iterator for first element in [begin,end) which does not satisfy
// the Split_Points_Predicate: [begin,mid) contains only points strictly less
// than mi. so, elements from [mid,end) are equal or higher than mi.
template< class RandomAccessIter, class Traits, class T >
RandomAccessIter
split_points( RandomAccessIter begin, RandomAccessIter end, Traits traits,
int dim, T& mi )
{
// magic formula
int levels = (int)(.91*log(((double)std::distance(begin,end))/137.0)+1);
levels = (levels <= 0) ? 1 : levels;
RandomAccessIter it = iterative_radon( begin, end, traits, dim, levels );
mi = Traits::get_lo( *it, dim );
return std::partition( begin, end, typename Traits::Lo_Less( mi, dim ) );
}
//#define DEBUG 0
#if DEBUG
static int level = -1;
#define DUMP(msg) { \
for( unsigned int i = level; i; --i ) \
std::cout << " "; \
std::cout << msg; \
}
#else
#define DUMP(msg) ;
#endif
template< class ForwardIter, class Traits >
void dump_points( ForwardIter begin, ForwardIter end, Traits traits,
unsigned int dim ) {
while( begin != end ) {
std::cout << Traits::get_lo( *begin, dim ) << " ";
++begin;
}
std::cout << std::endl;
}
template< class ForwardIter, class Traits >
void dump_intervals( ForwardIter begin, ForwardIter end, Traits traits,
unsigned int dim ) {
while( begin != end ) {
std::cout << "[" << Traits::get_lo( *begin, dim ) << ","
<< Traits::get_hi( *begin, dim ) << ") ";
++begin;
}
std::cout << std::endl;
}
template< class ForwardIter, class Traits >
void dump_box_numbers( ForwardIter begin, ForwardIter end, Traits traits ) {
while( begin != end ) {
std::cout << Traits::get_num( *begin ) << " ";
++begin;
}
std::cout << std::endl;
}
template< class T >
struct Counter {
T& value;
Counter( T& value ) : value( value ) { ++value; }
~Counter() { --value; }
};
template< class RandomAccessIter, class Callback, class T, class Traits >
void segment_tree( RandomAccessIter p_begin, RandomAccessIter p_end,
RandomAccessIter i_begin, RandomAccessIter i_end,
T lo, T hi,
Callback& callback, Traits traits, unsigned int dim,
bool in_order )
{
typedef typename Traits::Box Box;
typedef typename Traits::Interval_Spanning_Predicate Spanning;
typedef typename Traits::Lo_Less Lo_Less;
typedef typename Traits::Hi_Greater Hi_Greater;
#if DEBUG
Counter<int> bla( level );
//DUMP("----------------===========[ new node ]============-------------")
DUMP("range: [" << lo << "," << hi << ") dim " << dim << std::endl )
DUMP("intervals: " )
dump_box_numbers( i_begin, i_end, traits );
//dump_intervals( i_begin, i_end, traits, dim );
DUMP("points: " )
dump_box_numbers( p_begin, p_end, traits );
//dump_points( p_begin, p_end, traits, dim );
#endif
#if SEGMENT_TREE_CHECK_INVARIANTS
// first: each point is inside segment [lo,hi)
for( RandomAccessIter it = p_begin; it != p_end; ++it ) {
assert( Traits::get_lo( *it, dim ) < hi );
assert( Traits::get_lo( *it, dim ) >= lo );
}
// second: each interval intersects segment [lo,hi)
for( RandomAccessIter it = i_begin; it != i_end; ++it ) {
assert( Traits::get_lo( *it, dim ) < hi );
assert( Traits::get_hi( *it, dim ) > lo );
}
#endif
if( p_begin == p_end || i_begin == i_end || lo >= hi )
return;
if( dim == 0 ) {
DUMP( "dim = 0. scanning ... " << std::endl )
one_way_scan( p_begin, p_end, i_begin, i_end,
callback, traits, dim, in_order );
return;
}
if( (unsigned int)std::distance( p_begin, p_end ) < Traits::get_cutoff() ||
(unsigned int)std::distance( i_begin, i_end ) < Traits::get_cutoff() )
{
DUMP( "scanning ... " << std::endl )
modified_two_way_scan( p_begin, p_end, i_begin, i_end,
callback, traits, dim, in_order );
return;
}
RandomAccessIter i_span_end =
lo == std::numeric_limits< T >::min() ||
hi == std::numeric_limits< T >::max() ? i_begin :
std::partition( i_begin, i_end, Spanning( lo, hi, dim ) );
if( i_begin != i_span_end ) {
DUMP( "checking spanning intervals ... " << std::endl )
// make two calls for roots of segment tree at next level.
segment_tree( p_begin, p_end, i_begin, i_span_end,
std::numeric_limits< T >::min(),
std::numeric_limits< T >::max(),
callback, traits, dim - 1, in_order );
segment_tree( i_begin, i_span_end, p_begin, p_end,
std::numeric_limits< T >::min(),
std::numeric_limits< T >::max(),
callback, traits, dim - 1, !in_order );
}
T mi;
RandomAccessIter p_mid = split_points( p_begin, p_end, traits, dim, mi );
if( p_mid == p_begin || p_mid == p_end ) {
DUMP( "unable to split points! ")
//dump_points( p_begin, p_end, traits, dim );
DUMP( "performing modified two_way_san ... " << std::endl )
modified_two_way_scan( p_begin, p_end, i_span_end, i_end,
callback, traits, dim, in_order );
return;
}
RandomAccessIter i_mid;
// separate left intervals.
// left intervals have a low point strictly less than mi
i_mid = std::partition( i_span_end, i_end, Lo_Less( mi, dim ) );
DUMP("->left" << std::endl )
segment_tree( p_begin, p_mid, i_span_end, i_mid, lo, mi,
callback, traits, dim, in_order );
// separate right intervals.
// right intervals have a high point strictly higher than mi
i_mid = std::partition( i_span_end, i_end, Hi_Greater( mi, dim ) );
DUMP("->right"<< std::endl )
segment_tree( p_mid, p_end, i_span_end, i_mid, mi, hi,
callback, traits, dim, in_order );
}
template< class RandomAccessIter, class Callback, class Traits >
void segment_tree( RandomAccessIter p_begin, RandomAccessIter p_end,
RandomAccessIter i_begin, RandomAccessIter i_end,
Callback& callback, Traits traits, unsigned int dim )
{
typedef typename Traits::NumberType T;
segment_tree( p_begin, p_end, i_begin, i_end,
-std::numeric_limits< T >::max(),
std::numeric_limits< T >::max(),
callback, traits, dim, true );
segment_tree( i_begin, i_end, p_begin, p_end,
-std::numeric_limits< T >::max(),
std::numeric_limits< T >::max(),
callback, traits, dim, false );
}
#endif

View File

@ -1,15 +0,0 @@
CXX = g++
INCLUDE = -I./include
CXXFLAGS = $(INCLUDE) -O1
random_set_test: random_set_test.cc
$(CXX) $(CXXFLAGS) random_set_test.cc -o random_set_test
automated_test: automated_test.cc
$(CXX) $(CXXFLAGS) automated_test.cc -o automated_test
# $(CXX) -O3 -fomit-frame-pointer -fexpensive-optimizations -falign-functions=4 -malign-double -fprefetch-loop-arrays -march=pentium3 -msse automated_test.cc -o segment_tree
# -funroll-loops brings 10 percent slowdown on duron750 (64kb cache)

View File

@ -1,164 +0,0 @@
#include "bbox.h"
#include <bbox/box_traits.h>
#include <bbox/one_way_scan.h>
// enable invariant checking
#define SEGMENT_TREE_CHECK_INVARIANTS 1
#include <bbox/segment_tree.h>
#include "Timer.h"
#include <iostream>
#include <cstdlib>
#include <iterator>
#include <vector>
#include <cstdio>
#include <cmath>
using namespace std;
typedef double NumberType;
typedef Bbox_3< NumberType > 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 fill_boxes( unsigned int n, BoxContainer& boxes ) {
unsigned int maxEdgeLength = (int) pow(n, (double)2/3);
for( unsigned int i = 0; i < n; ++i ) {
NumberType lo[3], hi[3];
for( unsigned int d = 0; d < 3; ++d ) {
lo[d] = (NumberType)(drand48() * (n - maxEdgeLength));
hi[d] = lo[d] + 1 + (NumberType)(drand48() * maxEdgeLength);
}
boxes.push_back( Box( lo[0], lo[1], lo[2], hi[0], hi[1], hi[2] ) );
}
}
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_n( unsigned int n )
{
BoxContainer boxes1, boxes2;
ResultContainer result_scanner, result_tree;
cout << "generating random box sets with size " << n << " ... " << flush;
fill_boxes( n, boxes1 );
fill_boxes( n, boxes2 );
cout << endl;
StorageCallback< ResultContainer >
callback1( result_scanner ),
callback2( result_tree );
cout << "one way scan ... " << flush;
Timer timer;
timer.start();
one_way_scan( boxes1.begin(), boxes1.end(),
boxes2.begin(), boxes2.end(), callback1, Traits(), 2 );
one_way_scan( boxes2.begin(), boxes2.end(),
boxes1.begin(), boxes1.end(), callback1, Traits(), 2 );
timer.stop();
cout << "got " << callback1.counter << " intersections in "
<< timer.t << " seconds."
<< endl;
cout << "segment tree ... " << flush;
timer.reset();
timer.start();
Traits::cutoff = n < 2000 ? 6 : n / 100;
//Traits::cutoff = 5;
segment_tree( boxes1.begin(), boxes1.end(),
boxes2.begin(), boxes2.end(), callback2, Traits(), 2 );
timer.stop();
cout << "got " << callback2.counter << " intersections in "
<< timer.t << " seconds." <<endl;
if( callback1.counter != callback2.counter ) {
unsigned int missing = countMissingItems( result_scanner,
result_tree );
unsigned int duplicates = countDuplicates( result_tree );
cout << "!! failed !! " << missing << " missing and "
<< duplicates << " duplicate intersections in tree result."
<< endl;
}
else
cout << "--- passed --- " << endl;
}
int main( int argc, char ** argv ) {
for( unsigned int n = 8; n < 500000; n = (int)(n * 1.3))
test_n( n );
}