OpenWalnut  1.5.0dev
WBresenham_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 WBRESENHAM_TEST_H
26 #define WBRESENHAM_TEST_H
27 
28 #include <memory>
29 #include <vector>
30 
31 #include <cxxtest/TestSuite.h>
32 
33 #include "../WBresenham.h"
34 #include "core/common/WLogger.h"
35 
36 /**
37  * Unit tests the Bresenham algorithm.
38  */
39 class WBresenhamTest : public CxxTest::TestSuite
40 {
41 public:
42  /**
43  * Creates a member variable with a WBresenham instance which you may use
44  * for testing.
45  */
46  void setUp( void )
47  {
49 
50  std::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 3, 3, 3 ) );
51  m_algo = std::shared_ptr< WBresenham >( new WBresenham( grid, false ) );
52  }
53 
54  /**
55  * Clean up after each test
56  */
57  void tearDown( void )
58  {
59  m_algo.reset();
60  }
61 
62  /**
63  * If a line segments starts and ends on the same point only its voxel
64  * should be selected.
65  */
67  {
68  WLine l;
69  l.push_back( WPosition( 0.5, 0.5, 0.5 ) );
70  l.push_back( WPosition( 0.5, 0.5, 0.5 ) );
71  m_algo->raster( l );
72  std::vector< double > expected( 27, 0.0 );
73  expected[13] = 1.0;
74  TS_ASSERT_EQUALS( m_algo->m_values, expected );
75  }
76 
77  /**
78  * Multiple segments in one voxel should also mark only this voxel.
79  */
81  {
82  WLine l;
83  l.push_back( WPosition( 0.5, 0.5, 0.5 ) );
84  l.push_back( WPosition( 0.6, 0.6, 0.6 ) );
85  l.push_back( WPosition( 0.7, 0.7, 0.7 ) );
86  m_algo->raster( l );
87  std::vector< double > expected( 27, 0.0 );
88  expected[13] = 1.0;
89  TS_ASSERT_EQUALS( m_algo->m_values, expected );
90  }
91 
92  /**
93  * Lines like WFibers consisting out of multiple line segements should
94  * be traced segment by segment.
95  */
96  void testPolyLineRastering( void )
97  {
98  WLine l;
99  l.push_back( WPosition( 0.4, 0.4, 0.4 ) );
100  l.push_back( WPosition( 0.6, 0.6, 0.6 ) );
101  l.push_back( WPosition( 1.7, 1.7, 1.7 ) );
102  m_algo->raster( l );
103  std::vector< double > expected( 27, 0.0 );
104  expected[0] = 1.0;
105  expected[13] = 1.0;
106  expected[26] = 1.0;
107  TS_ASSERT_EQUALS( m_algo->m_values, expected );
108  }
109 
110  /**
111  * Lines rastered in the 3rd Quadrant should also be traced.
112  */
114  {
115  WMatrix< double > mat( 4, 4 );
116  mat.makeIdentity();
117  mat( 0, 3 ) = -2.0;
118  mat( 1, 3 ) = -2.0;
119  mat( 2, 3 ) = -2.0;
120 
121  WGridTransformOrtho trans( mat );
122  std::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 3, 3, 3, trans ) );
123  m_algo = std::shared_ptr< WBresenham >( new WBresenham( grid, false ) );
124 
125  WLine l;
126  l.push_back( WPosition( -1.7, -1.7, -1.7 ) );
127  l.push_back( WPosition( -0.6, -0.6, -0.6 ) );
128  l.push_back( WPosition( -0.4, -0.4, -0.4 ) );
129  m_algo->raster( l );
130  std::vector< double > expected( 27, 0.0 );
131  expected[0] = 1.0;
132  expected[13] = 1.0;
133  expected[26] = 1.0;
134  TS_ASSERT_EQUALS( m_algo->m_values, expected );
135  }
136 
137  /**
138  * If you have a line from A to B then rastering it from B to should be
139  * equivalent.
140  */
141  void testSymmetry( void )
142  {
143  WLine l;
144  l.push_back( WPosition( 0.4, 0.4, 0.4 ) );
145  l.push_back( WPosition( 0.6, 0.6, 0.6 ) );
146  l.push_back( WPosition( 1.7, 1.7, 1.7 ) );
147  m_algo->raster( l );
148  std::vector< double > expected( 27, 0.0 );
149  expected[0] = 1.0;
150  expected[13] = 1.0;
151  expected[26] = 1.0;
152  TS_ASSERT_EQUALS( m_algo->m_values, expected );
153  m_algo->m_values[0] = m_algo->m_values[13] = m_algo->m_values[26] = 0.0; // reset the values array
154  l.clear();
155  l.push_back( WPosition( 1.7, 1.7, 1.7 ) );
156  l.push_back( WPosition( 0.6, 0.6, 0.6 ) );
157  l.push_back( WPosition( 0.4, 0.4, 0.4 ) );
158  m_algo->raster( l );
159  TS_ASSERT_EQUALS( m_algo->m_values, expected );
160  }
161 
162  /**
163  * Lines starting in a voxel A and ending in voxel B are rastered exactly
164  * the same way as all lines starting in A and ending in B as well as
165  * the line starting in the center of A and ending in the center of B.
166  */
168  {
169  WLine l;
170  l.push_back( WPosition( 0.49, 0.0, 0.0 ) );
171  l.push_back( WPosition( 1.49, 1.99, 0.0 ) );
172  m_algo->raster( l );
173  std::vector< double > expected( 27, 0.0 );
174  expected[0] = 1.0;
175  expected[3] = 1.0; // voxel three, since the midpoint may choose between 3 and 4
176  expected[7] = 1.0;
177  TS_ASSERT_EQUALS( m_algo->m_values, expected );
178 
179  // reset the algo
180  m_algo->m_values[0] = 0.0;
181  m_algo->m_values[3] = 0.0;
182  m_algo->m_values[7] = 0.0;
183 
184  WLine k;
185  // These two are supposed to be the voxel centers.
186  k.push_back( WPosition( 0.0, 0.0, 0.0 ) );
187  k.push_back( WPosition( 1.0, 2.0 - wlimits::DBL_EPS , 0.0 ) );
188  m_algo->raster( k );
189  TS_ASSERT_EQUALS( m_algo->m_values, expected );
190  }
191 private:
192  std::shared_ptr< WBresenham > m_algo; //!< test instace of the WBresenham algo
193 };
194 
195 #endif // WBRESENHAM_TEST_H
Unit tests the Bresenham algorithm.
void testExactLineIsRasteredTheSameWayAsMidpointLines(void)
Lines starting in a voxel A and ending in voxel B are rastered exactly the same way as all lines star...
void testPolyLineRastering(void)
Lines like WFibers consisting out of multiple line segements should be traced segment by segment.
void tearDown(void)
Clean up after each test.
std::shared_ptr< WBresenham > m_algo
test instace of the WBresenham algo
void testSymmetry(void)
If you have a line from A to B then rastering it from B to should be equivalent.
void testPolySegmentOneVoxelRastering(void)
Multiple segments in one voxel should also mark only this voxel.
void testLineSegementWithSameStartAndEndPoint(void)
If a line segments starts and ends on the same point only its voxel should be selected.
void setUp(void)
Creates a member variable with a WBresenham instance which you may use for testing.
void testRasteringIn3rdQuadrant(void)
Lines rastered in the 3rd Quadrant should also be traced.
Implements basic Bresenham algorithm for rasterization.
Definition: WBresenham.h:43
A grid that has parallelepiped cells which all have the same proportion.
Implements an orthogonal grid transformation.
A line is an ordered sequence of WPositions.
Definition: WLine.h:42
static void startup(std::ostream &output=std::cout, LogLevel level=LL_DEBUG)
Create the first and only instance of the logger as it is a singleton.
Definition: WLogger.cpp:41
WMatrix & makeIdentity()
Makes the matrix contain the identity matrix, i.e.
Definition: WMatrix.h:352
void push_back(const value_type &value)
Wrapper around std::vector member function.
Definition: WMixinVector.h:457
void clear()
Wrapper around std::vector member function.
Definition: WMixinVector.h:206
This only is a 3d double vector.
const double DBL_EPS
Smallest double such: 1.0 + DBL_EPS == 1.0 is still true.
Definition: WLimits.cpp:46