/SpacePartitioning

A collection of Space Partitioning Algorithms for Cinder

Primary LanguageC++BSD 2-Clause "Simplified" LicenseBSD-2-Clause

SpacePartitioning

A collection of c++11 Space Partitioning templates for Cinder

This is a work in progress; currently only KdTree and Bin-lattice / Grid are available, but HashTable, Octree and BSPTree are on their way.

Basic Use:
Each classes share the same syntax for common tasks.

// Create a 3d KdTree (use alias for KdTree<3,float>)
sp::KdTree3 kdTree; 

// Insert elements
for( auto node : mNodes ) {
	const vec3& pos = node->getPosition();
	void* userData 	= static_cast<void*>( node );
	kdTree.insert( pos, userData );
}

// Nearest neighbor search
auto nn = kdTree.nearestNeighborSearch( vec3( 0.0f ) );

// Nearest neighbor search and get the distance square to the position
float distSq;
nn = kdTree.nearestNeighborSearch( vec3( 1.0f, 2.0f, 3.0f ), &distSq );

// Range search
auto neighbors = kdTree.rangeSearch( vec3( 0.0f ), 35.0f );
for( auto neighbor : neighbors ) {
	auto node = neighbor.first;
	auto distSq = neighbor.second;
	// ...
}

// Visitor Range search
auto neighbors = kdTree.rangeSearch( vec3( 0.0f ), 35.0f, 
	[]( KdTree2::Node* node, float distSq ) {
		// ...
	} );

KdTree:

A KdTree is a versatile space partitioning structure. They work in most situations and are really fast for nearest neighbor searches. If memory or insertion time is important they might not be the right choice. This implementation is not particulary optimised for range searches.

KdTrees come in the following flavors :

typedef KdTree<2, float>	KdTree2;
typedef KdTree<3, float>	KdTree3;
typedef KdTree<4, float>	KdTree4;
typedef KdTree<2, double>	dKdTree2;
typedef KdTree<3, double>	dKdTree3;
typedef KdTree<4, double>	dKdTree4;

Grid:

A Bin-Lattice spatial subdivision structure or uniform grid is easy and particulary fast. They clearly excel at range searches, usually have a small memory footprint and have fast insertion time. When it's not clear which structure to choose, Grid might be the first one to try. The choice of the k parameter is critical and might influence a lot the performance depending on the data. Providing the bounding rectangle or bounding box of the data is prefered if you need fast insertion. If you ommit the bounds parameters, insertion will obviously be much slower.

Grids come in the following flavors :

typedef Grid<2, float>		Grid2;
typedef Grid<3, float>		Grid3;
typedef Grid<2, double>		dGrid2;
typedef Grid<3, double>		dGrid3;

Test suite:
Running test.cpp should output something along those lines. It might be usefull to run these tests with your own data as the results might changes drastically according its type and distribution.

2d Brute Force

	Range search 				3.22801ms 		1990 neighbors
	Nearest search 				2.22701ms 		[    0.055,    0.027]
_____________________________________________________________________________________________

KdTree2

	Memory Footprint 			38.147mb
	Inserting 1000000 objects 	731.91ms
	Range Search 				0.497997ms 		1990 neighbors
	Range Search lambda 		0.222027ms 		1990 neighbors
	Nearest Search 				0.00196695ms 	[    0.055,    0.027]
	Clearing structure 			119.747ms
_____________________________________________________________________________________________

Grid2 k = 1

	Memory Footprint 			15.4923mb
	Inserting 1000000 objects 	93.623ms
	Range Search 				0.102997ms 		1990 neighbors
	Range Search lambda 		0.0450015ms 	1990 neighbors
	Nearest Search 				0.0119805ms 	[    0.055,    0.027]
	Clearing structure 			86.762ms
_____________________________________________________________________________________________

Grid2 k = 2

	Memory Footprint 			15.3184mb
	Inserting 1000000 objects 	116.088ms
	Range Search 				0.102997ms 		1990 neighbors
	Range Search lambda 		0.0609756ms 	1990 neighbors
	Nearest Search 				0.00995398ms 	[    0.055,    0.027]
	Clearing structure 			87.708ms
