00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef WGRIDREGULAR3D_TEST_H
00026 #define WGRIDREGULAR3D_TEST_H
00027
00028 #include <cstdio>
00029 #include <sstream>
00030 #include <string>
00031 #include <vector>
00032
00033 #include <boost/shared_ptr.hpp>
00034
00035 #include <cxxtest/TestSuite.h>
00036
00037 #include "../../common/exceptions/WOutOfBounds.h"
00038 #include "../../common/math/test/WVector3dTraits.h"
00039 #include "../../common/WLimits.h"
00040 #include "../WGridRegular3D.h"
00041
00042
00043
00044
00045
00046 class WGridRegular3DTest : public CxxTest::TestSuite
00047 {
00048 public:
00049
00050
00051
00052 void setUp( void )
00053 {
00054 m_delta = 1e-14;
00055 }
00056
00057
00058
00059
00060 void testInstantiation( void )
00061 {
00062 TS_ASSERT_THROWS_NOTHING( WGridRegular3D grid( 3, 3, 3 ) );
00063 }
00064
00065
00066
00067
00068 void testSize( void )
00069 {
00070 WGridTransformOrtho t( WMatrix< double >( 4, 4 ).makeIdentity() );
00071 WGridRegular3D grid( 3, 3, 3, t );
00072 TS_ASSERT_EQUALS( grid.size(), 27 );
00073 }
00074
00075
00076
00077
00078 void testConvinienceFunctions( void )
00079 {
00080 boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 3, 3, 3 ) );
00081 boost::array< unsigned int, 3 > expectedNbCoords = { { 3, 3, 3 } };
00082 TS_ASSERT_EQUALS( expectedNbCoords, getNbCoords( grid ) );
00083 boost::array< double, 3 > expectedOffsets = { { 1.0, 1.0, 1.0 } };
00084 TS_ASSERT_EQUALS( expectedOffsets, getOffsets( grid ) );
00085 boost::array< WVector3d, 3 > expectedDirections = { { WVector3d( 1.0, 0.0, 0.0 ), WVector3d( 0.0, 1.0, 0.0 ), WVector3d( 0.0, 0.0, 1.0 ) } };
00086 TS_ASSERT_EQUALS( expectedDirections, getDirections( grid ) );
00087 TS_ASSERT_EQUALS( expectedDirections, getUnitDirections( grid ) );
00088 }
00089
00090
00091
00092
00093 void testOrientation( void )
00094 {
00095 WMatrix< double > mat( 4, 4 );
00096 mat.makeIdentity();
00097 mat( 0, 0 ) = 2.2;
00098 mat( 1, 1 ) = 3.3;
00099 mat( 2, 2 ) = 4.4;
00100
00101 WGridTransformOrtho t( mat );
00102 WGridRegular3D grid( 3, 3, 3, t );
00103 TS_ASSERT_EQUALS( grid.size(), 27 );
00104 TS_ASSERT_EQUALS( grid.getOrigin(), WPosition( 0., 0., 0. ) );
00105 TS_ASSERT_EQUALS( grid.getDirectionX(), WVector3d( 2.2, 0., 0. ) );
00106 TS_ASSERT_EQUALS( grid.getDirectionY(), WVector3d( 0., 3.3, 0. ) );
00107 TS_ASSERT_EQUALS( grid.getDirectionZ(), WVector3d( 0., 0., 4.4 ) );
00108 }
00109
00110
00111
00112
00113 void testGetNbCoords( void )
00114 {
00115 size_t x = 3;
00116 size_t y = 4;
00117 size_t z = 5;
00118 WGridRegular3D grid( x, y, z );
00119 TS_ASSERT_EQUALS( grid.getNbCoordsX(), x );
00120 TS_ASSERT_EQUALS( grid.getNbCoordsY(), y );
00121 TS_ASSERT_EQUALS( grid.getNbCoordsZ(), z );
00122 }
00123
00124
00125
00126
00127
00128 void testGetVectorOffset( void )
00129 {
00130 WVector3d x( 3., 1., 2. );
00131 WVector3d y( 2., -6., 0. );
00132 WVector3d z( 12., 4., -20 );
00133
00134 WMatrix< double > mat( 4, 4 );
00135 mat.makeIdentity();
00136 mat( 0, 0 ) = x[ 0 ];
00137 mat( 1, 0 ) = x[ 1 ];
00138 mat( 2, 0 ) = x[ 2 ];
00139 mat( 0, 1 ) = y[ 0 ];
00140 mat( 1, 1 ) = y[ 1 ];
00141 mat( 2, 1 ) = y[ 2 ];
00142 mat( 0, 2 ) = z[ 0 ];
00143 mat( 1, 2 ) = z[ 1 ];
00144 mat( 2, 2 ) = z[ 2 ];
00145
00146 WGridTransformOrtho t( mat );
00147 WGridRegular3D grid( 3, 3, 3, t );
00148
00149 TS_ASSERT_DELTA( grid.getOffsetX(), length( x ), m_delta );
00150 TS_ASSERT_DELTA( grid.getOffsetY(), length( y ), m_delta );
00151 TS_ASSERT_DELTA( grid.getOffsetZ(), length( z ), m_delta );
00152 }
00153
00154
00155
00156
00157 void testGetPositionScalarOffset( void )
00158 {
00159 unsigned int nX = 10, nY = 11, nZ = 12;
00160 unsigned int iX = 8, iY = 9, iZ = 5;
00161 unsigned int i = iX + iY * nX + iZ * nX * nY;
00162
00163 double orX = 1.2;
00164 double orY = 3.4;
00165 double orZ = 5.6;
00166
00167 double ofX = 1.1;
00168 double ofY = 2.2;
00169 double ofZ = 3.3;
00170
00171 double x = orX + iX * ofX;
00172 double y = orY + iY * ofY;
00173 double z = orZ + iZ * ofZ;
00174
00175 WMatrix< double > mat( 4, 4 );
00176 mat.makeIdentity();
00177 mat( 0, 0 ) = ofX;
00178 mat( 1, 1 ) = ofY;
00179 mat( 2, 2 ) = ofZ;
00180 mat( 0, 3 ) = orX;
00181 mat( 1, 3 ) = orY;
00182 mat( 2, 3 ) = orZ;
00183
00184 WPosition expected( x, y, z );
00185 WGridTransformOrtho t( mat );
00186 WGridRegular3D grid( nX, nY, nZ, t );
00187
00188 TS_ASSERT_DELTA( grid.getPosition( iX, iY, iZ )[0], expected[0], m_delta );
00189 TS_ASSERT_DELTA( grid.getPosition( iX, iY, iZ )[1], expected[1], m_delta );
00190 TS_ASSERT_DELTA( grid.getPosition( iX, iY, iZ )[2], expected[2], m_delta );
00191 TS_ASSERT_DELTA( grid.getPosition( i )[0], expected[0], m_delta );
00192 TS_ASSERT_DELTA( grid.getPosition( i )[1], expected[1], m_delta );
00193 TS_ASSERT_DELTA( grid.getPosition( i )[2], expected[2], m_delta );
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 void testGetVoxelNumberOfGeneralPosition( void )
00222 {
00223 using boost::shared_ptr;
00224
00225 WMatrix< double > mat( 4, 4 );
00226 mat.makeIdentity();
00227 mat( 0, 3 ) = 3.1;
00228 mat( 1, 3 ) = 3.2;
00229 mat( 2, 3 ) = -6.;
00230
00231 WGridTransformOrtho t( mat );
00232 shared_ptr< WGridRegular3D > g = shared_ptr< WGridRegular3D >( new WGridRegular3D( 3, 3, 3, t ) );
00233 TS_ASSERT_EQUALS( g->getVoxelNum( WPosition( 4.35, 5.0, -6 ) ), 7 );
00234 }
00235
00236
00237
00238
00239 void testGetVoxelNumberOfPositionOutsideOfGrid( void )
00240 {
00241 using boost::shared_ptr;
00242
00243 shared_ptr< WGridRegular3D > g = shared_ptr< WGridRegular3D >( new WGridRegular3D( 3, 3, 3 ) );
00244 TS_ASSERT_EQUALS( g->getVoxelNum( WPosition( 0 - m_delta, 0, 0 ) ), -1 );
00245 TS_ASSERT_EQUALS( g->getVoxelNum( WPosition( 0, 2 + m_delta, 0 ) ), -1 );
00246 }
00247
00248
00249
00250
00251
00252
00253
00254 void testGetVoxelNumberOfPositionExactlyBetweenVoxels( void )
00255 {
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290 WGridRegular3D g( 3, 3, 3 );
00291
00292
00293 TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 1, 1, 1 ) ), 13 );
00294
00295
00296 TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 1.5, 1.5, 1.5 ) ), 26 );
00297
00298 TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 1, 1, 0.5 ) ), 13 );
00299 TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 0 , 1.5 , 1 ) ), 15 );
00300 TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 0.5, 1, 0 ) ), 4 );
00301
00302
00303 TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 0, 0, 0 ) ), 0 );
00304 }
00305
00306
00307
00308
00309 void testNeighboursInsideAGrid( void )
00310 {
00311 WGridRegular3D g( 3, 3, 3 );
00312 size_t data[] = { 12, 14, 10, 16, 4, 22 };
00313 std::vector< size_t > expected( data, data + 6 );
00314 TS_ASSERT_EQUALS( expected, g.getNeighbours( 13 ) );
00315 }
00316
00317
00318
00319
00320 void testRotatedVoxelNum()
00321 {
00322 WVector3d x( 0.707, 0.707, 0.0 );
00323 WVector3d y( -0.707, 0.707, 0.0 );
00324 WVector3d z( 0.0, 0.0, 1.0 );
00325 x = normalize( x );
00326 y = normalize( y );
00327 y *= 2.0;
00328 z *= 1.5;
00329
00330 WMatrix< double > mat( 4, 4 );
00331 mat.makeIdentity();
00332 mat( 0, 0 ) = x[ 0 ];
00333 mat( 1, 0 ) = x[ 1 ];
00334 mat( 2, 0 ) = x[ 2 ];
00335 mat( 0, 1 ) = y[ 0 ];
00336 mat( 1, 1 ) = y[ 1 ];
00337 mat( 2, 1 ) = y[ 2 ];
00338 mat( 0, 2 ) = z[ 0 ];
00339 mat( 1, 2 ) = z[ 1 ];
00340 mat( 2, 2 ) = z[ 2 ];
00341 mat( 0, 3 ) = 1.0;
00342
00343 WGridTransformOrtho t( mat );
00344 WGridRegular3D g( 5, 5, 5, t );
00345
00346 WVector3d v = WVector3d( 1.0, 0.0, 0.0 ) + 0.3 * z + 2.4 * y + 2.9 * x;
00347
00348 TS_ASSERT_EQUALS( g.getXVoxelCoord( v ), 3 );
00349 TS_ASSERT_EQUALS( g.getYVoxelCoord( v ), 2 );
00350 TS_ASSERT_EQUALS( g.getZVoxelCoord( v ), 0 );
00351 }
00352
00353
00354
00355
00356 void testRotatedVoxelOutOfGrid()
00357 {
00358 WVector3d x( 0.707, 0.707, 0.0 );
00359 WVector3d y( -0.707, 0.707, 0.0 );
00360 WVector3d z( 0.0, 0.0, 1.0 );
00361 x = normalize( x );
00362 y = normalize( y );
00363 y *= 2.0;
00364 z *= 1.5;
00365
00366 WMatrix< double > mat( 4, 4 );
00367 mat.makeIdentity();
00368 mat( 0, 0 ) = x[ 0 ];
00369 mat( 1, 0 ) = x[ 1 ];
00370 mat( 2, 0 ) = x[ 2 ];
00371 mat( 0, 1 ) = y[ 0 ];
00372 mat( 1, 1 ) = y[ 1 ];
00373 mat( 2, 1 ) = y[ 2 ];
00374 mat( 0, 2 ) = z[ 0 ];
00375 mat( 1, 2 ) = z[ 1 ];
00376 mat( 2, 2 ) = z[ 2 ];
00377 mat( 0, 3 ) = 1.0;
00378
00379 WGridTransformOrtho t( mat );
00380 WGridRegular3D g( 5, 5, 5, t );
00381
00382 WVector3d v( 1.0, 0.0, 0.0 );
00383 v -= wlimits::FLT_EPS * x;
00384
00385 TS_ASSERT_EQUALS( g.getXVoxelCoord( v ), -1 );
00386 TS_ASSERT_DIFFERS( g.getYVoxelCoord( v ), -1 );
00387 TS_ASSERT_DIFFERS( g.getZVoxelCoord( v ), -1 );
00388
00389 v -= wlimits::FLT_EPS * z;
00390
00391 TS_ASSERT_EQUALS( g.getXVoxelCoord( v ), -1 );
00392 TS_ASSERT_DIFFERS( g.getYVoxelCoord( v ), -1 );
00393 TS_ASSERT_EQUALS( g.getZVoxelCoord( v ), -1 );
00394
00395 v = WVector3d( 1.0, 0.0, 0.0 ) + ( 4.0 + wlimits::FLT_EPS ) * y;
00396
00397 TS_ASSERT_DIFFERS( g.getXVoxelCoord( v ), -1 );
00398 TS_ASSERT_EQUALS( g.getYVoxelCoord( v ), -1 );
00399 TS_ASSERT_DIFFERS( g.getZVoxelCoord( v ), -1 );
00400 }
00401
00402
00403
00404
00405 void testNeighboursOnFrontLowerLeft( void )
00406 {
00407 WGridRegular3D g( 3, 3, 3 );
00408 size_t data[] = { 1, 3, 9 };
00409 std::vector< size_t > expected( data, data + 3 );
00410 TS_ASSERT_EQUALS( expected, g.getNeighbours( 0 ) );
00411 }
00412
00413
00414
00415
00416 void testNeighbourOnBackUpperRight( void )
00417 {
00418 WGridRegular3D g( 3, 3, 3 );
00419 size_t data[] = { 25, 23, 17 };
00420 std::vector< size_t > expected( data, data + 3 );
00421 TS_ASSERT_EQUALS( expected, g.getNeighbours( 26 ) );
00422 }
00423
00424
00425
00426
00427
00428 void testNeighbourOnLeftBorderPlane( void )
00429 {
00430 WGridRegular3D g( 3, 3, 3 );
00431 size_t data[] = { 13, 9, 15, 3, 21 };
00432 std::vector< size_t > expected( data, data + 5 );
00433 TS_ASSERT_EQUALS( expected, g.getNeighbours( 12 ) );
00434 }
00435
00436
00437
00438
00439
00440 void testNeighbourOfVoxelNotInsideThisGrid( void )
00441 {
00442 WGridRegular3D g( 3, 3, 3 );
00443 TS_ASSERT_THROWS_EQUALS( g.getNeighbours( 27 ), const WOutOfBounds &e, std::string( e.what() ),
00444 "This point: 27 is not part of this grid: nbPosX: 3 nbPosY: 3 nbPosZ: 3" );
00445 }
00446
00447
00448
00449
00450 void testGetCellVertexIds( void )
00451 {
00452 WGridRegular3D g( 5, 3, 3 );
00453 size_t ids[] = { 23, 24, 28, 29, 38, 39, 43, 44 };
00454 std::vector< size_t > expected( ids, ids + 8 );
00455 TS_ASSERT_EQUALS( g.getCellVertexIds( 15 ), expected );
00456 }
00457
00458
00459
00460
00461 void testGetCellId( void )
00462 {
00463 WGridRegular3D g( 5, 3, 3 );
00464 bool isInside = true;
00465
00466
00467 size_t cellId = g.getCellId( WPosition( 3.3, 1.75, 0.78 ), &isInside );
00468 TS_ASSERT_EQUALS( cellId, 7 );
00469 TS_ASSERT_EQUALS( isInside, true );
00470
00471
00472 cellId = g.getCellId( WPosition( 4.0, 1.75, 0.3 ), &isInside );
00473 TS_ASSERT_EQUALS( isInside, false );
00474
00475 cellId = g.getCellId( WPosition( 4.0 - wlimits::FLT_EPS, 1.75, 0.3 ), &isInside );
00476 TS_ASSERT_EQUALS( isInside, true );
00477
00478 cellId = g.getCellId( WPosition( 0.0, 1.75, 0.3 ), &isInside );
00479 TS_ASSERT_EQUALS( isInside, true );
00480
00481 cellId = g.getCellId( WPosition( 0.0 - wlimits::FLT_EPS, 1.75, 0.3 ), &isInside );
00482 TS_ASSERT_EQUALS( isInside, false );
00483
00484
00485 cellId = g.getCellId( WPosition( 3.3, 2.0, 0.3 ), &isInside );
00486 TS_ASSERT_EQUALS( isInside, false );
00487
00488 cellId = g.getCellId( WPosition( 3.3, 2.0 - wlimits::FLT_EPS, 0.3 ), &isInside );
00489 TS_ASSERT_EQUALS( isInside, true );
00490
00491 cellId = g.getCellId( WPosition( 3.3, 0.0, 0.3 ), &isInside );
00492 TS_ASSERT_EQUALS( isInside, true );
00493
00494 cellId = g.getCellId( WPosition( 3.3, 0.0 - wlimits::FLT_EPS, 0.3 ), &isInside );
00495 TS_ASSERT_EQUALS( isInside, false );
00496
00497
00498 cellId = g.getCellId( WPosition( 3.3, 1.75, 2.0 ), &isInside );
00499 TS_ASSERT_EQUALS( isInside, false );
00500
00501 cellId = g.getCellId( WPosition( 3.3, 1.75, 2.0 - wlimits::FLT_EPS ), &isInside );
00502 TS_ASSERT_EQUALS( isInside, true );
00503
00504 cellId = g.getCellId( WPosition( 3.3, 1.75, 0.0 ), &isInside );
00505 TS_ASSERT_EQUALS( isInside, true );
00506
00507 cellId = g.getCellId( WPosition( 3.3, 1.75, 0.0 - wlimits::FLT_EPS ), &isInside );
00508 TS_ASSERT_EQUALS( isInside, false );
00509 }
00510
00511
00512
00513
00514 void testEnclosesQuery( void )
00515 {
00516 WGridRegular3D g( 2, 2, 2 );
00517
00518
00519 TS_ASSERT( !g.encloses( WPosition( 0 - wlimits::FLT_EPS, 0, 0 ) ) );
00520 TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) );
00521 TS_ASSERT( g.encloses( WPosition( 1.0 - wlimits::FLT_EPS, 0.5, 0.5 ) ) );
00522 TS_ASSERT( !g.encloses( WPosition( 1, 0.5, 0.5 ) ) );
00523
00524
00525 TS_ASSERT( !g.encloses( WPosition( 0, 0 - wlimits::FLT_EPS, 0 ) ) );
00526 TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) );
00527 TS_ASSERT( g.encloses( WPosition( 0.5, 1.0 - wlimits::FLT_EPS, 0.5 ) ) );
00528 TS_ASSERT( !g.encloses( WPosition( 0.5, 1.0, 0.5 ) ) );
00529
00530
00531 TS_ASSERT( !g.encloses( WPosition( 0, 0, 0 - wlimits::FLT_EPS ) ) );
00532 TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) );
00533 TS_ASSERT( g.encloses( WPosition( 0.5, 0.5, 1.0 - wlimits::FLT_EPS ) ) );
00534 TS_ASSERT( !g.encloses( WPosition( 0.5, 0.5, 1 ) ) );
00535 }
00536
00537
00538
00539
00540 void testEnclosesRotated()
00541 {
00542 WVector3d x( 0.707, 0.707, 0.0 );
00543 WVector3d y( -0.707, 0.707, 0.0 );
00544 WVector3d z( 0.0, 0.0, 1.0 );
00545 x = normalize( x );
00546 y = normalize( y );
00547 y *= 2.0;
00548 z *= 1.5;
00549
00550 WMatrix< double > mat( 4, 4 );
00551 mat.makeIdentity();
00552 mat( 0, 0 ) = x[ 0 ];
00553 mat( 1, 0 ) = x[ 1 ];
00554 mat( 2, 0 ) = x[ 2 ];
00555 mat( 0, 1 ) = y[ 0 ];
00556 mat( 1, 1 ) = y[ 1 ];
00557 mat( 2, 1 ) = y[ 2 ];
00558 mat( 0, 2 ) = z[ 0 ];
00559 mat( 1, 2 ) = z[ 1 ];
00560 mat( 2, 2 ) = z[ 2 ];
00561 mat( 0, 3 ) = 1.0;
00562
00563 WGridTransformOrtho t( mat );
00564 WGridRegular3D g( 5, 5, 5, t );
00565
00566 WVector3d o = WVector3d( 1.0, 0.0, 0.0 ) + ( x + y + z ) * 2.0 * wlimits::FLT_EPS;
00567 WVector3d v = o - 4.0 * wlimits::FLT_EPS * x;
00568 TS_ASSERT( !g.encloses( v ) );
00569 v = o;
00570 TS_ASSERT( g.encloses( v ) );
00571 v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * x;
00572 TS_ASSERT( g.encloses( v ) );
00573 v += 4.0 * wlimits::FLT_EPS * x;
00574 TS_ASSERT( !g.encloses( v ) );
00575
00576 v = o - 4.0 * wlimits::FLT_EPS * y;
00577 TS_ASSERT( !g.encloses( v ) );
00578 v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * y;
00579 TS_ASSERT( g.encloses( v ) );
00580 v += 4.0 * wlimits::FLT_EPS * y;
00581 TS_ASSERT( !g.encloses( v ) );
00582
00583 v = o - 4.0 * wlimits::FLT_EPS * z;
00584 TS_ASSERT( !g.encloses( v ) );
00585 v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * z;
00586 TS_ASSERT( g.encloses( v ) );
00587 v += 4.0 * wlimits::FLT_EPS * z;
00588 TS_ASSERT( !g.encloses( v ) );
00589 }
00590
00591 private:
00592 double m_delta;
00593 };
00594
00595 #endif // WGRIDREGULAR3D_TEST_H