00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef WLINE_TEST_H
00026 #define WLINE_TEST_H
00027
00028 #include <sstream>
00029 #include <string>
00030
00031 #include <cxxtest/TestSuite.h>
00032
00033 #include "../../exceptions/WOutOfBounds.h"
00034 #include "../../WLimits.h"
00035 #include "../WLine.h"
00036 #include "WLineTraits.h"
00037 #include "WPositionTraits.h"
00038
00039
00040
00041
00042 class WLineTest : public CxxTest::TestSuite
00043 {
00044 public:
00045
00046
00047
00048
00049
00050 void testEqualsDeltaDifferentLength( void )
00051 {
00052 WLine line;
00053 line.push_back( WPosition( 0, 0, 0 ) );
00054 line.push_back( WPosition( 1, 0, 0 ) );
00055 WLine other;
00056 other.push_back( WPosition( 0, 0, 0 ) );
00057 TS_ASSERT_EQUALS( equalsDelta( line, other, 0.0 ), 1 );
00058 }
00059
00060
00061
00062
00063
00064
00065 void testEqualsDeltaOnRealDifferentLines( void )
00066 {
00067 WLine line;
00068 line.push_back( WPosition( 0, 0, 0 ) );
00069 line.push_back( WPosition( 1, 0, 0 ) );
00070 WLine other;
00071 other.push_back( WPosition( 0, 0, 0 ) );
00072 other.push_back( WPosition( 1, 0, 0 + 2 * wlimits::DBL_EPS ) );
00073 TS_ASSERT_EQUALS( equalsDelta( line, other, wlimits::DBL_EPS ), 1 );
00074 }
00075
00076
00077
00078
00079
00080 void testEqualsDeltaOnDifferentLinesButWithinDelta( void )
00081 {
00082 WLine line;
00083 line.push_back( WPosition( 0, 0, 0 ) );
00084 line.push_back( WPosition( 1, 0, 0 ) );
00085 WLine other;
00086 other.push_back( WPosition( 0, 0, 0 ) );
00087 other.push_back( WPosition( 1, 0, 0 + 2 * wlimits::DBL_EPS ) );
00088 TS_ASSERT_EQUALS( equalsDelta( line, other, 2 * wlimits::DBL_EPS ), -1 );
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 void testOutputOperator( void )
00098 {
00099 WLine l;
00100 l.push_back( WPosition( 1.0, 1.0, 3.1415 ) );
00101 l.push_back( WPosition( 0.0, 0.0, 0.44 ) );
00102 l.push_back( WPosition( 1.0, 1.0, 1.0 ) );
00103 std::string expected( "[1.0000000000000000e+00;1.0000000000000000e+00;3.1415000000000002e+00;, "
00104 "0.0000000000000000e+00;0.0000000000000000e+00;4.4000000000000000e-01;, "
00105 "1.0000000000000000e+00;1.0000000000000000e+00;1.0000000000000000e+00;]" );
00106 std::stringstream ss;
00107 ss << l;
00108 TS_ASSERT_EQUALS( expected, ss.str() );
00109 }
00110
00111
00112
00113
00114 void testEqualityOperator( void )
00115 {
00116 WLine line1;
00117 line1.push_back( WPosition( 1.0, 1.0, 3.1415 ) );
00118 line1.push_back( WPosition( 0.0, 0.0, 0.44 ) );
00119 line1.push_back( WPosition( 1.0, 1.0, 1.0 ) );
00120 WLine line2;
00121 line2.push_back( WPosition( 1.0, 1.0, 3.1415 ) );
00122 line2.push_back( WPosition( 0.0, 0.0, 0.44 ) );
00123 line2.push_back( WPosition( 1.0, 1.0, 1.0 ) );
00124 TS_ASSERT_EQUALS( line1, line2 );
00125 line2.back()[1] += 0.0000000001;
00126 TS_ASSERT_DIFFERS( line1, line2 );
00127 }
00128
00129
00130
00131
00132
00133 void testAccessOperatorWithinValidBounds( void )
00134 {
00135 WLine line;
00136 line.push_back( WPosition( 1.0, 1.0, 3.1415 ) );
00137 line.push_back( WPosition( 0.0, 0.0, 0.44 ) );
00138 line.push_back( WPosition( 1.0, 1.0, 1.0 ) );
00139 WPosition expected( 1.0, 1.0, 1.0 );
00140 TS_ASSERT_EQUALS( expected, line[2] );
00141 }
00142
00143
00144
00145
00146
00147 void testReverseOrdering( void )
00148 {
00149 WLine line;
00150 line.push_back( WPosition( 1, 2, 3 ) );
00151 line.push_back( WPosition( 4, 5, 6 ) );
00152 line.push_back( WPosition( 7, 8, 9 ) );
00153 WLine expected;
00154 expected.push_back( WPosition( 7, 8, 9 ) );
00155 expected.push_back( WPosition( 4, 5, 6 ) );
00156 expected.push_back( WPosition( 1, 2, 3 ) );
00157 line.reverseOrder();
00158 TS_ASSERT_EQUALS( line, expected );
00159 }
00160
00161
00162
00163
00164
00165 void testPathLength( void )
00166 {
00167 WLine line;
00168 line.push_back( WPosition( 1, 2, 3 ) );
00169 line.push_back( WPosition( 4, 5, 6 ) );
00170 line.push_back( WPosition( 7, 8, 9 ) );
00171 double expected = length( WPosition( 1, 2, 3 ) - WPosition( 4, 5, 6 ) ) +
00172 length( WPosition( 4, 5, 6 ) - WPosition( 7, 8, 9 ) );
00173 TS_ASSERT_EQUALS( expected, pathLength( line ) );
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 void testDownSampleLine( void )
00183 {
00184 WLine line;
00185 line.push_back( WPosition( 0, 0, 0 ) );
00186 line.push_back( WPosition( 1, 1, 0 ) );
00187 line.push_back( WPosition( 2, 0, 0 ) );
00188 line.push_back( WPosition( 3, 1, 0 ) );
00189 line.resampleByNumberOfPoints( 3 );
00190 WLine expected;
00191 expected.push_back( WPosition( 0, 0, 0 ) );
00192 expected.push_back( WPosition( 1.5, 0.5, 0 ) );
00193 expected.push_back( WPosition( 3, 1, 0 ) );
00194 assert_equals_delta( line, expected, 2 * wlimits::DBL_EPS );
00195 }
00196
00197
00198
00199
00200
00201 void testSamplingWithSameNumberOfPoints( void )
00202 {
00203 WLine line;
00204 for( size_t i = 0; i < 10; ++i )
00205 {
00206 line.push_back( WPosition( i, 3 * i, 10 - i ) );
00207 }
00208 TS_ASSERT( line.size() == 10 );
00209 WLine expected( line );
00210 line.resampleByNumberOfPoints( 10 );
00211 assert_equals_delta( line, expected );
00212 }
00213
00214
00215
00216
00217 void testSamplingPointsAreExactlyInTheOldSegmentCenterAndCorners( void )
00218 {
00219 WLine line;
00220 WLine expected;
00221 for( int i = 0; i < 3; ++i )
00222 {
00223 line.push_back( WPosition( i, std::pow( -1.0, i % 2 ), 0 ) );
00224 expected.push_back( WPosition( i, std::pow( -1.0, i % 2 ), 0 ) );
00225 expected.push_back( WPosition( i + 0.5, 0, 0 ) );
00226 }
00227 expected.pop_back();
00228 line.resampleByNumberOfPoints( 5 );
00229 assert_equals_delta( expected, line );
00230 }
00231
00232
00233
00234
00235
00236 void testNumericalStabilityOfResampling( void )
00237 {
00238 WLine line;
00239 WLine expected;
00240 for( int i = 0; i < 100; ++i )
00241 {
00242 line.push_back( WPosition( i, std::pow( -1.0, i % 2 ), 0 ) );
00243 expected.push_back( WPosition( i, std::pow( -1.0, i % 2 ), 0 ) );
00244 expected.push_back( WPosition( i + 0.25, std::pow( -1.0, i % 2 ) * 0.5, 0 ) );
00245 expected.push_back( WPosition( i + 0.5, 0, 0 ) );
00246 expected.push_back( WPosition( i + 0.75, std::pow( -1.0, ( i + 1 ) % 2 ) * 0.5, 0 ) );
00247 }
00248 expected.pop_back();
00249 expected.pop_back();
00250 expected.pop_back();
00251 line.resampleByNumberOfPoints( 4 * 99 + 1 );
00252 assert_equals_delta( expected, line, 1.0e-10 * std::sqrt( 5.0 ) / 4 );
00253 }
00254
00255
00256
00257
00258 void testManySampelsInBetweenOfTwoOldPoints( void )
00259 {
00260 WLine line;
00261 line.push_back( WPosition( 0, 0, 0 ) );
00262 line.push_back( WPosition( 1, 1, 0 ) );
00263 line.resampleByNumberOfPoints( 1001 );
00264 WLine expected;
00265 expected.push_back( WPosition( 0, 0, 0 ) );
00266 for( size_t i = 1; i < 1001; ++i )
00267 {
00268 expected.push_back( WPosition( i / 1000.0, i / 1000.0, 0 ) );
00269 }
00270 assert_equals_delta( expected, line, 1.0 / 1001.0 * 1.0e-10 );
00271 }
00272
00273
00274
00275
00276
00277
00278 void testMidPointOnEvenSize( void )
00279 {
00280 WLine line;
00281 line.push_back( WPosition( 0, 0, 0 ) );
00282 line.push_back( WPosition( 1, 1, 0 ) );
00283 line.push_back( WPosition( 2, 0, 0 ) );
00284 line.push_back( WPosition( 3, 1, 0 ) );
00285 WPosition expected( 1, 1, 0 );
00286 TS_ASSERT_EQUALS( expected, WPosition( midPoint( line ) ) );
00287 }
00288
00289
00290
00291
00292 void testMidPointOnUnevenSize( void )
00293 {
00294 WLine line;
00295 line.push_back( WPosition( 0, 0, 0 ) );
00296 line.push_back( WPosition( 1, 1, 0 ) );
00297 line.push_back( WPosition( 2, 0, 0 ) );
00298 WPosition expected( 1, 1, 0 );
00299 TS_ASSERT_EQUALS( expected, WPosition( midPoint( line ) ) );
00300 }
00301
00302
00303
00304
00305
00306 void testMidPointOnEmptyLine( void )
00307 {
00308 WLine line;
00309 WPosition expected( 1, 1, 0 );
00310 TS_ASSERT_THROWS_EQUALS( midPoint( line ), WOutOfBounds &e, std::string( e.what() ), "There is no midpoint for an empty line." );
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320 void testMaxSegementLength( void )
00321 {
00322 WLine line;
00323 line.push_back( WPosition( 0, 0, 0 ) );
00324 line.push_back( WPosition( 1, 1, 0 ) );
00325 line.push_back( WPosition( 2, 0, 0 ) );
00326 TS_ASSERT_DELTA( maxSegmentLength( line ), std::sqrt( 2.0 ), wlimits::DBL_EPS );
00327 line.push_back( WPosition( 0, 0, 0 ) );
00328 TS_ASSERT_DELTA( maxSegmentLength( line ), 2.0, wlimits::DBL_EPS );
00329 }
00330
00331
00332
00333
00334 void testEmptyLineOnMaxSegementLength( void )
00335 {
00336 WLine line;
00337 TS_ASSERT_EQUALS( maxSegmentLength( line ), 0.0 );
00338 line.push_back( WPosition( 0, 3.1415, 0 ) );
00339 TS_ASSERT_EQUALS( maxSegmentLength( line ), 0.0 );
00340 }
00341
00342
00343
00344
00345 void testRemoveAdjacentDuplicates( void )
00346 {
00347 WLine line;
00348 line.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00349 line.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00350 line.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00351 line.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00352 line.push_back( WPosition( 0.0, 0.0, 0.0 ) );
00353 line.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00354 line.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00355 line.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00356 WLine expected;
00357 expected.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00358 expected.push_back( WPosition( 0.0, 0.0, 0.0 ) );
00359 expected.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00360 line.removeAdjacentDuplicates();
00361 assert_equals_delta( line, expected );
00362 }
00363
00364
00365
00366
00367 void testResamplingByNewSegmentLengthWithZeroLine( void )
00368 {
00369 WLine line;
00370 line.resampleBySegmentLength( 3.1415f );
00371 assert_equals_delta( line, WLine() );
00372 }
00373
00374
00375
00376
00377 void testResamplingByNewSegementLengthWithLineHavingJustOnePoint( void )
00378 {
00379 WLine line;
00380 line.push_back( WPosition( 0.1, 3.4, 34254.5 ) );
00381 WLine expected( line );
00382 line.resampleBySegmentLength( 3.1415f );
00383 assert_equals_delta( line, expected );
00384 }
00385
00386
00387
00388
00389
00390 void testResamplingByNewSegementLengthOldSegmentLengthBiggerAsNewSegmentLength( void )
00391 {
00392 WLine line;
00393 line.push_back( WPosition( 0.0, 0.0, 0.0 ) );
00394 line.push_back( WPosition( 1.1, 0.0, 0.0 ) );
00395 line.resampleBySegmentLength( 1.0 );
00396 WLine expected;
00397 expected.push_back( WPosition( 0.0, 0.0, 0.0 ) );
00398 expected.push_back( WPosition( 1.0, 0.0, 0.0 ) );
00399 assert_equals_delta( line, expected );
00400 }
00401
00402
00403
00404
00405
00406 void testResamplingByNewSegementLengthRemainderGreaterAsHalfOfNewSegmentLength( void )
00407 {
00408 WLine line;
00409 line.push_back( WPosition( 0.0, 0.0, 0.0 ) );
00410 line.push_back( WPosition( 1.1, 0.0, 0.0 ) );
00411 line.resampleBySegmentLength( 0.6 );
00412 WLine expected;
00413 expected.push_back( WPosition( 0.0, 0.0, 0.0 ) );
00414 expected.push_back( WPosition( 0.6, 0.0, 0.0 ) );
00415 expected.push_back( WPosition( 1.2, 0.0, 0.0 ) );
00416 assert_equals_delta( line, expected );
00417 }
00418
00419
00420
00421
00422
00423 void testResamplingByNewSegementLengthTravelingOutOfTheCircle( void )
00424 {
00425 WLine line;
00426 line.push_back( WPosition( 0.0, 0.0, 0.0 ) );
00427 line.push_back( WPosition( 1.0, 1.0, 0.0 ) );
00428 line.push_back( WPosition( 0.0, 1.0, 0.0 ) );
00429 line.push_back( WPosition( 1.0, 2.0, 0.0 ) );
00430 line.push_back( WPosition( 0.0, 2.0, 0.0 ) );
00431 line.push_back( WPosition( 1.0, 3.0, 0.0 ) );
00432 line.resampleBySegmentLength( 3.0 );
00433 WLine expected;
00434 expected.push_back( WPosition( 0.0, 0.0, 0.0 ) );
00435 expected.push_back( WPosition( 0.870829, 2.87083, 0.0 ) );
00436 assert_equals_delta( line, expected, 0.00001 );
00437 }
00438
00439 private:
00440
00441
00442
00443
00444
00445
00446
00447
00448 void assert_equals_delta( const WLine& first, const WLine& second, double delta = wlimits::DBL_EPS ) const
00449 {
00450 int diffPos = 0;
00451 if( ( diffPos = equalsDelta( first, second, delta ) ) != -1 )
00452 {
00453 using string_utils::operator<<;
00454 std::stringstream msg;
00455 msg << "Lines are different in at least point: " << diffPos;
00456 TS_FAIL( msg.str() );
00457 if( static_cast< int >( first.size() ) > diffPos && static_cast< int >( second.size() ) > diffPos )
00458 {
00459 std::cout << "first line at: " << diffPos << std::endl << first[diffPos] << std::endl;
00460 std::cout << "second line at: " << diffPos << std::endl << second[diffPos] << std::endl;
00461 }
00462 else
00463 {
00464 std::cout << "lines does not have the same number of points: first=" << first.size() << " second=" << second.size() << std::endl;
00465 }
00466 std::cout << "first line: " << std::endl << first << std::endl;
00467 std::cout << "second line: " << std::endl << second << std::endl;
00468 }
00469 }
00470 };
00471 #endif // WLINE_TEST_H