OpenWalnut  1.5.0dev
WBresenhamDBL_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 WBRESENHAMDBL_TEST_H
26 #define WBRESENHAMDBL_TEST_H
27 
28 #include <memory>
29 #include <vector>
30 
31 #include <cxxtest/TestSuite.h>
32 
33 #include "../WBresenhamDBL.h"
34 #include "core/common/WLogger.h"
35 
36 /**
37  * Unit tests the Bresenham algorithm.
38  */
39 class WBresenhamDBLTest : 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< WBresenhamDBL >( new WBresenhamDBL( 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 // TODO(math): This fails, but I decided not to improve the DBL algo, instead I write a new one with christians approach
111 // So either fix this or create a new one and discard this algorithm. The traceback of the error is in the err1 and err2
112 // variables: is must be err1 = dy2 -l - ( dx2 * yoffset ); etc.. but this makes new issues!
113 // /**
114 // * Lines rastered in the 3rd Quadrant should also be traced.
115 // */
116 // void testRasteringIn3rdQuadrant( void )
117 // {
118 // std::shared_ptr< WGridRegular3D > grid( new WGridRegular3D( 3, 3, 3, -2, -2, -2, 1, 1, 1 ) );
119 // m_algo = std::shared_ptr< WBresenhamDBL >( new WBresenhamDBL( grid, false ) );
120 //
121 // WLine l;
122 // l.push_back( WPosition( -1.7, -1.7, -1.7 ) );
123 // l.push_back( WPosition( -0.6, -0.6, -0.6 ) );
124 // l.push_back( WPosition( -0.4, -0.4, -0.4 ) );
125 // m_algo->raster( l );
126 // std::vector< double > expected( 27, 0.0 );
127 // expected[0] = 1.0;
128 // expected[13] = 1.0;
129 // expected[26] = 1.0;
130 // TS_ASSERT_EQUALS( m_algo->m_values, expected );
131 // }
132 
133  /**
134  * If you have a line from A to B then rastering it from B to should be
135  * equivalent.
136  */
137  void testSymmetry( void )
138  {
139  WLine l;
140  l.push_back( WPosition( 0.4, 0.4, 0.4 ) );
141  l.push_back( WPosition( 0.6, 0.6, 0.6 ) );
142  l.push_back( WPosition( 1.7, 1.7, 1.7 ) );
143  m_algo->raster( l );
144  std::vector< double > expected( 27, 0.0 );
145  expected[0] = 1.0;
146  expected[13] = 1.0;
147  expected[26] = 1.0;
148  TS_ASSERT_EQUALS( m_algo->m_values, expected );
149  m_algo->m_values[0] = m_algo->m_values[13] = m_algo->m_values[26] = 0.0; // reset the values array
150  l.clear();
151  l.push_back( WPosition( 1.7, 1.7, 1.7 ) );
152  l.push_back( WPosition( 0.6, 0.6, 0.6 ) );
153  l.push_back( WPosition( 0.4, 0.4, 0.4 ) );
154  m_algo->raster( l );
155  TS_ASSERT_EQUALS( m_algo->m_values, expected );
156  }
157 
158  /**
159  * Rasterization of exact lines must not match rasteriation of midpoint lines.
160  */
162  {
163  WLine l;
164  l.push_back( WPosition( 0.49, 0.0, 0.0 ) );
165  l.push_back( WPosition( 1.49, 1.51, 0.0 ) );
166  m_algo->raster( l );
167  std::vector< double > expected( 27, 0.0 );
168  expected[0] = 1.0;
169  expected[4] = 1.0; // voxel three, since the midpoint may choose between 3 and 4
170  expected[7] = 1.0;
171  TS_ASSERT_EQUALS( m_algo->m_values, expected );
172 
173  // reset the algo
174  m_algo->m_values[0] = m_algo->m_values[4] = m_algo->m_values[7] = 0.0;
175 
176  WLine k;
177  // These two points are supposed to be voxel centers
178  k.push_back( WPosition( 0.0, 0.0, 0.0 ) );
179  k.push_back( WPosition( 1.0, 2.0 - wlimits::DBL_EPS, 0.0 ) );
180  m_algo->raster( k );
181  expected[3] = 1.0;
182  expected[4] = 0.0;
183  TS_ASSERT_EQUALS( m_algo->m_values, expected );
184  }
185 
186 private:
187  std::shared_ptr< WBresenhamDBL > m_algo; //!< test instace of the WBresenham algo
188 };
189 
190 #endif // WBRESENHAMDBL_TEST_H
Unit tests the Bresenham algorithm.
void testLineSegementWithSameStartAndEndPoint(void)
If a line segments starts and ends on the same point only its voxel should be selected.
void tearDown(void)
Clean up after each test.
void testExactLineIsNotRasteredTheSameWayAsMidpointLines(void)
Rasterization of exact lines must not match rasteriation of midpoint lines.
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 testPolyLineRastering(void)
Lines like WFibers consisting out of multiple line segements should be traced segment by segment.
std::shared_ptr< WBresenhamDBL > m_algo
test instace of the WBresenham algo
void setUp(void)
Creates a member variable with a WBresenham instance which you may use for testing.
This is a modified version the Bresenham algorithm.
Definition: WBresenhamDBL.h:40
A grid that has parallelepiped cells which all have the same proportion.
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
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