OpenWalnut  1.3.1
WGridRegular3D_test.h
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #ifndef WGRIDREGULAR3D_TEST_H
26 #define WGRIDREGULAR3D_TEST_H
27 
28 #include <cstdio>
29 #include <sstream>
30 #include <string>
31 #include <vector>
32 
33 #include <boost/shared_ptr.hpp>
34 
35 #include <cxxtest/TestSuite.h>
36 
37 #include "../../common/exceptions/WOutOfBounds.h"
38 #include "../../common/math/test/WVector3dTraits.h"
39 #include "../../common/WLimits.h"
40 #include "../WGridRegular3D.h"
41 
42 
43 /**
44  * Tests the WGridRegular3D class.
45  */
46 class WGridRegular3DTest : public CxxTest::TestSuite
47 {
48 public:
49  /**
50  * Called before every test.
51  */
52  void setUp( void )
53  {
54  m_delta = 1e-14;
55  }
56 
57  /**
58  * Ensure that nothing is thrown when an instance is created.
59  */
60  void testInstantiation( void )
61  {
62  TS_ASSERT_THROWS_NOTHING( WGridRegular3D grid( 3, 3, 3 ) );
63  }
64 
65  /**
66  * After instantiation there should be the requested number of positions.
67  */
68  void testSize( void )
69  {
70  WGridTransformOrtho t( WMatrix< double >( 4, 4 ).makeIdentity() );
71  WGridRegular3D grid( 3, 3, 3, t );
72  TS_ASSERT_EQUALS( grid.size(), 27 );
73  }
74 
75  /**
76  * Each convinience function just assembles the three values into an boost array.
77  */
79  {
80  boost::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 3, 3, 3 ) );
81  boost::array< unsigned int, 3 > expectedNbCoords = { { 3, 3, 3 } }; // NOLINT curly braces
82  TS_ASSERT_EQUALS( expectedNbCoords, getNbCoords< double >( grid ) );
83  boost::array< double, 3 > expectedOffsets = { { 1.0, 1.0, 1.0 } }; // NOLINT curly braces
84  TS_ASSERT_EQUALS( expectedOffsets, getOffsets< double >( grid ) );
85  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
86  TS_ASSERT_EQUALS( expectedDirections, getDirections< double >( grid ) );
87  TS_ASSERT_EQUALS( expectedDirections, getUnitDirections< double >( grid ) );
88  }
89 
90  /**
91  * After instantiation there should be the right vectors, matrix and origin.
92  */
93  void testOrientation( void )
94  {
95  WMatrix< double > mat( 4, 4 );
96  mat.makeIdentity();
97  mat( 0, 0 ) = 2.2;
98  mat( 1, 1 ) = 3.3;
99  mat( 2, 2 ) = 4.4;
100 
101  WGridTransformOrtho t( mat );
102  WGridRegular3D grid( 3, 3, 3, t );
103  TS_ASSERT_EQUALS( grid.size(), 27 );
104  TS_ASSERT_EQUALS( grid.getOrigin(), WPosition( 0., 0., 0. ) );
105  TS_ASSERT_EQUALS( grid.getDirectionX(), WVector3d( 2.2, 0., 0. ) );
106  TS_ASSERT_EQUALS( grid.getDirectionY(), WVector3d( 0., 3.3, 0. ) );
107  TS_ASSERT_EQUALS( grid.getDirectionZ(), WVector3d( 0., 0., 4.4 ) );
108  }
109 
110  /**
111  * getNbCoords should return the samples prescribed by the use of the constructor
112  */
113  void testGetNbCoords( void )
114  {
115  size_t x = 3;
116  size_t y = 4;
117  size_t z = 5;
118  WGridRegular3D grid( x, y, z );
119  TS_ASSERT_EQUALS( grid.getNbCoordsX(), x );
120  TS_ASSERT_EQUALS( grid.getNbCoordsY(), y );
121  TS_ASSERT_EQUALS( grid.getNbCoordsZ(), z );
122  }
123 
124  /**
125  * getOffset should return the vector offsets prescribed by the use of the
126  * constructor
127  */
128  void testGetVectorOffset( void )
129  {
130  WVector3d x( 3., 1., 2. );
131  WVector3d y( 2., -6., 0. );
132  WVector3d z( 12., 4., -20 );
133 
134  WMatrix< double > mat( 4, 4 );
135  mat.makeIdentity();
136  mat( 0, 0 ) = x[ 0 ];
137  mat( 1, 0 ) = x[ 1 ];
138  mat( 2, 0 ) = x[ 2 ];
139  mat( 0, 1 ) = y[ 0 ];
140  mat( 1, 1 ) = y[ 1 ];
141  mat( 2, 1 ) = y[ 2 ];
142  mat( 0, 2 ) = z[ 0 ];
143  mat( 1, 2 ) = z[ 1 ];
144  mat( 2, 2 ) = z[ 2 ];
145 
146  WGridTransformOrtho t( mat );
147  WGridRegular3D grid( 3, 3, 3, t );
148 
149  TS_ASSERT_DELTA( grid.getOffsetX(), length( x ), m_delta );
150  TS_ASSERT_DELTA( grid.getOffsetY(), length( y ), m_delta );
151  TS_ASSERT_DELTA( grid.getOffsetZ(), length( z ), m_delta );
152  }
153 
154  /**
155  * getPosition should return the correct position for scalar offsets
156  */
158  {
159  unsigned int nX = 10, nY = 11, nZ = 12;
160  unsigned int iX = 8, iY = 9, iZ = 5;
161  unsigned int i = iX + iY * nX + iZ * nX * nY;
162 
163  double orX = 1.2;
164  double orY = 3.4;
165  double orZ = 5.6;
166 
167  double ofX = 1.1;
168  double ofY = 2.2;
169  double ofZ = 3.3;
170 
171  double x = orX + iX * ofX;
172  double y = orY + iY * ofY;
173  double z = orZ + iZ * ofZ;
174 
175  WMatrix< double > mat( 4, 4 );
176  mat.makeIdentity();
177  mat( 0, 0 ) = ofX;
178  mat( 1, 1 ) = ofY;
179  mat( 2, 2 ) = ofZ;
180  mat( 0, 3 ) = orX;
181  mat( 1, 3 ) = orY;
182  mat( 2, 3 ) = orZ;
183 
184  WPosition expected( x, y, z );
185  WGridTransformOrtho t( mat );
186  WGridRegular3D grid( nX, nY, nZ, t );
187 
188  TS_ASSERT_DELTA( grid.getPosition( iX, iY, iZ )[0], expected[0], m_delta );
189  TS_ASSERT_DELTA( grid.getPosition( iX, iY, iZ )[1], expected[1], m_delta );
190  TS_ASSERT_DELTA( grid.getPosition( iX, iY, iZ )[2], expected[2], m_delta );
191  TS_ASSERT_DELTA( grid.getPosition( i )[0], expected[0], m_delta );
192  TS_ASSERT_DELTA( grid.getPosition( i )[1], expected[1], m_delta );
193  TS_ASSERT_DELTA( grid.getPosition( i )[2], expected[2], m_delta );
194  }
195 
196  /**
197  * The cell number of a Position is defined as follows:
198  *
199  \verbatim
200  y-axis
201  |_____ _____ ___ _
202  3 | | | |
203  | | | ... + dy
204  |_____|_____|___ _|
205  2 | | . Line
206  | |/ | ...
207  |_____/___ _|___
208  1 | /| |
209  | ' | | ...
210  |_____|_____|______ x-axis
211  /0 1 2
212  / `--.--´
213  / dx
214  origin e.g. ( 3.1, 3.2, -6 ) and dx == dy == 1.0 ( the z-axis is ignored in this example )
215  \endverbatim
216  *
217  * Hence the line starts at approx. ( 3.85, 3.7, -6 ) and ends at
218  * approx. ( 4.35, 5.0 , -6 ). The Cell number e.g. of the start point
219  * is then: 4 and of the end point: 7.
220  */
222  {
223  using boost::shared_ptr;
224 
225  WMatrix< double > mat( 4, 4 );
226  mat.makeIdentity();
227  mat( 0, 3 ) = 3.1;
228  mat( 1, 3 ) = 3.2;
229  mat( 2, 3 ) = -6.;
230 
231  WGridTransformOrtho t( mat );
232  shared_ptr< WGridRegular3D > g = shared_ptr< WGridRegular3D >( new WGridRegular3D( 3, 3, 3, t ) );
233  TS_ASSERT_EQUALS( g->getVoxelNum( WPosition( 4.35, 5.0, -6 ) ), 7 );
234  }
235 
236  /**
237  * If a grid point is outside of the grid then -1 should be returned.
238  */
240  {
241  using boost::shared_ptr;
242 
243  shared_ptr< WGridRegular3D > g = shared_ptr< WGridRegular3D >( new WGridRegular3D( 3, 3, 3 ) );
244  TS_ASSERT_EQUALS( g->getVoxelNum( WPosition( 0 - m_delta, 0, 0 ) ), -1 );
245  TS_ASSERT_EQUALS( g->getVoxelNum( WPosition( 0, 2 + m_delta, 0 ) ), -1 );
246  }
247 
248  /**
249  * All points of the surfaces belonging to the lower,left,front corner of a
250  * voxel belong to this voxel. Instead all points located on the three
251  * surfaces belonging to the upper right back corner are considered not to
252  * belong to this voxel.
253  */
255  {
256  // A voxel is defined as this ( a cuboid with a center which is a grid point ):
257  // ______________ ____ (0.5, 0.5, 0.5)
258  // /: /|
259  // / : / |
260  // / : / |
261  // / : / |
262  // _/____:_ ___ __/ |
263  // | : | |
264  // | : *<--|--------- grid point (0, 0, 0)
265  // | :........|....|__
266  // dz == 1| ´ | /
267  // | ´ | / dy == 1
268  // | ´ | /
269  // _|´____________|/__
270  // |<- dx == 1 ->|
271  // -0.5,-0.5,-0.5
272  //
273  // the grid is as follows
274  // ______________ ____ 2,2,2
275  // /: / /|
276  // / : /: / |
277  // /------+------/| |
278  // / :……/……:………/…|…|
279  // /____:_/___:__/ | |---- 2,2,1
280  // | : | : | |/|
281  // | : | : | | |
282  // | :.|...:..| /| |____ 2,2,0
283  // +------+------+´ |/
284  // | ' | | /---- 2,1,0
285  // | ' | | /
286  // |'_____|______|/____
287  // | | |
288  // 0,0,0 1,0,0 2,0,0
289 
290  WGridRegular3D g( 3, 3, 3 );
291 
292  // center point of the grid
293  TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 1, 1, 1 ) ), 13 );
294 
295  // front lower left corner of the last cell
296  TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 1.5, 1.5, 1.5 ) ), 26 );
297 
298  TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 1, 1, 0.5 ) ), 13 );
299  TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 0 , 1.5 , 1 ) ), 15 );
300  TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 0.5, 1, 0 ) ), 4 );
301 
302  // origin
303  TS_ASSERT_EQUALS( g.getVoxelNum( WPosition( 0, 0, 0 ) ), 0 );
304  }
305 
306  /**
307  * A voxel inside a grid (not located on a border) has 6 neighbours.
308  */
310  {
311  WGridRegular3D g( 3, 3, 3 );
312  size_t data[] = { 12, 14, 10, 16, 4, 22 };
313  std::vector< size_t > expected( data, data + 6 );
314  TS_ASSERT_EQUALS( expected, g.getNeighbours( 13 ) );
315  }
316 
317  /**
318  * The correct voxel numbers should be returned in a rotated grid.
319  */
321  {
322  WVector3d x( 0.707, 0.707, 0.0 );
323  WVector3d y( -0.707, 0.707, 0.0 );
324  WVector3d z( 0.0, 0.0, 1.0 );
325  x = normalize( x );
326  y = normalize( y );
327  y *= 2.0;
328  z *= 1.5;
329 
330  WMatrix< double > mat( 4, 4 );
331  mat.makeIdentity();
332  mat( 0, 0 ) = x[ 0 ];
333  mat( 1, 0 ) = x[ 1 ];
334  mat( 2, 0 ) = x[ 2 ];
335  mat( 0, 1 ) = y[ 0 ];
336  mat( 1, 1 ) = y[ 1 ];
337  mat( 2, 1 ) = y[ 2 ];
338  mat( 0, 2 ) = z[ 0 ];
339  mat( 1, 2 ) = z[ 1 ];
340  mat( 2, 2 ) = z[ 2 ];
341  mat( 0, 3 ) = 1.0;
342 
343  WGridTransformOrtho t( mat );
344  WGridRegular3D g( 5, 5, 5, t );
345 
346  WVector3d v = WVector3d( 1.0, 0.0, 0.0 ) + 0.3 * z + 2.4 * y + 2.9 * x;
347 
348  TS_ASSERT_EQUALS( g.getXVoxelCoord( v ), 3 );
349  TS_ASSERT_EQUALS( g.getYVoxelCoord( v ), 2 );
350  TS_ASSERT_EQUALS( g.getZVoxelCoord( v ), 0 );
351  }
352 
353  /**
354  * Positions outside of a rotated grid should return voxel positions of -1.
355  */
357  {
358  WVector3d x( 0.707, 0.707, 0.0 );
359  WVector3d y( -0.707, 0.707, 0.0 );
360  WVector3d z( 0.0, 0.0, 1.0 );
361  x = normalize( x );
362  y = normalize( y );
363  y *= 2.0;
364  z *= 1.5;
365 
366  WMatrix< double > mat( 4, 4 );
367  mat.makeIdentity();
368  mat( 0, 0 ) = x[ 0 ];
369  mat( 1, 0 ) = x[ 1 ];
370  mat( 2, 0 ) = x[ 2 ];
371  mat( 0, 1 ) = y[ 0 ];
372  mat( 1, 1 ) = y[ 1 ];
373  mat( 2, 1 ) = y[ 2 ];
374  mat( 0, 2 ) = z[ 0 ];
375  mat( 1, 2 ) = z[ 1 ];
376  mat( 2, 2 ) = z[ 2 ];
377  mat( 0, 3 ) = 1.0;
378 
379  WGridTransformOrtho t( mat );
380  WGridRegular3D g( 5, 5, 5, t );
381 
382  WVector3d v( 1.0, 0.0, 0.0 );
383  v -= wlimits::FLT_EPS * x;
384 
385  TS_ASSERT_EQUALS( g.getXVoxelCoord( v ), -1 );
386  TS_ASSERT_DIFFERS( g.getYVoxelCoord( v ), -1 );
387  TS_ASSERT_DIFFERS( g.getZVoxelCoord( v ), -1 );
388 
389  v -= wlimits::FLT_EPS * z;
390 
391  TS_ASSERT_EQUALS( g.getXVoxelCoord( v ), -1 );
392  TS_ASSERT_DIFFERS( g.getYVoxelCoord( v ), -1 );
393  TS_ASSERT_EQUALS( g.getZVoxelCoord( v ), -1 );
394 
395  v = WVector3d( 1.0, 0.0, 0.0 ) + ( 4.0 + wlimits::FLT_EPS ) * y;
396 
397  TS_ASSERT_DIFFERS( g.getXVoxelCoord( v ), -1 );
398  TS_ASSERT_EQUALS( g.getYVoxelCoord( v ), -1 );
399  TS_ASSERT_DIFFERS( g.getZVoxelCoord( v ), -1 );
400  }
401 
402  /**
403  * A voxel with voxel-coordinates 0,0,0 has only three neighbours: 1,0,0; 0,1,0 and 0,0,1.
404  */
406  {
407  WGridRegular3D g( 3, 3, 3 );
408  size_t data[] = { 1, 3, 9 };
409  std::vector< size_t > expected( data, data + 3 );
410  TS_ASSERT_EQUALS( expected, g.getNeighbours( 0 ) );
411  }
412 
413  /**
414  * A voxel in the back upper right corner should also have only 3 neighbours.
415  */
417  {
418  WGridRegular3D g( 3, 3, 3 );
419  size_t data[] = { 25, 23, 17 };
420  std::vector< size_t > expected( data, data + 3 );
421  TS_ASSERT_EQUALS( expected, g.getNeighbours( 26 ) );
422  }
423 
424  /**
425  * A Voxel on a border plane should have neighbours on the plane but not
426  * out side the grid.
427  */
429  {
430  WGridRegular3D g( 3, 3, 3 );
431  size_t data[] = { 13, 9, 15, 3, 21 };
432  std::vector< size_t > expected( data, data + 5 );
433  TS_ASSERT_EQUALS( expected, g.getNeighbours( 12 ) );
434  }
435 
436  /**
437  * If the neighbours of a voxel not inside this grid are requested an Exception
438  * WOutOfBounds should be thrown.
439  */
441  {
442  WGridRegular3D g( 3, 3, 3 );
443  TS_ASSERT_THROWS_EQUALS( g.getNeighbours( 27 ), const WOutOfBounds &e, std::string( e.what() ),
444  "This point: 27 is not part of this grid: nbPosX: 3 nbPosY: 3 nbPosZ: 3" );
445  }
446 
447  /**
448  * Check whether we get the right Ids.
449  */
450  void testGetCellVertexIds( void )
451  {
452  WGridRegular3D g( 5, 3, 3 );
453  WGridRegular3D::CellVertexArray expected = { { 23, 24, 28, 29, 38, 39, 43, 44 } };
454  TS_ASSERT_EQUALS( g.getCellVertexIds( 15 ), expected );
455  }
456 
457  /**
458  * Check whether we get the right cellId.
459  */
460  void testGetCellId( void )
461  {
462  WGridRegular3D g( 5, 3, 3 );
463  bool isInside = true;
464 
465  // Test some value
466  size_t cellId = g.getCellId( WPosition( 3.3, 1.75, 0.78 ), &isInside );
467  TS_ASSERT_EQUALS( cellId, 7 );
468  TS_ASSERT_EQUALS( isInside, true );
469 
470  // Test bounds for X direction
471  cellId = g.getCellId( WPosition( 4.0, 1.75, 0.3 ), &isInside );
472  TS_ASSERT_EQUALS( isInside, false );
473 
474  cellId = g.getCellId( WPosition( 4.0 - wlimits::FLT_EPS, 1.75, 0.3 ), &isInside );
475  TS_ASSERT_EQUALS( isInside, true );
476 
477  cellId = g.getCellId( WPosition( 0.0, 1.75, 0.3 ), &isInside );
478  TS_ASSERT_EQUALS( isInside, true );
479 
480  cellId = g.getCellId( WPosition( 0.0 - wlimits::FLT_EPS, 1.75, 0.3 ), &isInside );
481  TS_ASSERT_EQUALS( isInside, false );
482 
483  // Test bounds for Y direction
484  cellId = g.getCellId( WPosition( 3.3, 2.0, 0.3 ), &isInside );
485  TS_ASSERT_EQUALS( isInside, false );
486 
487  cellId = g.getCellId( WPosition( 3.3, 2.0 - wlimits::FLT_EPS, 0.3 ), &isInside );
488  TS_ASSERT_EQUALS( isInside, true );
489 
490  cellId = g.getCellId( WPosition( 3.3, 0.0, 0.3 ), &isInside );
491  TS_ASSERT_EQUALS( isInside, true );
492 
493  cellId = g.getCellId( WPosition( 3.3, 0.0 - wlimits::FLT_EPS, 0.3 ), &isInside );
494  TS_ASSERT_EQUALS( isInside, false );
495 
496  // Test bounds for Z direction
497  cellId = g.getCellId( WPosition( 3.3, 1.75, 2.0 ), &isInside );
498  TS_ASSERT_EQUALS( isInside, false );
499 
500  cellId = g.getCellId( WPosition( 3.3, 1.75, 2.0 - wlimits::FLT_EPS ), &isInside );
501  TS_ASSERT_EQUALS( isInside, true );
502 
503  cellId = g.getCellId( WPosition( 3.3, 1.75, 0.0 ), &isInside );
504  TS_ASSERT_EQUALS( isInside, true );
505 
506  cellId = g.getCellId( WPosition( 3.3, 1.75, 0.0 - wlimits::FLT_EPS ), &isInside );
507  TS_ASSERT_EQUALS( isInside, false );
508  }
509 
510  /**
511  * If a point is inside of the boundary of a grid encloses should return true, otherwise false.
512  */
513  void testEnclosesQuery( void )
514  {
515  WGridRegular3D g( 2, 2, 2 );
516 
517  // Test bounds for X direction
518  TS_ASSERT( !g.encloses( WPosition( 0 - wlimits::FLT_EPS, 0, 0 ) ) );
519  TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) );
520  TS_ASSERT( g.encloses( WPosition( 1.0 - wlimits::FLT_EPS, 0.5, 0.5 ) ) );
521  TS_ASSERT( !g.encloses( WPosition( 1, 0.5, 0.5 ) ) );
522 
523  // Test bounds for Y direction
524  TS_ASSERT( !g.encloses( WPosition( 0, 0 - wlimits::FLT_EPS, 0 ) ) );
525  TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) );
526  TS_ASSERT( g.encloses( WPosition( 0.5, 1.0 - wlimits::FLT_EPS, 0.5 ) ) );
527  TS_ASSERT( !g.encloses( WPosition( 0.5, 1.0, 0.5 ) ) );
528 
529  // Test bounds for Z direction
530  TS_ASSERT( !g.encloses( WPosition( 0, 0, 0 - wlimits::FLT_EPS ) ) );
531  TS_ASSERT( g.encloses( WPosition( 0, 0, 0 ) ) );
532  TS_ASSERT( g.encloses( WPosition( 0.5, 0.5, 1.0 - wlimits::FLT_EPS ) ) );
533  TS_ASSERT( !g.encloses( WPosition( 0.5, 0.5, 1 ) ) );
534  }
535 
536  /**
537  * If a point is inside of the boundary of a grid encloses should return true, otherwise false.
538  */
540  {
541  WVector3d x( 0.707, 0.707, 0.0 );
542  WVector3d y( -0.707, 0.707, 0.0 );
543  WVector3d z( 0.0, 0.0, 1.0 );
544  x = normalize( x );
545  y = normalize( y );
546  y *= 2.0;
547  z *= 1.5;
548 
549  WMatrix< double > mat( 4, 4 );
550  mat.makeIdentity();
551  mat( 0, 0 ) = x[ 0 ];
552  mat( 1, 0 ) = x[ 1 ];
553  mat( 2, 0 ) = x[ 2 ];
554  mat( 0, 1 ) = y[ 0 ];
555  mat( 1, 1 ) = y[ 1 ];
556  mat( 2, 1 ) = y[ 2 ];
557  mat( 0, 2 ) = z[ 0 ];
558  mat( 1, 2 ) = z[ 1 ];
559  mat( 2, 2 ) = z[ 2 ];
560  mat( 0, 3 ) = 1.0;
561 
562  WGridTransformOrtho t( mat );
563  WGridRegular3D g( 5, 5, 5, t );
564 
565  WVector3d o = WVector3d( 1.0, 0.0, 0.0 ) + ( x + y + z ) * 2.0 * wlimits::FLT_EPS;
566  WVector3d v = o - 4.0 * wlimits::FLT_EPS * x;
567  TS_ASSERT( !g.encloses( v ) );
568  v = o;
569  TS_ASSERT( g.encloses( v ) );
570  v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * x;
571  TS_ASSERT( g.encloses( v ) );
572  v += 4.0 * wlimits::FLT_EPS * x;
573  TS_ASSERT( !g.encloses( v ) );
574 
575  v = o - 4.0 * wlimits::FLT_EPS * y;
576  TS_ASSERT( !g.encloses( v ) );
577  v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * y;
578  TS_ASSERT( g.encloses( v ) );
579  v += 4.0 * wlimits::FLT_EPS * y;
580  TS_ASSERT( !g.encloses( v ) );
581 
582  v = o - 4.0 * wlimits::FLT_EPS * z;
583  TS_ASSERT( !g.encloses( v ) );
584  v = o + ( 4.0 - 4.0 * wlimits::FLT_EPS ) * z;
585  TS_ASSERT( g.encloses( v ) );
586  v += 4.0 * wlimits::FLT_EPS * z;
587  TS_ASSERT( !g.encloses( v ) );
588  }
589 
590 private:
591  double m_delta; //!< Maximum amount to values are allowed to differ.
592 };
593 
594 #endif // WGRIDREGULAR3D_TEST_H