OpenWalnut
1.4.0
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 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 * Tests the WGridRegular3D class. 00045 */ 00046 class WGridRegular3DTest : public CxxTest::TestSuite 00047 { 00048 public: 00049 /** 00050 * Called before every test. 00051 */ 00052 void setUp( void ) 00053 { 00054 m_delta = 1e-14; 00055 } 00056 00057 /** 00058 * Ensure that nothing is thrown when an instance is created. 00059 */ 00060 void testInstantiation( void ) 00061 { 00062 TS_ASSERT_THROWS_NOTHING( WGridRegular3D grid( 3, 3, 3 ) ); 00063 } 00064 00065 /** 00066 * After instantiation there should be the requested number of positions. 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 * Each convinience function just assembles the three values into an boost array. 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 } }; // NOLINT curly braces 00082 TS_ASSERT_EQUALS( expectedNbCoords, getNbCoords< double >( grid ) ); 00083 boost::array< double, 3 > expectedOffsets = { { 1.0, 1.0, 1.0 } }; // NOLINT curly braces 00084 TS_ASSERT_EQUALS( expectedOffsets, getOffsets< double >( 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 ) } }; // NOLINT curly braces line length 00086 TS_ASSERT_EQUALS( expectedDirections, getDirections< double >( grid ) ); 00087 TS_ASSERT_EQUALS( expectedDirections, getUnitDirections< double >( grid ) ); 00088 } 00089 00090 /** 00091 * After instantiation there should be the right vectors, matrix and origin. 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 * getNbCoords should return the samples prescribed by the use of the constructor 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 * getOffset should return the vector offsets prescribed by the use of the 00126 * constructor 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 * getPosition should return the correct position for scalar offsets 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 * The cell number of a Position is defined as follows: 00198 * 00199 \verbatim 00200 y-axis 00201 |_____ _____ ___ _ 00202 3 | | | | 00203 | | | ... + dy 00204 |_____|_____|___ _| 00205 2 | | . Line 00206 | |/ | ... 00207 |_____/___ _|___ 00208 1 | /| | 00209 | ' | | ... 00210 |_____|_____|______ x-axis 00211 /0 1 2 00212 / `--.--´ 00213 / dx 00214 origin e.g. ( 3.1, 3.2, -6 ) and dx == dy == 1.0 ( the z-axis is ignored in this example ) 00215 \endverbatim 00216 * 00217 * Hence the line starts at approx. ( 3.85, 3.7, -6 ) and ends at 00218 * approx. ( 4.35, 5.0 , -6 ). The Cell number e.g. of the start point 00219 * is then: 4 and of the end point: 7. 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 * If a grid point is outside of the grid then -1 should be returned. 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 * All points of the surfaces belonging to the lower,left,front corner of a 00250 * voxel belong to this voxel. Instead all points located on the three 00251 * surfaces belonging to the upper right back corner are considered not to 00252 * belong to this voxel. 00253 */ 00254 void testGetVoxelNumberOfPositionExactlyBetweenVoxels( void ) 00255 { 00256 // A voxel is defined as this ( a cuboid with a center which is a grid point ): 00257 // ______________ ____ (0.5, 0.5, 0.5) 00258 // /: /| 00259 // / : / | 00260 // / : / | 00261 // / : / | 00262 // _/____:_ ___ __/ | 00263 // | : | | 00264 // | : *<--|--------- grid point (0, 0, 0) 00265 // | :........|....|__ 00266 // dz == 1| ´ | / 00267 // | ´ | / dy == 1 00268 // | ´ | / 00269 // _|´____________|/__ 00270 // |<- dx == 1 ->| 00271 // -0.5,-0.5,-0.5 00272 // 00273 // the grid is as follows 00274 // ______________ ____ 2,2,2 00275 // /: / /| 00276 // / : /: / | 00277 // /------+------/| | 00278 // / :……/……:………/…|…| 00279 // /____:_/___:__/ | |---- 2,2,1 00280 // | : | : | |/| 00281 // | : | : | | | 00282 // | :.|...:..| /| |____ 2,2,0 00283 // +------+------+´ |/ 00284 // | ' | | /---- 2,1,0 00285 // | ' | | / 00286 // |'_____|______|/____ 00287 // | | | 00288 // 0,0,0 1,0,0 2,0,0 00289 00290 WGridRegular3D g( 3, 3, 3 ); 00291 00292 // center point of the grid 00293 TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 1, 1, 1 ) ), 13 ); 00294 00295 // front lower left corner of the last cell 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 // origin 00303 TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 0, 0, 0 ) ), 0 ); 00304 } 00305 00306 /** 00307 * A voxel inside a grid (not located on a border) has 6 neighbours. 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 * The correct voxel numbers should be returned in a rotated grid. 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 * Positions outside of a rotated grid should return voxel positions of -1. 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 * A voxel with voxel-coordinates 0,0,0 has only three neighbours: 1,0,0; 0,1,0 and 0,0,1. 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 * A voxel in the back upper right corner should also have only 3 neighbours. 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 * A Voxel on a border plane should have neighbours on the plane but not 00426 * out side the grid. 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 * If the neighbours of a voxel not inside this grid are requested an Exception 00438 * WOutOfBounds should be thrown. 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 * Check whether we get the right Ids. 00449 */ 00450 void testGetCellVertexIds( void ) 00451 { 00452 WGridRegular3D g( 5, 3, 3 ); 00453 WGridRegular3D::CellVertexArray expected = { { 23, 24, 28, 29, 38, 39, 43, 44 } }; 00454 TS_ASSERT_EQUALS( g.getCellVertexIds( 15 ), expected ); 00455 } 00456 00457 /** 00458 * Check whether we get the right cellId. 00459 */ 00460 void testGetCellId( void ) 00461 { 00462 WGridRegular3D g( 5, 3, 3 ); 00463 bool isInside = true; 00464 00465 // Test some value 00466 size_t cellId = g.getCellId( WPosition( 3.3, 1.75, 0.78 ), &isInside ); 00467 TS_ASSERT_EQUALS( cellId, 7 ); 00468 TS_ASSERT_EQUALS( isInside, true ); 00469 00470 // Test bounds for X direction 00471 cellId = g.getCellId( WPosition( 4.0, 1.75, 0.3 ), &isInside ); 00472 TS_ASSERT_EQUALS( isInside, false ); 00473 00474 cellId = g.getCellId( WPosition( 4.0 - wlimits::FLT_EPS, 1.75, 0.3 ), &isInside ); 00475 TS_ASSERT_EQUALS( isInside, true ); 00476 00477 cellId = g.getCellId( WPosition( 0.0, 1.75, 0.3 ), &isInside ); 00478 TS_ASSERT_EQUALS( isInside, true ); 00479 00480 cellId = g.getCellId( WPosition( 0.0 - wlimits::FLT_EPS, 1.75, 0.3 ), &isInside ); 00481 TS_ASSERT_EQUALS( isInside, false ); 00482 00483 // Test bounds for Y direction 00484 cellId = g.getCellId( WPosition( 3.3, 2.0, 0.3 ), &isInside ); 00485 TS_ASSERT_EQUALS( isInside, false ); 00486 00487 cellId = g.getCellId( WPosition( 3.3, 2.0 - wlimits::FLT_EPS, 0.3 ), &isInside ); 00488 TS_ASSERT_EQUALS( isInside, true ); 00489 00490 cellId = g.getCellId( WPosition( 3.3, 0.0, 0.3 ), &isInside ); 00491 TS_ASSERT_EQUALS( isInside, true ); 00492 00493 cellId = g.getCellId( WPosition( 3.3, 0.0 - wlimits::FLT_EPS, 0.3 ), &isInside ); 00494 TS_ASSERT_EQUALS( isInside, false ); 00495 00496 // Test bounds for Z direction 00497 cellId = g.getCellId( WPosition( 3.3, 1.75, 2.0 ), &isInside ); 00498 TS_ASSERT_EQUALS( isInside, false ); 00499 00500 cellId = g.getCellId( WPosition( 3.3, 1.75, 2.0 - wlimits::FLT_EPS ), &isInside ); 00501 TS_ASSERT_EQUALS( isInside, true ); 00502 00503 cellId = g.getCellId( WPosition( 3.3, 1.75, 0.0 ), &isInside ); 00504 TS_ASSERT_EQUALS( isInside, true ); 00505 00506 cellId = g.getCellId( WPosition( 3.3, 1.75, 0.0 - wlimits::FLT_EPS ), &isInside ); 00507 TS_ASSERT_EQUALS( isInside, false ); 00508 } 00509 00510 /** 00511 * If a point is inside of the boundary of a grid encloses should return true, otherwise false. 00512 */ 00513 void testEnclosesQuery( void ) 00514 { 00515 WGridRegular3D g( 2, 2, 2 ); 00516 00517 // Test bounds for X direction 00518 TS_ASSERT( !g.encloses( WPosition( 0 - wlimits::FLT_EPS, 0, 0 ) ) ); 00519 TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) ); 00520 TS_ASSERT( g.encloses( WPosition( 1.0 - wlimits::FLT_EPS, 0.5, 0.5 ) ) ); 00521 TS_ASSERT( !g.encloses( WPosition( 1, 0.5, 0.5 ) ) ); 00522 00523 // Test bounds for Y direction 00524 TS_ASSERT( !g.encloses( WPosition( 0, 0 - wlimits::FLT_EPS, 0 ) ) ); 00525 TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) ); 00526 TS_ASSERT( g.encloses( WPosition( 0.5, 1.0 - wlimits::FLT_EPS, 0.5 ) ) ); 00527 TS_ASSERT( !g.encloses( WPosition( 0.5, 1.0, 0.5 ) ) ); 00528 00529 // Test bounds for Z direction 00530 TS_ASSERT( !g.encloses( WPosition( 0, 0, 0 - wlimits::FLT_EPS ) ) ); 00531 TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) ); 00532 TS_ASSERT( g.encloses( WPosition( 0.5, 0.5, 1.0 - wlimits::FLT_EPS ) ) ); 00533 TS_ASSERT( !g.encloses( WPosition( 0.5, 0.5, 1 ) ) ); 00534 } 00535 00536 /** 00537 * If a point is inside of the boundary of a grid encloses should return true, otherwise false. 00538 */ 00539 void testEnclosesRotated() 00540 { 00541 WVector3d x( 0.707, 0.707, 0.0 ); 00542 WVector3d y( -0.707, 0.707, 0.0 ); 00543 WVector3d z( 0.0, 0.0, 1.0 ); 00544 x = normalize( x ); 00545 y = normalize( y ); 00546 y *= 2.0; 00547 z *= 1.5; 00548 00549 WMatrix< double > mat( 4, 4 ); 00550 mat.makeIdentity(); 00551 mat( 0, 0 ) = x[ 0 ]; 00552 mat( 1, 0 ) = x[ 1 ]; 00553 mat( 2, 0 ) = x[ 2 ]; 00554 mat( 0, 1 ) = y[ 0 ]; 00555 mat( 1, 1 ) = y[ 1 ]; 00556 mat( 2, 1 ) = y[ 2 ]; 00557 mat( 0, 2 ) = z[ 0 ]; 00558 mat( 1, 2 ) = z[ 1 ]; 00559 mat( 2, 2 ) = z[ 2 ]; 00560 mat( 0, 3 ) = 1.0; 00561 00562 WGridTransformOrtho t( mat ); 00563 WGridRegular3D g( 5, 5, 5, t ); 00564 00565 WVector3d o = WVector3d( 1.0, 0.0, 0.0 ) + ( x + y + z ) * 2.0 * wlimits::FLT_EPS; 00566 WVector3d v = o - 4.0 * wlimits::FLT_EPS * x; 00567 TS_ASSERT( !g.encloses( v ) ); 00568 v = o; 00569 TS_ASSERT( g.encloses( v ) ); 00570 v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * x; 00571 TS_ASSERT( g.encloses( v ) ); 00572 v += 4.0 * wlimits::FLT_EPS * x; 00573 TS_ASSERT( !g.encloses( v ) ); 00574 00575 v = o - 4.0 * wlimits::FLT_EPS * y; 00576 TS_ASSERT( !g.encloses( v ) ); 00577 v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * y; 00578 TS_ASSERT( g.encloses( v ) ); 00579 v += 4.0 * wlimits::FLT_EPS * y; 00580 TS_ASSERT( !g.encloses( v ) ); 00581 00582 v = o - 4.0 * wlimits::FLT_EPS * z; 00583 TS_ASSERT( !g.encloses( v ) ); 00584 v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * z; 00585 TS_ASSERT( g.encloses( v ) ); 00586 v += 4.0 * wlimits::FLT_EPS * z; 00587 TS_ASSERT( !g.encloses( v ) ); 00588 } 00589 00590 private: 00591 double m_delta; //!< Maximum amount to values are allowed to differ. 00592 }; 00593 00594 #endif // WGRIDREGULAR3D_TEST_H