_____________________________________________________________________________________________

Grid2 k = 3

	Memory Footprint 			15.2743mb
	Inserting 1000000 objects 	117.888ms
	Range Search 				0.140011ms 		1990 neighbors
	Range Search lambda 		0.115037ms 		1990 neighbors
	Nearest Search 				0.145972ms 		[    0.055,    0.027]
	Clearing structure 			92.24ms
_____________________________________________________________________________________________

Grid2 k = 4

	Memory Footprint 			15.2627mb
	Inserting 1000000 objects 	120.338ms
	Range Search 				0.141025ms 		1990 neighbors
	Range Search lambda 		0.113964ms 		1990 neighbors
	Nearest Search 				0.118971ms 		[    0.055,    0.027]
	Clearing structure 			92.325ms
_____________________________________________________________________________________________

Unbounded-Grid2 k = 1

	Memory Footprint 			15.4923mb
	Inserting 1000000 objects 	297.285ms
	Range Search 				0.102997ms 		1990 neighbors
	Range Search lambda 		0.0700355ms 	1990 neighbors
	Nearest Search 				0.0090003ms 	[    0.055,    0.027]
	Clearing structure 			90.626ms
_____________________________________________________________________________________________



3d Brute Force

	Range search 				1.97297ms 		73 neighbors
	Nearest search 				1.90198ms 		[    0.103,    0.016,    1.801]
_____________________________________________________________________________________________

KdTree3

	Memory Footprint 			38.147mb
	Inserting 1000000 objects 	1009.77ms
	Range Search 				0.0450015ms 		73 neighbors
	Range Search lambda 		0.0160336ms 		73 neighbors
	Nearest Search 				0.00196695ms 		[    0.103,    0.016,    1.801]
	Clearing structure 			128.187ms
_____________________________________________________________________________________________

Grid3 k = 1

	Memory Footprint 			46.47mb
	Inserting 1000000 objects 	281.196ms
	Range Search 				0.0350475ms 		73 neighbors
	Range Search lambda 		0.00798702ms 		73 neighbors
	Nearest Search 				0.00202656ms 		[    0.103,    0.016,    1.801]
	Clearing structure 			117.986ms
_____________________________________________________________________________________________

Grid3 k = 2

	Memory Footprint 			25.9244mb
	Inserting 1000000 objects 	277.803ms
	Range Search 				0.0240207ms 		73 neighbors
	Range Search lambda 		0.00399351ms 		73 neighbors
	Nearest Search 				0.00303984ms 		[    0.103,    0.016,    1.801]
	Clearing structure 			95.844ms
_____________________________________________________________________________________________

Grid3 k = 3

	Memory Footprint 			23.2906mb
	Inserting 1000000 objects 	102.613ms
	Range Search 				0.0320077ms 		73 neighbors
	Range Search lambda 		0.0100136ms 		73 neighbors
	Nearest Search 				0.00298023ms 		[    0.103,    0.016,    1.801]
	Clearing structure 			98.442ms
_____________________________________________________________________________________________

Grid3 k = 4

	Memory Footprint 			22.9386mb
	Inserting 1000000 objects 	151.011ms
	Range Search 				0.048995ms 			73 neighbors
	Range Search lambda 		0.0529885ms 		73 neighbors
	Nearest Search 				0.0169873ms 		[    0.103,    0.016,    1.801]
	Clearing structure 			101.531ms
_____________________________________________________________________________________________

Unbounded-Grid3 k = 3

	Memory Footprint 			23.2906mb
	Inserting 1000000 objects 	378.761ms
	Range Search 				0.050962ms 			73 neighbors
	Range Search lambda 		0.0370145ms 		73 neighbors
	Nearest Search 				0.0370145ms 		[    0.103,    0.016,    1.801]
	Clearing structure 			97.918ms
_____________________________________________________________________________________________