OpenWalnut  1.5.0dev
WMath_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 WMATH_TEST_H
26 #define WMATH_TEST_H
27 
28 #include <iomanip>
29 #include <memory>
30 
31 #include <cxxtest/TestSuite.h>
32 
33 #include "../../WLimits.h"
34 #include "../WMath.h"
35 #include "WPositionTraits.h"
36 
37 
38 /**
39  * Unit tests wmath's helper functions.
40  */
41 class WMathTest : public CxxTest::TestSuite
42 {
43 public:
44  /**
45  * If some points are inside the plane the triangle is considered to intersect with that plane.
46  */
48  {
49  WPlane p( WVector3d( 0, 0, 1 ), WPosition( 0, 0, 0 ) );
50  TS_ASSERT( testIntersectTriangle( WPosition( 0, 0, 0 ), WPosition( 0, 0, 1 ), WPosition( 1, 0, 1 ), p ) );
51  TS_ASSERT( testIntersectTriangle( WPosition( 0, 0, 0 ), WPosition( 0, 1, 0 ), WPosition( 1, 0, 1 ), p ) );
52  TS_ASSERT( testIntersectTriangle( WPosition( 0, 0, 0 ), WPosition( 0, 1, 0 ), WPosition( 1, 0, 0 ), p ) );
53  }
54 
55  /**
56  * If no point is in plane but at not all are on one side the trinagle intersects.
57  */
59  {
60  WPlane p( WVector3d( 0, 0, 1 ), WPosition( 0, 0, 0 ) );
61  TS_ASSERT( testIntersectTriangle( WPosition( 0, 0, -1 ), WPosition( 0, 0, 1 ), WPosition( 1, 0, 1 ), p ) );
62  }
63 
64  /**
65  * If all point are on one side of the plane no intersection can take place.
66  */
68  {
69  WPlane p( WVector3d( 0, 0, 1 ), WPosition( 0, 0, 0 ) );
70  TS_ASSERT( !testIntersectTriangle( WPosition( 0, 0, -1 ), WPosition( 0, 1, -1 ), WPosition( 1, 0, -3 ), p ) );
71  }
72 
73 
74  /**
75  * The intersection of a plane plane with a segment, having a starting and
76  * an endpoint. It should be a commutative operation in terms of staring
77  * and ending points.
78  */
80  {
81  WPlane p( WVector3d( 0, 0, 1 ), WPosition( 0, 0, 0 ) );
82  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
83  bool actual = intersectPlaneSegment( p, WPosition( 3, 0, 1 ), WPosition( 1, 0, -1 ), cutPoint );
84  TS_ASSERT_EQUALS( actual, true );
85  TS_ASSERT_EQUALS( *cutPoint, WPosition( 2, 0, 0 ) );
86  actual = intersectPlaneSegment( p, WPosition( 1, 0, -1 ), WPosition( 3, 0, 1 ), cutPoint );
87  TS_ASSERT_EQUALS( actual, true );
88  TS_ASSERT_EQUALS( *cutPoint, WPosition( 2, 0, 0 ) );
89  }
90 
91  /**
92  * If there is no intersection at all the position 0,0,0 should be written
93  * into the point of intersection and false should be returned.
94  */
96  {
97  WPlane p( WVector3d( 0, 0, 1 ), WPosition( 0, 0, 0 ) );
98  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
99  bool actual = intersectPlaneSegment( p,
100  WPosition( 3, 0, 10 * wlimits::DBL_EPS ),
101  WPosition( 10 * wlimits::DBL_EPS, 0, 10 * wlimits::DBL_EPS ), cutPoint );
102  TS_ASSERT_EQUALS( actual, false );
103  TS_ASSERT_EQUALS( *cutPoint, WPosition( 0, 0, 0 ) );
104  }
105 
106  /**
107  * If an endpoint is inside of the plane then a point of intersection
108  * must exists and true must be returned.
109  */
111  {
112  WPlane p( WVector3d( 0, 0, 1 ), WPosition( 0, 0, 0 ) );
113  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
114  bool actual = intersectPlaneSegment( p, WPosition( 3, 0, wlimits::DBL_EPS ), WPosition( 1, 0, 1 ), cutPoint );
115  TS_ASSERT_EQUALS( actual, true );
116  TS_ASSERT( std::abs( ( *cutPoint )[0] - 3.0 ) <= 2*wlimits::DBL_EPS );
117  TS_ASSERT( std::abs( ( *cutPoint )[1] - 0 ) <= 2*wlimits::DBL_EPS );
118  TS_ASSERT( std::abs( ( *cutPoint )[2] - 0 ) <= 2*wlimits::DBL_EPS );
119  actual = intersectPlaneSegment( p, WPosition( 1, 0, 1 ), WPosition( 3, 0, wlimits::DBL_EPS ), cutPoint );
120  TS_ASSERT_EQUALS( actual, true );
121  TS_ASSERT( std::abs( ( *cutPoint )[0] - 3.0 ) <= 2*wlimits::DBL_EPS );
122  TS_ASSERT( std::abs( ( *cutPoint )[1] - 0 ) <= 2*wlimits::DBL_EPS );
123  TS_ASSERT( std::abs( ( *cutPoint )[2] - 0 ) <= 2*wlimits::DBL_EPS );
124  }
125 
126  /**
127  * If the segment is totally inside of the plane, the first point must be
128  * returned which is actually one (of many intersecting points)
129  * intersecting point and true must be returned.
130  */
132  {
133  WPlane p( WVector3d( 0, 0, 1 ), WPosition( 0, 0, 0 ) );
134  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
135  bool actual = intersectPlaneSegment( p, WPosition( 3, 0, 0 ), WPosition( 1, 0, 0 ), cutPoint );
136  TS_ASSERT_EQUALS( actual, true );
137  TS_ASSERT_EQUALS( *cutPoint, WPosition( 3, 0, 0 ) );
138  actual = intersectPlaneSegment( p, WPosition( 1, 0, 0 ), WPosition( 3, 0, 0 ), cutPoint );
139  TS_ASSERT_EQUALS( actual, true );
140  TS_ASSERT_EQUALS( *cutPoint, WPosition( 1, 0, 0 ) );
141  }
142 
143  /**
144  * If a set of consecutive segements (aka line) is tested again
145  * intersection with that plane, each segment should be tested.
146  */
148  {
149  WLine l;
150  l.push_back( WPosition( -1, 0, 0 ) );
151  l.push_back( WPosition( 1, 0, 0 ) );
152  l.push_back( WPosition( 2, 0, 0 ) );
153  l.push_back( WPosition( 5, 0, 0 ) );
154  l.push_back( WPosition( 5, 4, 0 ) );
155  WPlane p( WVector3d( 1, 0, 0 ), WPosition( 3.5, 13, 23 ) );
156  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
157  bool actual = intersectPlaneLineNearCP( p, l, cutPoint );
158  TS_ASSERT( actual );
159  TS_ASSERT( std::abs( ( *cutPoint )[0] - 3.5 ) <= 2*wlimits::DBL_EPS );
160  TS_ASSERT( std::abs( ( *cutPoint )[1] - 0 ) <= 2*wlimits::DBL_EPS );
161  TS_ASSERT( std::abs( ( *cutPoint )[2] - 0 ) <= 2*wlimits::DBL_EPS );
162  }
163 
164  /**
165  * If none of the segments of the line intersects with the plane, false and
166  * 0,0,0 should be returned.
167  */
169  {
170  WLine l;
171  l.push_back( WPosition( -1, 0, 0 ) );
172  l.push_back( WPosition( 1, 0, 0 ) );
173  l.push_back( WPosition( 2, 0, 0 ) );
174  l.push_back( WPosition( 5, 0, 0 ) );
175  l.push_back( WPosition( 5, 4, 0 ) );
176  WPlane p( WVector3d( 1, 0, 0 ), WPosition( 5.0001, 13, 23 ) );
177  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
178  bool actual = intersectPlaneLineNearCP( p, l, cutPoint );
179  TS_ASSERT( !actual );
180  WPlane q( WVector3d( -1.1, 0, 0 ), WPosition( 5.0001, 13, 23 ) );
181  actual = intersectPlaneLineNearCP( q, l, cutPoint );
182  TS_ASSERT( !actual );
183  }
184 
185  /**
186  * If an endpoint of a line intersects with the plane, this point should be
187  * returned and ofcourse true.
188  */
190  {
191  WLine l;
192  l.push_back( WPosition( -1, 0, 0 ) );
193  l.push_back( WPosition( 1, 0, 0 ) );
194  l.push_back( WPosition( 2, 0, 0 ) );
195  l.push_back( WPosition( 5, 0, 0 ) );
196  l.push_back( WPosition( 5, 4, 0 ) );
197  WPlane p( WVector3d( 1, 0, 0 ), WPosition( -1, 13, 23 ) );
198  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
199  bool actual = intersectPlaneLineNearCP( p, l, cutPoint );
200  TS_ASSERT( actual );
201  TS_ASSERT( std::abs( ( *cutPoint )[0] - ( -1 ) ) <= 2*wlimits::DBL_EPS );
202  TS_ASSERT( std::abs( ( *cutPoint )[1] - 0 ) <= 2*wlimits::DBL_EPS );
203  TS_ASSERT( std::abs( ( *cutPoint )[2] - 0 ) <= 2*wlimits::DBL_EPS );
204  }
205 
206  /**
207  * If a whole segment of the line is insisde that plane the first point
208  * should be returned along with true as return code.
209  */
211  {
212  WLine l;
213  l.push_back( WPosition( -1, 0, 0 ) );
214  l.push_back( WPosition( 1, 0, 0 ) );
215  l.push_back( WPosition( 2, 0, 0 ) );
216  l.push_back( WPosition( 5, 0, 0 ) );
217  l.push_back( WPosition( 5, 4, 0 ) );
218  WPlane p( WVector3d( 1, 0, 0 ), WPosition( 5, 13, 23 ) );
219  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
220  bool actual = intersectPlaneLineNearCP( p, l, cutPoint );
221  TS_ASSERT( actual );
222  TS_ASSERT( std::abs( ( *cutPoint )[0] - 5 ) <= 2*wlimits::DBL_EPS );
223  TS_ASSERT( std::abs( ( *cutPoint )[1] - 0 ) <= 2*wlimits::DBL_EPS );
224  TS_ASSERT( std::abs( ( *cutPoint )[2] - 0 ) <= 2*wlimits::DBL_EPS );
225  }
226 
227  /**
228  * If many points of intersection occurs the closest to the base point
229  * should be selected and return true.
230  */
232  {
233  WLine l;
234  l.push_back( WPosition( -1, 0, 0 ) );
235  l.push_back( WPosition( 1, 0, 0 ) );
236  l.push_back( WPosition( 2, 1, 0 ) );
237  l.push_back( WPosition( -1, 1, 0 ) );
238  WPlane p( WVector3d( 1, 0, 0 ), WPosition( 0, 0, 0 ) );
239  std::shared_ptr< WPosition > cutPoint( new WPosition( 0, 0, 0 ) );
240  bool actual = intersectPlaneLineNearCP( p, l, cutPoint );
241  TS_ASSERT( actual );
242  TS_ASSERT( std::abs( ( *cutPoint )[0] - 0 ) <= 2*wlimits::DBL_EPS );
243  TS_ASSERT( std::abs( ( *cutPoint )[1] - 0 ) <= 2*wlimits::DBL_EPS );
244  TS_ASSERT( std::abs( ( *cutPoint )[2] - 0 ) <= 2*wlimits::DBL_EPS );
245  WPlane q( WVector3d( -1, 0, 0 ), WPosition( 0, 0.6, 0 ) );
246  actual = intersectPlaneLineNearCP( q, l, cutPoint );
247  TS_ASSERT( actual );
248  TS_ASSERT( std::abs( ( *cutPoint )[0] - 0 ) <= 2*wlimits::DBL_EPS );
249  TS_ASSERT( std::abs( ( *cutPoint )[1] - 1 ) <= 2*wlimits::DBL_EPS );
250  TS_ASSERT( std::abs( ( *cutPoint )[2] - 0 ) <= 2*wlimits::DBL_EPS );
251  }
252 
253  /**
254  * Test the factorial calculation.
255  */
256  void testFactorials( void )
257  {
258  // TODO(philips): add even and odd factorials
259  TS_ASSERT_EQUALS( factorial( 0 ), 1 );
260  TS_ASSERT_EQUALS( factorial( 1 ), 1 );
261  TS_ASSERT_EQUALS( factorial( 2 ), 2 );
262  TS_ASSERT_EQUALS( factorial( 3 ), 6 );
263  TS_ASSERT_EQUALS( factorial( 4 ), 24 );
264  TS_ASSERT_EQUALS( factorial( 5 ), 120 );
265  TS_ASSERT_EQUALS( factorial( 6 ), 720 );
266  TS_ASSERT_EQUALS( factorial( 7 ), 5040 );
267  TS_ASSERT_EQUALS( factorial( 8 ), 40320 );
268  }
269 
270  /**
271  * Test the areEqual function.
272  */
273  void testAreEqual( void )
274  {
275  TS_ASSERT_EQUALS( areEqual( 1.0, 1.0 ), true );
276  TS_ASSERT_EQUALS( areEqual( 1.0, 1.0, 1e-3 ), true );
277  TS_ASSERT_EQUALS( areEqual( 1.0, 1.0+1e-3, 1e-3 ), true );
278  TS_ASSERT_EQUALS( areEqual( 1.0, 1.0+2e-3, 1e-3 ), false );
279  TS_ASSERT_EQUALS( areEqual( 1.0, 1.0+1e-3 ), false );
280  }
281 };
282 
283 #endif // WMATH_TEST_H
A line is an ordered sequence of WPositions.
Definition: WLine.h:42
Unit tests wmath's helper functions.
Definition: WMath_test.h:42
void testIntersectionOfPlaneWithLine(void)
If a set of consecutive segements (aka line) is tested again intersection with that plane,...
Definition: WMath_test.h:147
void testTrianglePlaneIntersectionWithAllPointsOnOneSide(void)
If all point are on one side of the plane no intersection can take place.
Definition: WMath_test.h:67
void testTrianglePlaneIntersectionWithNoPointInPlane(void)
If no point is in plane but at not all are on one side the trinagle intersects.
Definition: WMath_test.h:58
void testMultipleIntersectionPlaneLine(void)
If many points of intersection occurs the closest to the base point should be selected and return tru...
Definition: WMath_test.h:231
void testNoIntersectionOfPlaneWithLine(void)
If none of the segments of the line intersects with the plane, false and 0,0,0 should be returned.
Definition: WMath_test.h:168
void testIntersectionOfPlaneWithSegmentHavingOnePointInPlane(void)
If an endpoint is inside of the plane then a point of intersection must exists and true must be retur...
Definition: WMath_test.h:110
void testTrianglePlaneIntersectionWithPointsInPlane(void)
If some points are inside the plane the triangle is considered to intersect with that plane.
Definition: WMath_test.h:47
void testFactorials(void)
Test the factorial calculation.
Definition: WMath_test.h:256
void testIntersectionPlaneLineWithSegmentInPlane(void)
If a whole segment of the line is insisde that plane the first point should be returned along with tr...
Definition: WMath_test.h:210
void testIntersectionOfPlaneWithSegment(void)
The intersection of a plane plane with a segment, having a starting and an endpoint.
Definition: WMath_test.h:79
void testAreEqual(void)
Test the areEqual function.
Definition: WMath_test.h:273
void testIntersectionPlaneLineWithJustOnePoint(void)
If an endpoint of a line intersects with the plane, this point should be returned and ofcourse true.
Definition: WMath_test.h:189
void testIntersectionOfPlaneWithSegmentInPlane(void)
If the segment is totally inside of the plane, the first point must be returned which is actually one...
Definition: WMath_test.h:131
void testNoIntersectionOfPlaneWithSegment(void)
If there is no intersection at all the position 0,0,0 should be written into the point of intersectio...
Definition: WMath_test.h:95
void push_back(const value_type &value)
Wrapper around std::vector member function.
Definition: WMixinVector.h:457
Represents a plane with a normal vector and a position in space.
Definition: WPlane.h:39
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