Commit 5d8397b5 authored by Mathias Goldau's avatar Mathias Goldau
Browse files

[ADD] Get Neighbours of a voxel coordinate as vector

parent c30bfc34
......@@ -25,8 +25,9 @@
#include <cmath>
#include <vector>
#include "WGridRegular3D.h"
#include "../common/exceptions/WOutOfBounds.h"
#include "../math/WLinearAlgebraFunctions.h"
#include "WGridRegular3D.h"
using wmath::WVector3D;
using wmath::WPosition;
......@@ -300,3 +301,47 @@ boost::shared_ptr< std::vector< wmath::WPosition > > WGridRegular3D::getVoxelVer
return result;
}
std::vector< size_t > WGridRegular3D::getNeighbours( size_t id ) const
{
std::vector< size_t > neighbours;
size_t x = id % m_nbPosX;
size_t y = ( id / m_nbPosX ) % m_nbPosY;
size_t z = id / ( m_nbPosX * m_nbPosY );
if( x >= m_nbPosX || y >= m_nbPosY || z >= m_nbPosZ )
{
std::stringstream ss;
ss << "This point: " << id << " is not part of this grid: ";
ss << " nbPosX: " << m_nbPosX;
ss << " nbPosY: " << m_nbPosY;
ss << " nbPosZ: " << m_nbPosZ;
throw WOutOfBounds( ss.str() );
}
// for every neighbour we must check if its not on the boundary, it will be skipped otherwise
if( x > 0 )
{
neighbours.push_back( id - 1 );
}
if( x < m_nbPosX - 1 )
{
neighbours.push_back( id + 1 );
}
if( y > 0 )
{
neighbours.push_back( id - m_nbPosX );
}
if( y < m_nbPosY - 1 )
{
neighbours.push_back( id + m_nbPosX );
}
if( z > 0 )
{
neighbours.push_back( id - ( m_nbPosX * m_nbPosY ) );
}
if( z < m_nbPosZ - 1 )
{
neighbours.push_back( id + ( m_nbPosX * m_nbPosY ) );
}
return neighbours;
}
......@@ -341,6 +341,8 @@ public:
boost::shared_ptr< std::vector< wmath::WPosition > > getVoxelVertices( const wmath::WPosition& point,
const double margin = 0.0 ) const;
std::vector< size_t > getNeighbours( size_t id ) const;
protected:
private:
/**
......
......@@ -33,6 +33,7 @@
#include <cxxtest/TestSuite.h>
#include "../../common/exceptions/WOutOfBounds.h"
#include "../../math/test/WVector3DTraits.h"
#include "../WGridRegular3D.h"
......@@ -412,21 +413,76 @@ public:
// | | |
// 0,0,0 1,0,0 2,0,0
using boost::shared_ptr;
shared_ptr< WGridRegular3D > g = shared_ptr< WGridRegular3D >( new WGridRegular3D( 3, 3, 3, 0, 0, 0, 1, 1, 1 ) );
WGridRegular3D g( 3, 3, 3, 0, 0, 0, 1, 1, 1 );
// center point of the grid
TS_ASSERT_EQUALS( g->getVoxelNum( wmath::WPosition( 1, 1, 1 ) ), 13 );
TS_ASSERT_EQUALS( g.getVoxelNum( wmath::WPosition( 1, 1, 1 ) ), 13 );
// front lower left corner of the last cell
TS_ASSERT_EQUALS( g->getVoxelNum( wmath::WPosition( 1.5, 1.5, 1.5 ) ), 26 );
TS_ASSERT_EQUALS( g.getVoxelNum( wmath::WPosition( 1.5, 1.5, 1.5 ) ), 26 );
TS_ASSERT_EQUALS( g->getVoxelNum( wmath::WPosition( 1, 1, 0.5 ) ), 13 );
TS_ASSERT_EQUALS( g->getVoxelNum( wmath::WPosition( 0 , 1.5 , 1 ) ), 15 );
TS_ASSERT_EQUALS( g->getVoxelNum( wmath::WPosition( 0.5, 1, 0 ) ), 4 );
TS_ASSERT_EQUALS( g.getVoxelNum( wmath::WPosition( 1, 1, 0.5 ) ), 13 );
TS_ASSERT_EQUALS( g.getVoxelNum( wmath::WPosition( 0 , 1.5 , 1 ) ), 15 );
TS_ASSERT_EQUALS( g.getVoxelNum( wmath::WPosition( 0.5, 1, 0 ) ), 4 );
// origin
TS_ASSERT_EQUALS( g->getVoxelNum( wmath::WPosition( 0, 0, 0 ) ), 0 );
TS_ASSERT_EQUALS( g.getVoxelNum( wmath::WPosition( 0, 0, 0 ) ), 0 );
}
/**
* A voxel inside a grid (not located on a border) has 6 neighbours.
*/
void testNeighboursInsideAGrid( void )
{
WGridRegular3D g( 3, 3, 3, 0, 0, 0, 1, 1, 1 );
size_t data[] = { 12, 14, 10, 16, 4, 22 };
std::vector< size_t > expected( data, data + 6 );
TS_ASSERT_EQUALS( expected, g.getNeighbours( 13 ) );
}
/**
* A voxel with voxel-coordinates 0,0,0 has only three neighbours: 1,0,0; 0,1,0 and 0,0,1.
*/
void testNeighboursOnFrontLowerLeft( void )
{
WGridRegular3D g( 3, 3, 3, 0, 0, 0, 1, 1, 1 );
size_t data[] = { 1, 3, 9 };
std::vector< size_t > expected( data, data + 3 );
TS_ASSERT_EQUALS( expected, g.getNeighbours( 0 ) );
}
/**
* A voxel in the back upper right corner should also have only 3 neighbours.
*/
void testNeighbourOnBackUpperRight( void )
{
WGridRegular3D g( 3, 3, 3, 0, 0, 0, 1, 1, 1 );
size_t data[] = { 25, 23, 17 };
std::vector< size_t > expected( data, data + 3 );
TS_ASSERT_EQUALS( expected, g.getNeighbours( 26 ) );
}
/**
* A Voxel on a border plane should have neighbours on the plane but not
* out side the grid.
*/
void testNeighbourOnLeftBorderPlane( void )
{
WGridRegular3D g( 3, 3, 3, 0, 0, 0, 1, 1, 1 );
size_t data[] = { 13, 9, 15, 3, 21 };
std::vector< size_t > expected( data, data + 5 );
TS_ASSERT_EQUALS( expected, g.getNeighbours( 12 ) );
}
/**
* If the neighbours of a voxel not inside this grid are requested an Exception
* WOutOfBounds should be thrown.
*/
void testNeighbourOfVoxelNotInsideThisGrid( void )
{
WGridRegular3D g( 3, 3, 3, 0, 0, 0, 1, 1, 1 );
TS_ASSERT_THROWS_EQUALS( g.getNeighbours( 27 ), const WOutOfBounds &e, std::string( e.what() ),
"This point: 27 is not part of this grid: nbPosX: 3 nbPosY: 3 nbPosZ: 3" );
}
private:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment