source: src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.cpp@ 23c605

Last change on this file since 23c605 was 23c605, checked in by Frederik Heber <heber@…>, 11 years ago

SphericalPointDistribution is now working with bond degree weights.

  • recurseMatching() now works on IndexTupleList_t.
  • also rewrote calculatePairwiseDistances() and calculateErrorOfMatching().
  • L1THRESHOLD in recurseMatching() moved over to class body.
  • increased verbosity level of ...Matching() functions by one, added note on eventually chosen matching and why.
  • we assert that bestL2 is not too large.
  • FIX: calculateErrorOfMatching() did not use absolute value of gap for L1 error.
  • TESTS: Regresssion test FragmentMolecule-cycles working again.
  • Property mode set to 100644
File size: 52.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2014 Frederik Heber. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * SphericalPointDistributionUnitTest.cpp
25 *
26 * Created on: May 29, 2014
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35using namespace std;
36
37#include <cppunit/CompilerOutputter.h>
38#include <cppunit/extensions/TestFactoryRegistry.h>
39#include <cppunit/ui/text/TestRunner.h>
40
41// include headers that implement a archive in simple text format
42#include <boost/archive/text_oarchive.hpp>
43#include <boost/archive/text_iarchive.hpp>
44
45#include "SphericalPointDistributionUnitTest.hpp"
46
47#include <boost/assign.hpp>
48#include <boost/math/quaternion.hpp>
49
50#include "CodePatterns/Assert.hpp"
51#include "CodePatterns/Log.hpp"
52
53#include "LinearAlgebra/Line.hpp"
54
55#include "Fragmentation/Exporters/SphericalPointDistribution.hpp"
56
57#include "LinearAlgebra/Line.hpp"
58
59#ifdef HAVE_TESTRUNNER
60#include "UnitTestMain.hpp"
61#endif /*HAVE_TESTRUNNER*/
62
63using namespace boost::assign;
64
65/********************************************** Test classes **************************************/
66
67// Registers the fixture into the 'registry'
68CPPUNIT_TEST_SUITE_REGISTRATION( SphericalPointDistributionTest );
69
70
71void SphericalPointDistributionTest::setUp()
72{
73 // failing asserts should be thrown
74 ASSERT_DO(Assert::Throw);
75
76 setVerbosity(6);
77}
78
79
80void SphericalPointDistributionTest::tearDown()
81{
82}
83
84
85/** UnitTest for matchSphericalPointDistributions() with two points
86 */
87void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_2()
88{
89 SphericalPointDistribution SPD(1.);
90 // test with one point, matching trivially
91 {
92 SphericalPointDistribution::WeightedPolygon_t polygon;
93 polygon += std::make_pair(Vector(1.,0.,0.), 1);
94 SphericalPointDistribution::Polygon_t newpolygon =
95 SPD.get<2>();
96 SphericalPointDistribution::Polygon_t expected;
97 expected += Vector(-1.,0.,0.);
98 SphericalPointDistribution::Polygon_t remaining =
99 SphericalPointDistribution::matchSphericalPointDistributions(
100 polygon,
101 newpolygon);
102 CPPUNIT_ASSERT_EQUAL( expected, remaining );
103 }
104
105 // test with one point, just a flip of axis
106 {
107 SphericalPointDistribution::WeightedPolygon_t polygon;
108 polygon += std::make_pair( Vector(0.,1.,0.), 1);
109 SphericalPointDistribution::Polygon_t newpolygon =
110 SPD.get<2>();
111 SphericalPointDistribution::Polygon_t expected;
112 expected += Vector(0.,-1.,0.);
113 SphericalPointDistribution::Polygon_t remaining =
114 SphericalPointDistribution::matchSphericalPointDistributions(
115 polygon,
116 newpolygon);
117 CPPUNIT_ASSERT_EQUAL( expected, remaining );
118 }
119
120 // test with one point, just a flip to another axis
121 {
122 SphericalPointDistribution::WeightedPolygon_t polygon;
123 polygon += std::make_pair( Vector(0.,0.,-1.), 1);
124 SphericalPointDistribution::Polygon_t newpolygon =
125 SPD.get<2>();
126 SphericalPointDistribution::Polygon_t expected;
127 expected += Vector(0.,0.,1.);
128 SphericalPointDistribution::Polygon_t remaining =
129 SphericalPointDistribution::matchSphericalPointDistributions(
130 polygon,
131 newpolygon);
132 CPPUNIT_ASSERT_EQUAL( expected, remaining );
133 }
134
135 // test with one point, full rotation
136 {
137 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
138 SphericalPointDistribution::WeightedPolygon_t polygon;
139 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
140 SphericalPointDistribution::Polygon_t newpolygon =
141 SPD.get<2>();
142 SphericalPointDistribution::Polygon_t expected;
143 expected += RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI);
144 SphericalPointDistribution::Polygon_t remaining =
145 SphericalPointDistribution::matchSphericalPointDistributions(
146 polygon,
147 newpolygon);
148 CPPUNIT_ASSERT_EQUAL( expected, remaining );
149 }
150}
151
152void perturbPolygon(
153 SphericalPointDistribution::WeightedPolygon_t &_polygon,
154 double _amplitude
155 )
156{
157 for (SphericalPointDistribution::WeightedPolygon_t::iterator iter = _polygon.begin();
158 iter != _polygon.end(); ++iter) {
159 Vector perturber;
160 perturber.GetOneNormalVector(iter->first);
161 perturber.Scale(_amplitude);
162 iter->first = iter->first + perturber;
163 (iter->first).Normalize();
164 }
165}
166
167static
168bool areEqualToWithinBounds(
169 const SphericalPointDistribution::Polygon_t &_polygon,
170 const SphericalPointDistribution::Polygon_t &_otherpolygon,
171 double _amplitude
172 )
173{
174 // same size?
175 if (_polygon.size() != _otherpolygon.size())
176 return false;
177 // same points ? We just check witrh trivial mapping, nothing fancy ...
178 bool status = true;
179 SphericalPointDistribution::Polygon_t::const_iterator iter = _polygon.begin();
180 SphericalPointDistribution::Polygon_t::const_iterator otheriter = _otherpolygon.begin();
181 for (; iter != _polygon.end(); ++iter, ++otheriter) {
182 status &= (*iter - *otheriter).Norm() < _amplitude;
183 }
184 return status;
185}
186
187/** UnitTest for areEqualToWithinBounds()
188 */
189void SphericalPointDistributionTest::areEqualToWithinBoundsTest()
190{
191 // test with no points
192 {
193 SphericalPointDistribution::Polygon_t polygon;
194 SphericalPointDistribution::Polygon_t expected = polygon;
195 CPPUNIT_ASSERT( areEqualToWithinBounds(polygon, expected, std::numeric_limits<double>::epsilon()*1e2) );
196 }
197 // test with one point
198 {
199 SphericalPointDistribution::Polygon_t polygon;
200 polygon += Vector(1.,0.,0.);
201 SphericalPointDistribution::Polygon_t expected = polygon;
202 CPPUNIT_ASSERT( areEqualToWithinBounds(polygon, expected, std::numeric_limits<double>::epsilon()*1e2) );
203 }
204 // test with two points
205 {
206 SphericalPointDistribution::Polygon_t polygon;
207 polygon += Vector(1.,0.,0.);
208 polygon += Vector(0.,1.,0.);
209 SphericalPointDistribution::Polygon_t expected = polygon;
210 CPPUNIT_ASSERT( areEqualToWithinBounds(polygon, expected, std::numeric_limits<double>::epsilon()*1e2) );
211 }
212
213 // test with two points in different order: THIS GOES WRONG: We only check trivially
214 {
215 SphericalPointDistribution::Polygon_t polygon;
216 polygon += Vector(1.,0.,0.);
217 polygon += Vector(0.,1.,0.);
218 SphericalPointDistribution::Polygon_t expected;
219 expected += Vector(0.,1.,0.);
220 expected += Vector(1.,0.,0.);
221 CPPUNIT_ASSERT( !areEqualToWithinBounds(polygon, expected, std::numeric_limits<double>::epsilon()*1e2) );
222 }
223
224 // test with two different points
225 {
226 SphericalPointDistribution::Polygon_t polygon;
227 polygon += Vector(1.,0.,0.);
228 polygon += Vector(0.,1.,0.);
229 SphericalPointDistribution::Polygon_t expected;
230 expected += Vector(1.01,0.,0.);
231 expected += Vector(0.,1.,0.);
232 CPPUNIT_ASSERT( areEqualToWithinBounds(polygon, expected, 0.05) );
233 CPPUNIT_ASSERT( !areEqualToWithinBounds(polygon, expected, 0.005) );
234 }
235
236 // test with different number of points
237 {
238 SphericalPointDistribution::Polygon_t polygon;
239 polygon += Vector(1.,0.,0.);
240 polygon += Vector(0.,1.,0.);
241 SphericalPointDistribution::Polygon_t expected;
242 expected += Vector(0.,1.,0.);
243 CPPUNIT_ASSERT( !areEqualToWithinBounds(polygon, expected, 0.05) );
244 }
245}
246
247/** UnitTest for joinPoints()
248 */
249void SphericalPointDistributionTest::joinPointsTest()
250{
251 // test with simple configuration of three points
252 {
253 SphericalPointDistribution::Polygon_t newpolygon;
254 newpolygon += Vector(1.,0.,0.);
255 newpolygon += Vector(0.,1.,0.);
256 newpolygon += Vector(0.,0.,1.);
257 SphericalPointDistribution::Polygon_t expectedpolygon = newpolygon;
258 SphericalPointDistribution::IndexTupleList_t matching;
259 matching += SphericalPointDistribution::IndexList_t(1,0);
260 matching += SphericalPointDistribution::IndexList_t(1,1);
261 matching += SphericalPointDistribution::IndexList_t(1,2);
262 SphericalPointDistribution::IndexList_t IndexList =
263 SphericalPointDistribution::joinPoints(
264 newpolygon,
265 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
266 matching);
267 SphericalPointDistribution::IndexList_t expected;
268 expected += 0,1,2;
269 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
270 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
271 }
272
273 // test with simple configuration of three points, only two are picked
274 {
275 SphericalPointDistribution::Polygon_t newpolygon;
276 newpolygon += Vector(1.,0.,0.);
277 newpolygon += Vector(0.,1.,0.);
278 newpolygon += Vector(0.,0.,1.);
279 SphericalPointDistribution::Polygon_t expectedpolygon = newpolygon;
280 SphericalPointDistribution::IndexTupleList_t matching;
281 matching += SphericalPointDistribution::IndexList_t(1,1);
282 matching += SphericalPointDistribution::IndexList_t(1,2);
283 SphericalPointDistribution::IndexList_t IndexList =
284 SphericalPointDistribution::joinPoints(
285 newpolygon,
286 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
287 matching);
288 SphericalPointDistribution::IndexList_t expected;
289 expected += 1,2;
290 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
291 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
292 }
293
294 // test with simple configuration of three points, two are joined
295 {
296 SphericalPointDistribution::Polygon_t newpolygon;
297 newpolygon += Vector(1.,0.,0.);
298 newpolygon += Vector(0.,1.,0.);
299 newpolygon += Vector(0.,0.,1.);
300 SphericalPointDistribution::Polygon_t expectedpolygon;
301 expectedpolygon += Vector(1.,0.,0.);
302 expectedpolygon += Vector(0.,M_SQRT1_2,M_SQRT1_2);
303 SphericalPointDistribution::IndexTupleList_t matching;
304 SphericalPointDistribution::IndexList_t joined;
305 joined += 1,2;
306 matching += SphericalPointDistribution::IndexList_t(1,0);
307 matching += joined;
308 SphericalPointDistribution::IndexList_t IndexList =
309 SphericalPointDistribution::joinPoints(
310 newpolygon,
311 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
312 matching);
313 SphericalPointDistribution::IndexList_t expected;
314 expected += 0,1;
315 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
316 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
317 }
318
319 // test with simple configuration of six points, two are joined, jumbled indices
320 {
321 SphericalPointDistribution::Polygon_t newpolygon;
322 newpolygon += Vector(1.,0.,1.);
323 newpolygon += Vector(1.,0.,0.);
324 newpolygon += Vector(1.,1.,0.);
325 newpolygon += Vector(0.,1.,0.);
326 newpolygon += Vector(0.,0.,1.);
327 newpolygon += Vector(1.,0.,1.);
328 SphericalPointDistribution::Polygon_t expectedpolygon;
329 expectedpolygon += Vector(1.,0.,1.);
330 expectedpolygon += Vector(1.,0.,0.);
331 expectedpolygon += Vector(1.,1.,0.);
332 expectedpolygon += Vector(1.,0.,1.);
333 expectedpolygon += Vector(0.,M_SQRT1_2,M_SQRT1_2); // new centers go last
334 SphericalPointDistribution::IndexTupleList_t matching;
335 SphericalPointDistribution::IndexList_t joined;
336 joined += 3,4;
337 matching += SphericalPointDistribution::IndexList_t(1,1);
338 matching += joined;
339 SphericalPointDistribution::IndexList_t IndexList =
340 SphericalPointDistribution::joinPoints(
341 newpolygon,
342 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
343 matching);
344 SphericalPointDistribution::IndexList_t expected;
345 expected += 1,4;
346 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
347 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
348 }
349}
350
351/** UnitTest for matchSphericalPointDistributions() with three points
352 */
353void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_3()
354{
355 SphericalPointDistribution SPD(1.);
356
357 // test with one point, matching trivially
358 {
359 SphericalPointDistribution::WeightedPolygon_t polygon;
360 polygon += std::make_pair( Vector(1.,0.,0.), 1);
361 SphericalPointDistribution::Polygon_t newpolygon =
362 SPD.get<3>();
363 SphericalPointDistribution::Polygon_t expected = newpolygon;
364 expected.pop_front(); // remove first point
365 SphericalPointDistribution::Polygon_t remaining =
366 SphericalPointDistribution::matchSphericalPointDistributions(
367 polygon,
368 newpolygon);
369 CPPUNIT_ASSERT_EQUAL( expected, remaining );
370 }
371
372 // test with one point, just a flip of x and y axis
373 {
374 SphericalPointDistribution::WeightedPolygon_t polygon;
375 polygon += std::make_pair( Vector(0.,1.,0.), 1);
376 SphericalPointDistribution::Polygon_t newpolygon =
377 SPD.get<3>();
378 SphericalPointDistribution::Polygon_t expected = newpolygon;
379 expected.pop_front(); // remove first point
380 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
381 iter != expected.end(); ++iter) {
382 std::swap((*iter)[0], (*iter)[1]);
383 (*iter)[0] *= -1.;
384 }
385 SphericalPointDistribution::Polygon_t remaining =
386 SphericalPointDistribution::matchSphericalPointDistributions(
387 polygon,
388 newpolygon);
389 CPPUNIT_ASSERT_EQUAL( expected, remaining );
390 }
391
392 // test with two points, matching trivially
393 {
394 SphericalPointDistribution::WeightedPolygon_t polygon;
395 polygon += std::make_pair( Vector(1.,0.,0.), 1);
396 polygon += std::make_pair( Vector(-0.5, sqrt(3)*0.5,0.), 1);
397 SphericalPointDistribution::Polygon_t newpolygon =
398 SPD.get<3>();
399 SphericalPointDistribution::Polygon_t expected = newpolygon;
400 expected.pop_front(); // remove first point
401 expected.pop_front(); // remove second point
402 SphericalPointDistribution::Polygon_t remaining =
403 SphericalPointDistribution::matchSphericalPointDistributions(
404 polygon,
405 newpolygon);
406 CPPUNIT_ASSERT_EQUAL( expected, remaining );
407 // also slightly perturbed
408 const double amplitude = 0.05;
409 perturbPolygon(polygon, amplitude);
410 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
411 }
412
413 // test with two points, full rotation
414 {
415 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
416 SphericalPointDistribution::WeightedPolygon_t polygon;
417 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
418 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
419 SphericalPointDistribution::Polygon_t newpolygon =
420 SPD.get<3>();
421 SphericalPointDistribution::Polygon_t expected = newpolygon;
422 expected.pop_front(); // remove first point
423 expected.pop_front(); // remove second point
424 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
425 iter != expected.end(); ++iter)
426 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
427 SphericalPointDistribution::Polygon_t remaining =
428 SphericalPointDistribution::matchSphericalPointDistributions(
429 polygon,
430 newpolygon);
431 CPPUNIT_ASSERT_EQUAL( expected, remaining );
432 // also slightly perturbed
433 const double amplitude = 0.05;
434 perturbPolygon(polygon, amplitude);
435 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
436 }
437
438 // test with three points, matching trivially
439 {
440 SphericalPointDistribution::WeightedPolygon_t polygon;
441 polygon += std::make_pair( Vector(1.,0.,0.), 1);
442 polygon += std::make_pair( Vector(-0.5, sqrt(3)*0.5,0.), 1);
443 polygon += std::make_pair( Vector(-0.5, -sqrt(3)*0.5,0.), 1);
444 SphericalPointDistribution::Polygon_t newpolygon =
445 SPD.get<3>();
446 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
447 SphericalPointDistribution::Polygon_t remaining =
448 SphericalPointDistribution::matchSphericalPointDistributions(
449 polygon,
450 newpolygon);
451 CPPUNIT_ASSERT_EQUAL( expected, remaining );
452 // also slightly perturbed
453 const double amplitude = 0.05;
454 perturbPolygon(polygon, amplitude);
455 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
456 }
457
458
459 // test with three points, full rotation
460 {
461 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
462 SphericalPointDistribution::WeightedPolygon_t polygon;
463 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
464 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
465 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, -sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
466 SphericalPointDistribution::Polygon_t newpolygon =
467 SPD.get<3>();
468 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
469 SphericalPointDistribution::Polygon_t remaining =
470 SphericalPointDistribution::matchSphericalPointDistributions(
471 polygon,
472 newpolygon);
473 CPPUNIT_ASSERT_EQUAL( expected, remaining );
474 // also slightly perturbed
475 const double amplitude = 0.05;
476 perturbPolygon(polygon, amplitude);
477 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
478 }
479}
480
481/** UnitTest for matchSphericalPointDistributions() with four points
482 */
483void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_4()
484{
485 SphericalPointDistribution SPD(1.);
486
487 // test with one point, matching trivially
488 {
489 SphericalPointDistribution::WeightedPolygon_t polygon;
490 polygon += std::make_pair( Vector(1.,0.,0.), 1);
491 SphericalPointDistribution::Polygon_t newpolygon =
492 SPD.get<4>();
493 SphericalPointDistribution::Polygon_t expected = newpolygon;
494 expected.pop_front(); // remove first point
495 SphericalPointDistribution::Polygon_t remaining =
496 SphericalPointDistribution::matchSphericalPointDistributions(
497 polygon,
498 newpolygon);
499 CPPUNIT_ASSERT_EQUAL( expected, remaining );
500 }
501
502 // test with one point, just a flip of axis
503 {
504 SphericalPointDistribution::WeightedPolygon_t polygon;
505 polygon += std::make_pair( Vector(0.,1.,0.), 1);
506 SphericalPointDistribution::Polygon_t newpolygon =
507 SPD.get<4>();
508 SphericalPointDistribution::Polygon_t expected = newpolygon;
509 expected.pop_front(); // remove first point
510 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
511 iter != expected.end(); ++iter) {
512 std::swap((*iter)[0], (*iter)[1]);
513 (*iter)[0] *= -1.;
514 }
515 SphericalPointDistribution::Polygon_t remaining =
516 SphericalPointDistribution::matchSphericalPointDistributions(
517 polygon,
518 newpolygon);
519 CPPUNIT_ASSERT_EQUAL( expected, remaining );
520 }
521
522 // test with two points, matching trivially
523 {
524 SphericalPointDistribution::WeightedPolygon_t polygon;
525 polygon += std::make_pair( Vector(1.,0.,0.), 1);
526 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
527 SphericalPointDistribution::Polygon_t newpolygon =
528 SPD.get<4>();
529 SphericalPointDistribution::Polygon_t expected = newpolygon;
530 expected.pop_front(); // remove first point
531 expected.pop_front(); // remove second point
532 SphericalPointDistribution::Polygon_t remaining =
533 SphericalPointDistribution::matchSphericalPointDistributions(
534 polygon,
535 newpolygon);
536 CPPUNIT_ASSERT_EQUAL( expected, remaining );
537 // also slightly perturbed
538 const double amplitude = 0.05;
539 perturbPolygon(polygon, amplitude);
540 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
541 }
542
543 // test with two points, matching trivially, also with slightly perturbed
544 {
545 SphericalPointDistribution::WeightedPolygon_t polygon;
546 polygon += std::make_pair( Vector(1.,0.,0.), 1);
547 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
548 SphericalPointDistribution::Polygon_t newpolygon =
549 SPD.get<4>();
550 SphericalPointDistribution::Polygon_t expected = newpolygon;
551 expected.pop_front(); // remove first point
552 expected.pop_front(); // remove second point
553 SphericalPointDistribution::Polygon_t remaining =
554 SphericalPointDistribution::matchSphericalPointDistributions(
555 polygon,
556 newpolygon);
557 CPPUNIT_ASSERT_EQUAL( expected, remaining );
558 // also slightly perturbed
559 const double amplitude = 0.05;
560 perturbPolygon(polygon, amplitude);
561 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
562 }
563
564 // test with two points, full rotation
565 {
566 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
567 SphericalPointDistribution::WeightedPolygon_t polygon;
568 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
569 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 47.6/180*M_PI), 1);
570 SphericalPointDistribution::Polygon_t newpolygon =
571 SPD.get<4>();
572 SphericalPointDistribution::Polygon_t expected = newpolygon;
573 expected.pop_front(); // remove first point
574 expected.pop_front(); // remove second point
575 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
576 iter != expected.end(); ++iter)
577 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
578 SphericalPointDistribution::Polygon_t remaining =
579 SphericalPointDistribution::matchSphericalPointDistributions(
580 polygon,
581 newpolygon);
582 CPPUNIT_ASSERT_EQUAL( expected, remaining );
583 // also slightly perturbed
584 const double amplitude = 0.05;
585 perturbPolygon(polygon, amplitude);
586 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
587 }
588
589 // test with three points, matching trivially
590 {
591 SphericalPointDistribution::WeightedPolygon_t polygon;
592 polygon += std::make_pair( Vector(1.,0.,0.), 1);
593 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
594 polygon += std::make_pair( Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 1);
595 SphericalPointDistribution::Polygon_t newpolygon =
596 SPD.get<4>();
597 SphericalPointDistribution::Polygon_t expected = newpolygon;
598 expected.pop_front(); // remove first point
599 expected.pop_front(); // remove second point
600 expected.pop_front(); // remove third point
601 SphericalPointDistribution::Polygon_t remaining =
602 SphericalPointDistribution::matchSphericalPointDistributions(
603 polygon,
604 newpolygon);
605 CPPUNIT_ASSERT_EQUAL( expected, remaining );
606 // also slightly perturbed
607 const double amplitude = 0.05;
608 perturbPolygon(polygon, amplitude);
609 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
610 }
611
612 // test with three points, full rotation
613 {
614 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
615 SphericalPointDistribution::WeightedPolygon_t polygon;
616 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
617 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 47.6/180*M_PI), 1);
618 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 47.6/180*M_PI), 1);
619 SphericalPointDistribution::Polygon_t newpolygon =
620 SPD.get<4>();
621 SphericalPointDistribution::Polygon_t expected = newpolygon;
622 expected.pop_front(); // remove first point
623 expected.pop_front(); // remove second point
624 expected.pop_front(); // remove third point
625 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
626 iter != expected.end(); ++iter)
627 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
628 SphericalPointDistribution::Polygon_t remaining =
629 SphericalPointDistribution::matchSphericalPointDistributions(
630 polygon,
631 newpolygon);
632 CPPUNIT_ASSERT_EQUAL( expected, remaining );
633 // also slightly perturbed
634 const double amplitude = 0.05;
635 perturbPolygon(polygon, amplitude);
636 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
637 }
638}
639
640/** UnitTest for matchSphericalPointDistributions() with four points and weights
641 * not all equal to one.
642 */
643void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_multiple()
644{
645 SphericalPointDistribution SPD(1.);
646
647 // test with four points: one point having weight of two
648 {
649 SphericalPointDistribution::WeightedPolygon_t polygon;
650 polygon += std::make_pair( Vector(1.,0.,0.), 2);
651 SphericalPointDistribution::Polygon_t newpolygon =
652 SPD.get<4>();
653 SphericalPointDistribution::Polygon_t expected;
654 expected += Vector(-0.5773502691896,-5.551115123126e-17,0.8164965809277);
655 expected += Vector(-0.5773502691896,-5.551115123126e-17,-0.8164965809277);
656 SphericalPointDistribution::Polygon_t remaining =
657 SphericalPointDistribution::matchSphericalPointDistributions(
658 polygon,
659 newpolygon);
660// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
661 CPPUNIT_ASSERT_EQUAL( expected, remaining );
662 }
663
664 // test with five points: one point having weight of two
665 {
666 SphericalPointDistribution::WeightedPolygon_t polygon;
667 polygon += std::make_pair( Vector(1.,0.,0.), 2);
668 SphericalPointDistribution::Polygon_t newpolygon =
669 SPD.get<5>();
670 SphericalPointDistribution::Polygon_t expected;
671 expected += Vector(-0.7071067811865,0.7071067811865,0);
672 expected += Vector(-0.3535533905933,-0.3535533905933,0.8660254037844);
673 expected += Vector(-0.3535533905933,-0.3535533905933,-0.8660254037844);
674 SphericalPointDistribution::Polygon_t remaining =
675 SphericalPointDistribution::matchSphericalPointDistributions(
676 polygon,
677 newpolygon);
678// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
679 CPPUNIT_ASSERT_EQUAL( expected, remaining );
680 }
681
682
683 // test with five points: one point having weight of two, one weight of one
684 {
685 SphericalPointDistribution::WeightedPolygon_t polygon;
686 polygon += std::make_pair( Vector(M_SQRT1_2,M_SQRT1_2,0.), 2);
687 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
688 SphericalPointDistribution::Polygon_t newpolygon =
689 SPD.get<5>();
690 SphericalPointDistribution::Polygon_t expected;
691 expected += Vector(0.3535533786708,-0.3535533955317,-0.8660254066357);
692 expected += Vector(0.3535534025157,-0.3535533856548,0.8660254009332);
693 SphericalPointDistribution::Polygon_t remaining =
694 SphericalPointDistribution::matchSphericalPointDistributions(
695 polygon,
696 newpolygon);
697// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
698 CPPUNIT_ASSERT_EQUAL( expected, remaining );
699 }
700
701 // test with six points: two points each having weight of two
702 {
703 SphericalPointDistribution::WeightedPolygon_t polygon;
704 polygon += std::make_pair( Vector(M_SQRT1_2,-M_SQRT1_2,0.), 2);
705 polygon += std::make_pair( Vector(-M_SQRT1_2,M_SQRT1_2,0.), 2);
706 SphericalPointDistribution::Polygon_t newpolygon =
707 SPD.get<6>();
708 SphericalPointDistribution::Polygon_t expected;
709 expected += Vector(0.,0.,-1.);
710 expected += Vector(0.,0.,1.);
711 SphericalPointDistribution::Polygon_t remaining =
712 SphericalPointDistribution::matchSphericalPointDistributions(
713 polygon,
714 newpolygon);
715// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
716 CPPUNIT_ASSERT_EQUAL( expected, remaining );
717 }
718}
719
720/** UnitTest for matchSphericalPointDistributions() with five points
721 */
722void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_5()
723{
724 SphericalPointDistribution SPD(1.);
725
726 // test with one point, matching trivially
727 {
728 SphericalPointDistribution::WeightedPolygon_t polygon;
729 polygon += std::make_pair( Vector(1.,0.,0.), 1);
730 SphericalPointDistribution::Polygon_t newpolygon =
731 SPD.get<5>();
732 SphericalPointDistribution::Polygon_t expected = newpolygon;
733 expected.pop_front(); // remove first point
734 SphericalPointDistribution::Polygon_t remaining =
735 SphericalPointDistribution::matchSphericalPointDistributions(
736 polygon,
737 newpolygon);
738 CPPUNIT_ASSERT_EQUAL( expected, remaining );
739 }
740
741 // test with one point, just a flip of axis
742 {
743 SphericalPointDistribution::WeightedPolygon_t polygon;
744 polygon += std::make_pair( Vector(0.,1.,0.), 1);
745 SphericalPointDistribution::Polygon_t newpolygon =
746 SPD.get<5>();
747 SphericalPointDistribution::Polygon_t expected = newpolygon;
748 expected.pop_front(); // remove first point
749 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
750 iter != expected.end(); ++iter) {
751 std::swap((*iter)[0], (*iter)[1]);
752 (*iter)[0] *= -1.;
753 }
754 SphericalPointDistribution::Polygon_t remaining =
755 SphericalPointDistribution::matchSphericalPointDistributions(
756 polygon,
757 newpolygon);
758 CPPUNIT_ASSERT_EQUAL( expected, remaining );
759 }
760
761 // test with two points, matching trivially
762 {
763 SphericalPointDistribution::WeightedPolygon_t polygon;
764 polygon += std::make_pair( Vector(1.,0.,0.), 1);
765 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
766 SphericalPointDistribution::Polygon_t newpolygon =
767 SPD.get<5>();
768 SphericalPointDistribution::Polygon_t expected = newpolygon;
769 expected.pop_front(); // remove first point
770 expected.pop_front(); // remove second point
771 SphericalPointDistribution::Polygon_t remaining =
772 SphericalPointDistribution::matchSphericalPointDistributions(
773 polygon,
774 newpolygon);
775 CPPUNIT_ASSERT_EQUAL( expected, remaining );
776 // also slightly perturbed
777 const double amplitude = 0.05;
778 perturbPolygon(polygon, amplitude);
779 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
780 }
781
782 // test with two points, full rotation
783 {
784 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
785 SphericalPointDistribution::WeightedPolygon_t polygon;
786 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180.*M_PI), 1);
787 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180.*M_PI), 1);
788 SphericalPointDistribution::Polygon_t newpolygon =
789 SPD.get<5>();
790 SphericalPointDistribution::Polygon_t expected = newpolygon;
791 expected.pop_front(); // remove first point
792 expected.pop_front(); // remove second point
793 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
794 iter != expected.end(); ++iter)
795 *iter = RotationAxis.rotateVector(*iter, 47.6/180.*M_PI);
796 SphericalPointDistribution::Polygon_t remaining =
797 SphericalPointDistribution::matchSphericalPointDistributions(
798 polygon,
799 newpolygon);
800 // the three remaining points sit on a plane that may be rotated arbitrarily
801 // so we cannot simply check for equality between expected and remaining
802 // hence, we just check that they are orthogonal to the first two points
803 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
804 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
805 fixiter != polygon.end(); ++fixiter) {
806 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
807 iter != remaining.end(); ++iter) {
808 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
809 }
810 }
811 }
812
813 // test with three points, matching trivially
814 {
815 SphericalPointDistribution::WeightedPolygon_t polygon;
816 polygon += std::make_pair( Vector(1.,0.,0.), 1);
817 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
818 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
819 SphericalPointDistribution::Polygon_t newpolygon =
820 SPD.get<5>();
821 SphericalPointDistribution::Polygon_t expected = newpolygon;
822 expected.pop_front(); // remove first point
823 expected.pop_front(); // remove second point
824 expected.pop_front(); // remove third point
825 SphericalPointDistribution::Polygon_t remaining =
826 SphericalPointDistribution::matchSphericalPointDistributions(
827 polygon,
828 newpolygon);
829 CPPUNIT_ASSERT_EQUAL( expected, remaining );
830 // also slightly perturbed
831 const double amplitude = 0.05;
832 perturbPolygon(polygon, amplitude);
833 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
834 }
835
836 // test with three points, full rotation
837 {
838 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
839 SphericalPointDistribution::WeightedPolygon_t polygon;
840 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
841 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
842 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
843 SphericalPointDistribution::Polygon_t newpolygon =
844 SPD.get<5>();
845 SphericalPointDistribution::Polygon_t expected = newpolygon;
846 expected.pop_front(); // remove first point
847 expected.pop_front(); // remove second point
848 expected.pop_front(); // remove third point
849 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
850 iter != expected.end(); ++iter)
851 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
852 SphericalPointDistribution::Polygon_t remaining =
853 SphericalPointDistribution::matchSphericalPointDistributions(
854 polygon,
855 newpolygon);
856 CPPUNIT_ASSERT_EQUAL( expected, remaining );
857 // also slightly perturbed
858 const double amplitude = 0.05;
859 perturbPolygon(polygon, amplitude);
860 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
861 }
862}
863
864/** UnitTest for matchSphericalPointDistributions() with six points
865 */
866void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_6()
867{
868 SphericalPointDistribution SPD(1.);
869
870 // test with one point, matching trivially
871 {
872 SphericalPointDistribution::WeightedPolygon_t polygon;
873 polygon += std::make_pair( Vector(1.,0.,0.), 1);
874 SphericalPointDistribution::Polygon_t newpolygon =
875 SPD.get<6>();
876 SphericalPointDistribution::Polygon_t expected = newpolygon;
877 expected.pop_front(); // remove first point
878 SphericalPointDistribution::Polygon_t remaining =
879 SphericalPointDistribution::matchSphericalPointDistributions(
880 polygon,
881 newpolygon);
882 CPPUNIT_ASSERT_EQUAL( expected, remaining );
883 }
884
885 // test with one point, just a flip of axis
886 {
887 SphericalPointDistribution::WeightedPolygon_t polygon;
888 polygon += std::make_pair( Vector(0.,1.,0.), 1);
889 SphericalPointDistribution::Polygon_t newpolygon =
890 SPD.get<6>();
891 SphericalPointDistribution::Polygon_t expected = newpolygon;
892 expected.pop_front(); // remove first point
893 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
894 iter != expected.end(); ++iter) {
895 std::swap((*iter)[0], (*iter)[1]);
896 (*iter)[0] *= -1.;
897 }
898 SphericalPointDistribution::Polygon_t remaining =
899 SphericalPointDistribution::matchSphericalPointDistributions(
900 polygon,
901 newpolygon);
902 CPPUNIT_ASSERT_EQUAL( expected, remaining );
903 }
904
905 // test with two points, matching trivially
906 {
907 SphericalPointDistribution::WeightedPolygon_t polygon;
908 polygon += std::make_pair( Vector(1.,0.,0.), 1);
909 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
910 SphericalPointDistribution::Polygon_t newpolygon =
911 SPD.get<6>();
912 SphericalPointDistribution::Polygon_t expected = newpolygon;
913 expected.pop_front(); // remove first point
914 expected.pop_front(); // remove second spoint
915 SphericalPointDistribution::Polygon_t remaining =
916 SphericalPointDistribution::matchSphericalPointDistributions(
917 polygon,
918 newpolygon);
919 CPPUNIT_ASSERT_EQUAL( expected, remaining );
920 // also slightly perturbed
921 const double amplitude = 0.05;
922 perturbPolygon(polygon, amplitude);
923 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
924 }
925
926 // test with two points, full rotation
927 {
928 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
929 SphericalPointDistribution::WeightedPolygon_t polygon;
930 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
931 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
932 SphericalPointDistribution::Polygon_t newpolygon =
933 SPD.get<6>();
934 SphericalPointDistribution::Polygon_t expected = newpolygon;
935 expected.pop_front(); // remove first point
936 expected.pop_front(); // remove second spoint
937 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
938 iter != expected.end(); ++iter)
939 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
940 SphericalPointDistribution::Polygon_t remaining =
941 SphericalPointDistribution::matchSphericalPointDistributions(
942 polygon,
943 newpolygon);
944 // the four remaining points sit on a plane that may have been rotated arbitrarily
945 // so we cannot simply check for equality between expected and remaining
946 // hence, we just check that they are orthogonal to the first two points
947 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
948 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
949 fixiter != polygon.end(); ++fixiter) {
950 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
951 iter != remaining.end(); ++iter) {
952 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
953 }
954 }
955 }
956
957 // test with three points, matching trivially
958 {
959 SphericalPointDistribution::WeightedPolygon_t polygon;
960 polygon += std::make_pair( Vector(1.,0.,0.), 1);
961 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
962 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
963 SphericalPointDistribution::Polygon_t newpolygon =
964 SPD.get<6>();
965 SphericalPointDistribution::Polygon_t expected = newpolygon;
966 expected.pop_front(); // remove first point
967 expected.pop_front(); // remove second point
968 expected.pop_front(); // remove third point
969 SphericalPointDistribution::Polygon_t remaining =
970 SphericalPointDistribution::matchSphericalPointDistributions(
971 polygon,
972 newpolygon);
973 CPPUNIT_ASSERT_EQUAL( expected, remaining );
974 // also slightly perturbed
975 const double amplitude = 0.05;
976 perturbPolygon(polygon, amplitude);
977 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
978 }
979
980 // test with three points, full rotation
981 {
982 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
983 SphericalPointDistribution::WeightedPolygon_t polygon;
984 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
985 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
986 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
987 SphericalPointDistribution::Polygon_t newpolygon =
988 SPD.get<6>();
989 SphericalPointDistribution::Polygon_t expected = newpolygon;
990 expected.pop_front(); // remove first point
991 expected.pop_front(); // remove second point
992 expected.pop_front(); // remove third point
993 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
994 iter != expected.end(); ++iter)
995 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
996 SphericalPointDistribution::Polygon_t remaining =
997 SphericalPointDistribution::matchSphericalPointDistributions(
998 polygon,
999 newpolygon);
1000 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1001 // also slightly perturbed
1002 const double amplitude = 0.05;
1003 perturbPolygon(polygon, amplitude);
1004 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1005 }
1006}
1007
1008/** UnitTest for matchSphericalPointDistributions() with seven points
1009 */
1010void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_7()
1011{
1012 SphericalPointDistribution SPD(1.);
1013
1014 // test with one point, matching trivially
1015 {
1016 SphericalPointDistribution::WeightedPolygon_t polygon;
1017 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1018 SphericalPointDistribution::Polygon_t newpolygon =
1019 SPD.get<7>();
1020 SphericalPointDistribution::Polygon_t expected = newpolygon;
1021 expected.pop_front(); // remove first point
1022 SphericalPointDistribution::Polygon_t remaining =
1023 SphericalPointDistribution::matchSphericalPointDistributions(
1024 polygon,
1025 newpolygon);
1026 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1027 }
1028
1029 // test with one point, just a flip of axis
1030 {
1031 SphericalPointDistribution::WeightedPolygon_t polygon;
1032 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1033 SphericalPointDistribution::Polygon_t newpolygon =
1034 SPD.get<7>();
1035 SphericalPointDistribution::Polygon_t expected = newpolygon;
1036 expected.pop_front(); // remove first point
1037 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1038 iter != expected.end(); ++iter) {
1039 std::swap((*iter)[0], (*iter)[1]);
1040 (*iter)[0] *= -1.;
1041 }
1042 SphericalPointDistribution::Polygon_t remaining =
1043 SphericalPointDistribution::matchSphericalPointDistributions(
1044 polygon,
1045 newpolygon);
1046 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1047 }
1048
1049 // test with two points, matching trivially
1050 {
1051 SphericalPointDistribution::WeightedPolygon_t polygon;
1052 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1053 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1054 SphericalPointDistribution::Polygon_t newpolygon =
1055 SPD.get<7>();
1056 SphericalPointDistribution::Polygon_t expected = newpolygon;
1057 expected.pop_front(); // remove first point
1058 expected.pop_front(); // remove second point
1059 SphericalPointDistribution::Polygon_t remaining =
1060 SphericalPointDistribution::matchSphericalPointDistributions(
1061 polygon,
1062 newpolygon);
1063 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1064 // also slightly perturbed
1065 const double amplitude = 0.05;
1066 perturbPolygon(polygon, amplitude);
1067 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1068 }
1069
1070 // test with two points, full rotation
1071 {
1072 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1073 SphericalPointDistribution::WeightedPolygon_t polygon;
1074 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1075 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1076 SphericalPointDistribution::Polygon_t newpolygon =
1077 SPD.get<7>();
1078 SphericalPointDistribution::Polygon_t expected = newpolygon;
1079 expected.pop_front(); // remove first point
1080 expected.pop_front(); // remove second point
1081 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1082 iter != expected.end(); ++iter)
1083 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1084 SphericalPointDistribution::Polygon_t remaining =
1085 SphericalPointDistribution::matchSphericalPointDistributions(
1086 polygon,
1087 newpolygon);
1088 // the five remaining points sit on a plane that may have been rotated arbitrarily
1089 // so we cannot simply check for equality between expected and remaining
1090 // hence, we just check that they are orthogonal to the first two points
1091 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1092 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1093 fixiter != polygon.end(); ++fixiter) {
1094 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1095 iter != remaining.end(); ++iter) {
1096 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1097 }
1098 }
1099 }
1100
1101 // test with three points, matching trivially
1102 {
1103 SphericalPointDistribution::WeightedPolygon_t polygon;
1104 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1105 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1106 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
1107 SphericalPointDistribution::Polygon_t newpolygon =
1108 SPD.get<7>();
1109 SphericalPointDistribution::Polygon_t expected = newpolygon;
1110 expected.pop_front(); // remove first point
1111 expected.pop_front(); // remove second point
1112 expected.pop_front(); // remove third point
1113 SphericalPointDistribution::Polygon_t remaining =
1114 SphericalPointDistribution::matchSphericalPointDistributions(
1115 polygon,
1116 newpolygon);
1117 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1118 // also slightly perturbed
1119 const double amplitude = 0.05;
1120 perturbPolygon(polygon, amplitude);
1121 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1122 }
1123
1124 // test with three points, full rotation
1125 {
1126 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1127 SphericalPointDistribution::WeightedPolygon_t polygon;
1128 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1129 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1130 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
1131 SphericalPointDistribution::Polygon_t newpolygon =
1132 SPD.get<7>();
1133 SphericalPointDistribution::Polygon_t expected = newpolygon;
1134 expected.pop_front(); // remove first point
1135 expected.pop_front(); // remove second point
1136 expected.pop_front(); // remove third point
1137 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1138 iter != expected.end(); ++iter)
1139 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1140 SphericalPointDistribution::Polygon_t remaining =
1141 SphericalPointDistribution::matchSphericalPointDistributions(
1142 polygon,
1143 newpolygon);
1144 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1145 // also slightly perturbed
1146 const double amplitude = 0.05;
1147 perturbPolygon(polygon, amplitude);
1148 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1149 }
1150}
1151
1152/** UnitTest for matchSphericalPointDistributions() with eight points
1153 */
1154void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_8()
1155{
1156 SphericalPointDistribution SPD(1.);
1157
1158 // test with one point, matching trivially
1159 {
1160 SphericalPointDistribution::WeightedPolygon_t polygon;
1161 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1162 SphericalPointDistribution::Polygon_t newpolygon =
1163 SPD.get<8>();
1164 SphericalPointDistribution::Polygon_t expected = newpolygon;
1165 expected.pop_front(); // remove first point
1166 SphericalPointDistribution::Polygon_t remaining =
1167 SphericalPointDistribution::matchSphericalPointDistributions(
1168 polygon,
1169 newpolygon);
1170 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1171 }
1172
1173 // test with one point, just a flip of axis
1174 {
1175 SphericalPointDistribution::WeightedPolygon_t polygon;
1176 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1177 SphericalPointDistribution::Polygon_t newpolygon =
1178 SPD.get<8>();
1179 SphericalPointDistribution::Polygon_t expected = newpolygon;
1180 expected.pop_front(); // remove first point
1181 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1182 iter != expected.end(); ++iter) {
1183 std::swap((*iter)[0], (*iter)[1]);
1184 (*iter)[0] *= -1.;
1185 }
1186 SphericalPointDistribution::Polygon_t remaining =
1187 SphericalPointDistribution::matchSphericalPointDistributions(
1188 polygon,
1189 newpolygon);
1190 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1191 }
1192
1193 // test with two points, matching trivially
1194 {
1195 SphericalPointDistribution::WeightedPolygon_t polygon;
1196 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1197 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1198 SphericalPointDistribution::Polygon_t newpolygon =
1199 SPD.get<8>();
1200 SphericalPointDistribution::Polygon_t expected = newpolygon;
1201 expected.pop_front(); // remove first point
1202 expected.pop_front(); // remove second point
1203 SphericalPointDistribution::Polygon_t remaining =
1204 SphericalPointDistribution::matchSphericalPointDistributions(
1205 polygon,
1206 newpolygon);
1207 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1208 // also slightly perturbed
1209 const double amplitude = 0.05;
1210 perturbPolygon(polygon, amplitude);
1211 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1212 }
1213
1214 // test with two points, full rotation
1215 {
1216 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1217 SphericalPointDistribution::WeightedPolygon_t polygon;
1218 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1219 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1220 SphericalPointDistribution::Polygon_t newpolygon =
1221 SPD.get<8>();
1222 SphericalPointDistribution::Polygon_t expected = newpolygon;
1223 expected.pop_front(); // remove first point
1224 expected.pop_front(); // remove second point
1225 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1226 iter != expected.end(); ++iter)
1227 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1228 SphericalPointDistribution::Polygon_t remaining =
1229 SphericalPointDistribution::matchSphericalPointDistributions(
1230 polygon,
1231 newpolygon);
1232 // the six remaining points sit on two planes that may have been rotated arbitrarily
1233 // so we cannot simply check for equality between expected and remaining
1234 // hence, we just check that they are orthogonal to the first two points
1235 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1236 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1237 fixiter != polygon.end(); ++fixiter) {
1238 SphericalPointDistribution::Polygon_t::const_iterator expectiter = expected.begin();
1239 SphericalPointDistribution::Polygon_t::const_iterator remainiter = remaining.begin();
1240 for (;remainiter != remaining.end(); ++expectiter, ++remainiter) {
1241 // check that points in expected/remaining have same angle to the given ones
1242// CPPUNIT_ASSERT_EQUAL( (*expectiter).Angle(*fixiter), (*remainiter).Angle(*fixiter) );
1243 CPPUNIT_ASSERT( fabs( (*expectiter).Angle(fixiter->first) - (*remainiter).Angle(fixiter->first) )
1244 < std::numeric_limits<double>::epsilon()*1e4 );
1245 }
1246 }
1247 }
1248
1249 // test with three points, matching trivially
1250 {
1251 SphericalPointDistribution::WeightedPolygon_t polygon;
1252 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1253 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1254 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0, 0.0), 1);
1255 SphericalPointDistribution::Polygon_t newpolygon =
1256 SPD.get<8>();
1257 SphericalPointDistribution::Polygon_t expected = newpolygon;
1258 expected.pop_front(); // remove first point
1259 expected.pop_front(); // remove second point
1260 expected.pop_front(); // remove third point
1261 SphericalPointDistribution::Polygon_t remaining =
1262 SphericalPointDistribution::matchSphericalPointDistributions(
1263 polygon,
1264 newpolygon);
1265 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1266 // also slightly perturbed
1267 const double amplitude = 0.05;
1268 perturbPolygon(polygon, amplitude);
1269 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1270 }
1271
1272 // test with three points, full rotation
1273 {
1274 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1275 SphericalPointDistribution::WeightedPolygon_t polygon;
1276 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1277 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1278 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0, 0.0), 47.6/180*M_PI), 1);
1279 SphericalPointDistribution::Polygon_t newpolygon =
1280 SPD.get<8>();
1281 SphericalPointDistribution::Polygon_t expected = newpolygon;
1282 expected.pop_front(); // remove first point
1283 expected.pop_front(); // remove second point
1284 expected.pop_front(); // remove third point
1285 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1286 iter != expected.end(); ++iter)
1287 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1288 SphericalPointDistribution::Polygon_t remaining =
1289 SphericalPointDistribution::matchSphericalPointDistributions(
1290 polygon,
1291 newpolygon);
1292 CPPUNIT_ASSERT_EQUAL( expected, remaining );
1293 // also slightly perturbed
1294 const double amplitude = 0.05;
1295 perturbPolygon(polygon, amplitude);
1296 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1297 }
1298}
Note: See TracBrowser for help on using the repository browser.