source: src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.cpp@ a2f8a9

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

Added calculation of center of minimum distance by bisection.

  • this will give us a unique a definite point independent of the (rotational) position of the point set on the unit sphere.
  • added unit test.
  • Property mode set to 100644
File size: 60.4 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/** due to root-taking in function we only have limited numerical precision,
71 * basically half of the double range.
72 */
73const double CenterAccuracy = sqrt(std::numeric_limits<double>::epsilon()*1e2);
74
75void SphericalPointDistributionTest::setUp()
76{
77 // failing asserts should be thrown
78 ASSERT_DO(Assert::Throw);
79
80 setVerbosity(6);
81}
82
83
84void SphericalPointDistributionTest::tearDown()
85{
86}
87
88/** UnitTest for calculateCenterOfMinimumDistance()
89 */
90void SphericalPointDistributionTest::calculateCenterOfMinimumDistanceTest()
91{
92 // single point
93 {
94 SphericalPointDistribution::VectorArray_t points;
95 points +=
96 Vector(1.,0.,0.);
97 SphericalPointDistribution::IndexList_t indices;
98 indices += 0;
99 const Vector expected = points[0];
100 const Vector center =
101 SphericalPointDistribution::calculateCenterOfMinimumDistance(points, indices);
102// std::cout << " Difference is " << (expected - center).Norm() << std::endl;
103// CPPUNIT_ASSERT_EQUAL ( expected, center );
104 CPPUNIT_ASSERT( expected.IsEqualTo(center, CenterAccuracy));
105 }
106
107 // single point, rotated
108 {
109 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
110 SphericalPointDistribution::VectorArray_t points;
111 points +=
112 RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI);
113 SphericalPointDistribution::IndexList_t indices;
114 indices += 0;
115 const Vector expected = points[0];
116 const Vector center =
117 SphericalPointDistribution::calculateCenterOfMinimumDistance(points, indices);
118// std::cout << " Difference is " << (expected - center).Norm() << std::endl;
119// CPPUNIT_ASSERT_EQUAL ( expected, center );
120 CPPUNIT_ASSERT( expected.IsEqualTo(center, CenterAccuracy));
121 }
122
123 // two points
124 {
125 SphericalPointDistribution::VectorArray_t points;
126 points +=
127 Vector(1.,0.,0.),
128 Vector(0.,1.,0.);
129 SphericalPointDistribution::IndexList_t indices;
130 indices += 0,1;
131 const Vector expected = Vector(M_SQRT1_2,M_SQRT1_2,0.);
132 const Vector center =
133 SphericalPointDistribution::calculateCenterOfMinimumDistance(points, indices);
134// std::cout << " Difference is " << (expected - center).Norm() << std::endl;
135// CPPUNIT_ASSERT_EQUAL ( expected, center );
136 CPPUNIT_ASSERT( expected.IsEqualTo(center, CenterAccuracy));
137 }
138
139 // two points, rotated
140 {
141 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
142 SphericalPointDistribution::VectorArray_t points;
143 points +=
144 RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI),
145 RotationAxis.rotateVector(Vector(0.,1.,0.), 47.6/180*M_PI);
146 SphericalPointDistribution::IndexList_t indices;
147 indices += 0,1;
148 const Vector expected = RotationAxis.rotateVector(Vector(M_SQRT1_2,M_SQRT1_2,0.), 47.6/180*M_PI);
149 const Vector center =
150 SphericalPointDistribution::calculateCenterOfMinimumDistance(points, indices);
151// std::cout << " Difference is " << (expected - center).Norm() << std::endl;
152// CPPUNIT_ASSERT_EQUAL ( expected, center );
153 CPPUNIT_ASSERT( expected.IsEqualTo(center, CenterAccuracy));
154 }
155
156 // three points in line
157 {
158 SphericalPointDistribution::VectorArray_t points;
159 points +=
160 Vector(1.,0.,0.),
161 Vector(0.,1.,0.),
162 Vector(-1.,0.,0.);
163 SphericalPointDistribution::IndexList_t indices;
164 indices += 0,1,2;
165 const Vector expected = points[1];
166 const Vector center =
167 SphericalPointDistribution::calculateCenterOfMinimumDistance(points, indices);
168// std::cout << " Difference is " << (expected - center).Norm() << std::endl;
169// CPPUNIT_ASSERT_EQUAL ( expected, center );
170 CPPUNIT_ASSERT( expected.IsEqualTo(center, CenterAccuracy));
171 }
172
173 // three points in line, rotated
174 {
175 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
176 SphericalPointDistribution::VectorArray_t points;
177 points +=
178 RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI),
179 RotationAxis.rotateVector(Vector(0.,1.,0.), 47.6/180*M_PI),
180 RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI);
181 SphericalPointDistribution::IndexList_t indices;
182 indices += 0,1,2;
183 const Vector expected = points[1];
184 const Vector center =
185 SphericalPointDistribution::calculateCenterOfMinimumDistance(points, indices);
186// std::cout << " Difference is " << (expected - center).Norm() << std::endl;
187// CPPUNIT_ASSERT_EQUAL ( expected, center );
188 CPPUNIT_ASSERT( expected.IsEqualTo(center, CenterAccuracy));
189 }
190}
191
192static
193bool areEqualToWithinBounds(
194 const SphericalPointDistribution::Polygon_t &_polygon,
195 const SphericalPointDistribution::Polygon_t &_otherpolygon,
196 double _amplitude
197 )
198{
199 // same size?
200 if (_polygon.size() != _otherpolygon.size())
201 return false;
202 // same points ? We just check witrh trivial mapping, nothing fancy ...
203 bool status = true;
204 SphericalPointDistribution::Polygon_t::const_iterator iter = _polygon.begin();
205 SphericalPointDistribution::Polygon_t::const_iterator otheriter = _otherpolygon.begin();
206 for (; iter != _polygon.end(); ++iter, ++otheriter) {
207 status &= (*iter).IsEqualTo(*otheriter, _amplitude);
208 }
209 return status;
210}
211
212/** UnitTest for areEqualToWithinBounds()
213 */
214void SphericalPointDistributionTest::areEqualToWithinBoundsTest()
215{
216 // test with no points
217 {
218 SphericalPointDistribution::Polygon_t polygon;
219 SphericalPointDistribution::Polygon_t expected = polygon;
220 CPPUNIT_ASSERT( areEqualToWithinBounds(polygon, expected, std::numeric_limits<double>::epsilon()*1e2) );
221 }
222 // test with one point
223 {
224 SphericalPointDistribution::Polygon_t polygon;
225 polygon += Vector(1.,0.,0.);
226 SphericalPointDistribution::Polygon_t expected = polygon;
227 CPPUNIT_ASSERT( areEqualToWithinBounds(polygon, expected, std::numeric_limits<double>::epsilon()*1e2) );
228 }
229 // test with two points
230 {
231 SphericalPointDistribution::Polygon_t polygon;
232 polygon += Vector(1.,0.,0.);
233 polygon += Vector(0.,1.,0.);
234 SphericalPointDistribution::Polygon_t expected = polygon;
235 CPPUNIT_ASSERT( areEqualToWithinBounds(polygon, expected, std::numeric_limits<double>::epsilon()*1e2) );
236 }
237
238 // test with two points in different order: THIS GOES WRONG: We only check trivially
239 {
240 SphericalPointDistribution::Polygon_t polygon;
241 polygon += Vector(1.,0.,0.);
242 polygon += Vector(0.,1.,0.);
243 SphericalPointDistribution::Polygon_t expected;
244 expected += Vector(0.,1.,0.);
245 expected += Vector(1.,0.,0.);
246 CPPUNIT_ASSERT( !areEqualToWithinBounds(polygon, expected, std::numeric_limits<double>::epsilon()*1e2) );
247 }
248
249 // test with two different points
250 {
251 SphericalPointDistribution::Polygon_t polygon;
252 polygon += Vector(1.,0.,0.);
253 polygon += Vector(0.,1.,0.);
254 SphericalPointDistribution::Polygon_t expected;
255 expected += Vector(1.01,0.,0.);
256 expected += Vector(0.,1.,0.);
257 CPPUNIT_ASSERT( areEqualToWithinBounds(polygon, expected, 0.05) );
258 CPPUNIT_ASSERT( !areEqualToWithinBounds(polygon, expected, 0.005) );
259 }
260
261 // test with different number of points
262 {
263 SphericalPointDistribution::Polygon_t polygon;
264 polygon += Vector(1.,0.,0.);
265 polygon += Vector(0.,1.,0.);
266 SphericalPointDistribution::Polygon_t expected;
267 expected += Vector(0.,1.,0.);
268 CPPUNIT_ASSERT( !areEqualToWithinBounds(polygon, expected, 0.05) );
269 }
270}
271
272/** UnitTest for matchSphericalPointDistributions() with two points
273 */
274void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_2()
275{
276 SphericalPointDistribution SPD(1.);
277 // test with one point, matching trivially
278 {
279 SphericalPointDistribution::WeightedPolygon_t polygon;
280 polygon += std::make_pair(Vector(1.,0.,0.), 1);
281 SphericalPointDistribution::Polygon_t newpolygon =
282 SPD.get<2>();
283 SphericalPointDistribution::Polygon_t expected;
284 expected += Vector(-1.,0.,0.);
285 SphericalPointDistribution::Polygon_t remaining =
286 SphericalPointDistribution::matchSphericalPointDistributions(
287 polygon,
288 newpolygon);
289// CPPUNIT_ASSERT_EQUAL( expected, remaining );
290 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
291 }
292
293 // test with one point, just a flip of axis
294 {
295 SphericalPointDistribution::WeightedPolygon_t polygon;
296 polygon += std::make_pair( Vector(0.,1.,0.), 1);
297 SphericalPointDistribution::Polygon_t newpolygon =
298 SPD.get<2>();
299 SphericalPointDistribution::Polygon_t expected;
300 expected += Vector(0.,-1.,0.);
301 SphericalPointDistribution::Polygon_t remaining =
302 SphericalPointDistribution::matchSphericalPointDistributions(
303 polygon,
304 newpolygon);
305// CPPUNIT_ASSERT_EQUAL( expected, remaining );
306 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
307 }
308
309 // test with one point, just a flip to another axis
310 {
311 SphericalPointDistribution::WeightedPolygon_t polygon;
312 polygon += std::make_pair( Vector(0.,0.,-1.), 1);
313 SphericalPointDistribution::Polygon_t newpolygon =
314 SPD.get<2>();
315 SphericalPointDistribution::Polygon_t expected;
316 expected += Vector(0.,0.,1.);
317 SphericalPointDistribution::Polygon_t remaining =
318 SphericalPointDistribution::matchSphericalPointDistributions(
319 polygon,
320 newpolygon);
321// CPPUNIT_ASSERT_EQUAL( expected, remaining );
322 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
323 }
324
325 // test with one point, full rotation
326 {
327 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
328 SphericalPointDistribution::WeightedPolygon_t polygon;
329 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
330 SphericalPointDistribution::Polygon_t newpolygon =
331 SPD.get<2>();
332 SphericalPointDistribution::Polygon_t expected;
333 expected += RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI);
334 SphericalPointDistribution::Polygon_t remaining =
335 SphericalPointDistribution::matchSphericalPointDistributions(
336 polygon,
337 newpolygon);
338// CPPUNIT_ASSERT_EQUAL( expected, remaining );
339 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
340 }
341}
342
343void perturbPolygon(
344 SphericalPointDistribution::WeightedPolygon_t &_polygon,
345 double _amplitude
346 )
347{
348 for (SphericalPointDistribution::WeightedPolygon_t::iterator iter = _polygon.begin();
349 iter != _polygon.end(); ++iter) {
350 Vector perturber;
351 perturber.GetOneNormalVector(iter->first);
352 perturber.Scale(_amplitude);
353 iter->first = iter->first + perturber;
354 (iter->first).Normalize();
355 }
356}
357
358/** UnitTest for joinPoints()
359 */
360void SphericalPointDistributionTest::joinPointsTest()
361{
362 // test with simple configuration of three points
363 {
364 SphericalPointDistribution::Polygon_t newpolygon;
365 newpolygon += Vector(1.,0.,0.);
366 newpolygon += Vector(0.,1.,0.);
367 newpolygon += Vector(0.,0.,1.);
368 SphericalPointDistribution::Polygon_t expectedpolygon = newpolygon;
369 SphericalPointDistribution::IndexTupleList_t matching;
370 matching += SphericalPointDistribution::IndexList_t(1,0);
371 matching += SphericalPointDistribution::IndexList_t(1,1);
372 matching += SphericalPointDistribution::IndexList_t(1,2);
373 SphericalPointDistribution::IndexList_t IndexList =
374 SphericalPointDistribution::joinPoints(
375 newpolygon,
376 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
377 matching);
378 SphericalPointDistribution::IndexList_t expected;
379 expected += 0,1,2;
380 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
381 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
382 }
383
384 // test with simple configuration of three points, only two are picked
385 {
386 SphericalPointDistribution::Polygon_t newpolygon;
387 newpolygon += Vector(1.,0.,0.);
388 newpolygon += Vector(0.,1.,0.);
389 newpolygon += Vector(0.,0.,1.);
390 SphericalPointDistribution::Polygon_t expectedpolygon = newpolygon;
391 SphericalPointDistribution::IndexTupleList_t matching;
392 matching += SphericalPointDistribution::IndexList_t(1,1);
393 matching += SphericalPointDistribution::IndexList_t(1,2);
394 SphericalPointDistribution::IndexList_t IndexList =
395 SphericalPointDistribution::joinPoints(
396 newpolygon,
397 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
398 matching);
399 SphericalPointDistribution::IndexList_t expected;
400 expected += 1,2;
401 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
402 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
403 }
404
405 // test with simple configuration of three points, two are joined
406 {
407 SphericalPointDistribution::Polygon_t newpolygon;
408 newpolygon += Vector(1.,0.,0.);
409 newpolygon += Vector(0.,1.,0.);
410 newpolygon += Vector(0.,0.,1.);
411 SphericalPointDistribution::Polygon_t expectedpolygon;
412 expectedpolygon += Vector(1.,0.,0.);
413 expectedpolygon += Vector(0.,M_SQRT1_2,M_SQRT1_2);
414 SphericalPointDistribution::IndexTupleList_t matching;
415 SphericalPointDistribution::IndexList_t joined;
416 joined += 1,2;
417 matching += SphericalPointDistribution::IndexList_t(1,0);
418 matching += joined;
419 SphericalPointDistribution::IndexList_t IndexList =
420 SphericalPointDistribution::joinPoints(
421 newpolygon,
422 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
423 matching);
424 SphericalPointDistribution::IndexList_t expected;
425 expected += 0,1;
426 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
427 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
428 }
429
430 // test with simple configuration of six points, two are joined, jumbled indices
431 {
432 SphericalPointDistribution::Polygon_t newpolygon;
433 newpolygon += Vector(1.,0.,1.);
434 newpolygon += Vector(1.,0.,0.);
435 newpolygon += Vector(1.,1.,0.);
436 newpolygon += Vector(0.,1.,0.);
437 newpolygon += Vector(0.,0.,1.);
438 newpolygon += Vector(1.,0.,1.);
439 SphericalPointDistribution::Polygon_t expectedpolygon;
440 expectedpolygon += Vector(1.,0.,1.);
441 expectedpolygon += Vector(1.,0.,0.);
442 expectedpolygon += Vector(1.,1.,0.);
443 expectedpolygon += Vector(1.,0.,1.);
444 expectedpolygon += Vector(0.,M_SQRT1_2,M_SQRT1_2); // new centers go last
445 SphericalPointDistribution::IndexTupleList_t matching;
446 SphericalPointDistribution::IndexList_t joined;
447 joined += 3,4;
448 matching += SphericalPointDistribution::IndexList_t(1,1);
449 matching += joined;
450 SphericalPointDistribution::IndexList_t IndexList =
451 SphericalPointDistribution::joinPoints(
452 newpolygon,
453 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
454 matching);
455 SphericalPointDistribution::IndexList_t expected;
456 expected += 1,4;
457 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
458 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
459 }
460}
461
462/** UnitTest for matchSphericalPointDistributions() with three points
463 */
464void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_3()
465{
466 SphericalPointDistribution SPD(1.);
467
468 // test with one point, matching trivially
469 {
470 SphericalPointDistribution::WeightedPolygon_t polygon;
471 polygon += std::make_pair( Vector(1.,0.,0.), 1);
472 SphericalPointDistribution::Polygon_t newpolygon =
473 SPD.get<3>();
474 SphericalPointDistribution::Polygon_t expected = newpolygon;
475 expected.pop_front(); // remove first point
476 SphericalPointDistribution::Polygon_t remaining =
477 SphericalPointDistribution::matchSphericalPointDistributions(
478 polygon,
479 newpolygon);
480// CPPUNIT_ASSERT_EQUAL( expected, remaining );
481 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
482 }
483
484 // test with one point, just a flip of x and y axis
485 {
486 SphericalPointDistribution::WeightedPolygon_t polygon;
487 polygon += std::make_pair( Vector(0.,1.,0.), 1);
488 SphericalPointDistribution::Polygon_t newpolygon =
489 SPD.get<3>();
490 SphericalPointDistribution::Polygon_t expected = newpolygon;
491 expected.pop_front(); // remove first point
492 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
493 iter != expected.end(); ++iter) {
494 std::swap((*iter)[0], (*iter)[1]);
495 (*iter)[0] *= -1.;
496 }
497 SphericalPointDistribution::Polygon_t remaining =
498 SphericalPointDistribution::matchSphericalPointDistributions(
499 polygon,
500 newpolygon);
501// CPPUNIT_ASSERT_EQUAL( expected, remaining );
502 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
503 }
504
505 // test with two points, matching trivially
506 {
507 SphericalPointDistribution::WeightedPolygon_t polygon;
508 polygon += std::make_pair( Vector(1.,0.,0.), 1);
509 polygon += std::make_pair( Vector(-0.5, sqrt(3)*0.5,0.), 1);
510 SphericalPointDistribution::Polygon_t newpolygon =
511 SPD.get<3>();
512 SphericalPointDistribution::Polygon_t expected = newpolygon;
513 expected.pop_front(); // remove first point
514 expected.pop_front(); // remove second point
515 SphericalPointDistribution::Polygon_t remaining =
516 SphericalPointDistribution::matchSphericalPointDistributions(
517 polygon,
518 newpolygon);
519// CPPUNIT_ASSERT_EQUAL( expected, remaining );
520 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
521 // also slightly perturbed
522 const double amplitude = 0.05;
523 perturbPolygon(polygon, amplitude);
524 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
525 }
526
527 // test with two points, full rotation
528 {
529 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
530 SphericalPointDistribution::WeightedPolygon_t polygon;
531 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
532 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
533 SphericalPointDistribution::Polygon_t newpolygon =
534 SPD.get<3>();
535 SphericalPointDistribution::Polygon_t expected = newpolygon;
536 expected.pop_front(); // remove first point
537 expected.pop_front(); // remove second point
538 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
539 iter != expected.end(); ++iter)
540 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
541 SphericalPointDistribution::Polygon_t remaining =
542 SphericalPointDistribution::matchSphericalPointDistributions(
543 polygon,
544 newpolygon);
545// CPPUNIT_ASSERT_EQUAL( expected, remaining );
546 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
547 // also slightly perturbed
548 const double amplitude = 0.05;
549 perturbPolygon(polygon, amplitude);
550 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
551 }
552
553 // test with three points, matching trivially
554 {
555 SphericalPointDistribution::WeightedPolygon_t polygon;
556 polygon += std::make_pair( Vector(1.,0.,0.), 1);
557 polygon += std::make_pair( Vector(-0.5, sqrt(3)*0.5,0.), 1);
558 polygon += std::make_pair( Vector(-0.5, -sqrt(3)*0.5,0.), 1);
559 SphericalPointDistribution::Polygon_t newpolygon =
560 SPD.get<3>();
561 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
562 SphericalPointDistribution::Polygon_t remaining =
563 SphericalPointDistribution::matchSphericalPointDistributions(
564 polygon,
565 newpolygon);
566// CPPUNIT_ASSERT_EQUAL( expected, remaining );
567 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
568 // also slightly perturbed
569 const double amplitude = 0.05;
570 perturbPolygon(polygon, amplitude);
571 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
572 }
573
574
575 // test with three points, full rotation
576 {
577 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
578 SphericalPointDistribution::WeightedPolygon_t polygon;
579 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
580 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
581 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, -sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
582 SphericalPointDistribution::Polygon_t newpolygon =
583 SPD.get<3>();
584 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
585 SphericalPointDistribution::Polygon_t remaining =
586 SphericalPointDistribution::matchSphericalPointDistributions(
587 polygon,
588 newpolygon);
589// CPPUNIT_ASSERT_EQUAL( expected, remaining );
590 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
591 // also slightly perturbed
592 const double amplitude = 0.05;
593 perturbPolygon(polygon, amplitude);
594 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
595 }
596}
597
598/** UnitTest for matchSphericalPointDistributions() with four points
599 */
600void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_4()
601{
602 SphericalPointDistribution SPD(1.);
603
604 // test with one point, matching trivially
605 {
606 SphericalPointDistribution::WeightedPolygon_t polygon;
607 polygon += std::make_pair( Vector(1.,0.,0.), 1);
608 SphericalPointDistribution::Polygon_t newpolygon =
609 SPD.get<4>();
610 SphericalPointDistribution::Polygon_t expected = newpolygon;
611 expected.pop_front(); // remove first point
612 SphericalPointDistribution::Polygon_t remaining =
613 SphericalPointDistribution::matchSphericalPointDistributions(
614 polygon,
615 newpolygon);
616 // CPPUNIT_ASSERT_EQUAL( expected, remaining );
617 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
618 }
619
620 // test with one point, just a flip of axis
621 {
622 SphericalPointDistribution::WeightedPolygon_t polygon;
623 polygon += std::make_pair( Vector(0.,1.,0.), 1);
624 SphericalPointDistribution::Polygon_t newpolygon =
625 SPD.get<4>();
626 SphericalPointDistribution::Polygon_t expected = newpolygon;
627 expected.pop_front(); // remove first point
628 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
629 iter != expected.end(); ++iter) {
630 std::swap((*iter)[0], (*iter)[1]);
631 (*iter)[0] *= -1.;
632 }
633 SphericalPointDistribution::Polygon_t remaining =
634 SphericalPointDistribution::matchSphericalPointDistributions(
635 polygon,
636 newpolygon);
637// CPPUNIT_ASSERT_EQUAL( expected, remaining );
638 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
639 }
640
641 // test with two points, matching trivially
642 {
643 SphericalPointDistribution::WeightedPolygon_t polygon;
644 polygon += std::make_pair( Vector(1.,0.,0.), 1);
645 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
646 SphericalPointDistribution::Polygon_t newpolygon =
647 SPD.get<4>();
648 SphericalPointDistribution::Polygon_t expected = newpolygon;
649 expected.pop_front(); // remove first point
650 expected.pop_front(); // remove second point
651 SphericalPointDistribution::Polygon_t remaining =
652 SphericalPointDistribution::matchSphericalPointDistributions(
653 polygon,
654 newpolygon);
655// CPPUNIT_ASSERT_EQUAL( expected, remaining );
656 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
657 // also slightly perturbed
658 const double amplitude = 0.05;
659 perturbPolygon(polygon, amplitude);
660 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
661 }
662
663 // test with two points, matching trivially, also with slightly perturbed
664 {
665 SphericalPointDistribution::WeightedPolygon_t polygon;
666 polygon += std::make_pair( Vector(1.,0.,0.), 1);
667 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
668 SphericalPointDistribution::Polygon_t newpolygon =
669 SPD.get<4>();
670 SphericalPointDistribution::Polygon_t expected = newpolygon;
671 expected.pop_front(); // remove first point
672 expected.pop_front(); // remove second point
673 SphericalPointDistribution::Polygon_t remaining =
674 SphericalPointDistribution::matchSphericalPointDistributions(
675 polygon,
676 newpolygon);
677// CPPUNIT_ASSERT_EQUAL( expected, remaining );
678 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
679 // also slightly perturbed
680 const double amplitude = 0.05;
681 perturbPolygon(polygon, amplitude);
682 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
683 }
684
685 // test with two points, full rotation
686 {
687 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
688 SphericalPointDistribution::WeightedPolygon_t polygon;
689 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
690 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 47.6/180*M_PI), 1);
691 SphericalPointDistribution::Polygon_t newpolygon =
692 SPD.get<4>();
693 SphericalPointDistribution::Polygon_t expected = newpolygon;
694 expected.pop_front(); // remove first point
695 expected.pop_front(); // remove second point
696 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
697 iter != expected.end(); ++iter)
698 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
699 SphericalPointDistribution::Polygon_t remaining =
700 SphericalPointDistribution::matchSphericalPointDistributions(
701 polygon,
702 newpolygon);
703// CPPUNIT_ASSERT_EQUAL( expected, remaining );
704 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
705 // also slightly perturbed
706 const double amplitude = 0.05;
707 perturbPolygon(polygon, amplitude);
708 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
709 }
710
711 // test with three points, matching trivially
712 {
713 SphericalPointDistribution::WeightedPolygon_t polygon;
714 polygon += std::make_pair( Vector(1.,0.,0.), 1);
715 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
716 polygon += std::make_pair( Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 1);
717 SphericalPointDistribution::Polygon_t newpolygon =
718 SPD.get<4>();
719 SphericalPointDistribution::Polygon_t expected = newpolygon;
720 expected.pop_front(); // remove first point
721 expected.pop_front(); // remove second point
722 expected.pop_front(); // remove third point
723 SphericalPointDistribution::Polygon_t remaining =
724 SphericalPointDistribution::matchSphericalPointDistributions(
725 polygon,
726 newpolygon);
727// CPPUNIT_ASSERT_EQUAL( expected, remaining );
728 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
729 // also slightly perturbed
730 const double amplitude = 0.05;
731 perturbPolygon(polygon, amplitude);
732 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
733 }
734
735 // test with three points, full rotation
736 {
737 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
738 SphericalPointDistribution::WeightedPolygon_t polygon;
739 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
740 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 47.6/180*M_PI), 1);
741 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 47.6/180*M_PI), 1);
742 SphericalPointDistribution::Polygon_t newpolygon =
743 SPD.get<4>();
744 SphericalPointDistribution::Polygon_t expected = newpolygon;
745 expected.pop_front(); // remove first point
746 expected.pop_front(); // remove second point
747 expected.pop_front(); // remove third point
748 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
749 iter != expected.end(); ++iter)
750 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
751 SphericalPointDistribution::Polygon_t remaining =
752 SphericalPointDistribution::matchSphericalPointDistributions(
753 polygon,
754 newpolygon);
755// CPPUNIT_ASSERT_EQUAL( expected, remaining );
756 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
757 // also slightly perturbed
758 const double amplitude = 0.05;
759 perturbPolygon(polygon, amplitude);
760 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
761 }
762}
763
764/** UnitTest for matchSphericalPointDistributions() with four points and weights
765 * not all equal to one.
766 */
767void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_multiple()
768{
769 SphericalPointDistribution SPD(1.);
770
771 // test with four points: one point having weight of two
772 {
773 SphericalPointDistribution::WeightedPolygon_t polygon;
774 polygon += std::make_pair( Vector(1.,0.,0.), 2);
775 SphericalPointDistribution::Polygon_t newpolygon =
776 SPD.get<4>();
777 SphericalPointDistribution::Polygon_t expected;
778 expected += Vector(-0.5773502691896,-5.551115123126e-17,0.8164965809277);
779 expected += Vector(-0.5773502691896,-5.551115123126e-17,-0.8164965809277);
780 SphericalPointDistribution::Polygon_t remaining =
781 SphericalPointDistribution::matchSphericalPointDistributions(
782 polygon,
783 newpolygon);
784// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
785// CPPUNIT_ASSERT_EQUAL( expected, remaining );
786 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
787 }
788
789 // test with five points: one point having weight of two
790 {
791 SphericalPointDistribution::WeightedPolygon_t polygon;
792 polygon += std::make_pair( Vector(1.,0.,0.), 2);
793 SphericalPointDistribution::Polygon_t newpolygon =
794 SPD.get<5>();
795 SphericalPointDistribution::Polygon_t expected;
796 expected += Vector(-0.7071067811865,0.7071067811865,0);
797 expected += Vector(-0.3535533905933,-0.3535533905933,0.8660254037844);
798 expected += Vector(-0.3535533905933,-0.3535533905933,-0.8660254037844);
799 SphericalPointDistribution::Polygon_t remaining =
800 SphericalPointDistribution::matchSphericalPointDistributions(
801 polygon,
802 newpolygon);
803// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
804// CPPUNIT_ASSERT_EQUAL( expected, remaining );
805 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
806 }
807
808
809 // test with five points: one point having weight of two, one weight of one
810 {
811 SphericalPointDistribution::WeightedPolygon_t polygon;
812 polygon += std::make_pair( Vector(M_SQRT1_2,M_SQRT1_2,0.), 2);
813 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
814 SphericalPointDistribution::Polygon_t newpolygon =
815 SPD.get<5>();
816 SphericalPointDistribution::Polygon_t expected;
817 expected += Vector(0.3535533786708,-0.3535533955317,-0.8660254066357);
818 expected += Vector(0.3535534025157,-0.3535533856548,0.8660254009332);
819 SphericalPointDistribution::Polygon_t remaining =
820 SphericalPointDistribution::matchSphericalPointDistributions(
821 polygon,
822 newpolygon);
823// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
824// CPPUNIT_ASSERT_EQUAL( expected, remaining );
825 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
826 }
827
828 // test with six points: two points each having weight of two
829 {
830 SphericalPointDistribution::WeightedPolygon_t polygon;
831 polygon += std::make_pair( Vector(M_SQRT1_2,-M_SQRT1_2,0.), 2);
832 polygon += std::make_pair( Vector(-M_SQRT1_2,M_SQRT1_2,0.), 2);
833 SphericalPointDistribution::Polygon_t newpolygon =
834 SPD.get<6>();
835 SphericalPointDistribution::Polygon_t expected;
836 expected += Vector(0.,0.,-1.);
837 expected += Vector(0.,0.,1.);
838 SphericalPointDistribution::Polygon_t remaining =
839 SphericalPointDistribution::matchSphericalPointDistributions(
840 polygon,
841 newpolygon);
842// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
843// CPPUNIT_ASSERT_EQUAL( expected, remaining );
844 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
845 }
846}
847
848/** UnitTest for matchSphericalPointDistributions() with five points
849 */
850void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_5()
851{
852 SphericalPointDistribution SPD(1.);
853
854 // test with one point, matching trivially
855 {
856 SphericalPointDistribution::WeightedPolygon_t polygon;
857 polygon += std::make_pair( Vector(1.,0.,0.), 1);
858 SphericalPointDistribution::Polygon_t newpolygon =
859 SPD.get<5>();
860 SphericalPointDistribution::Polygon_t expected = newpolygon;
861 expected.pop_front(); // remove first point
862 SphericalPointDistribution::Polygon_t remaining =
863 SphericalPointDistribution::matchSphericalPointDistributions(
864 polygon,
865 newpolygon);
866// CPPUNIT_ASSERT_EQUAL( expected, remaining );
867 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
868 }
869
870 // test with one point, just a flip of axis
871 {
872 SphericalPointDistribution::WeightedPolygon_t polygon;
873 polygon += std::make_pair( Vector(0.,1.,0.), 1);
874 SphericalPointDistribution::Polygon_t newpolygon =
875 SPD.get<5>();
876 SphericalPointDistribution::Polygon_t expected = newpolygon;
877 expected.pop_front(); // remove first point
878 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
879 iter != expected.end(); ++iter) {
880 std::swap((*iter)[0], (*iter)[1]);
881 (*iter)[0] *= -1.;
882 }
883 SphericalPointDistribution::Polygon_t remaining =
884 SphericalPointDistribution::matchSphericalPointDistributions(
885 polygon,
886 newpolygon);
887// CPPUNIT_ASSERT_EQUAL( expected, remaining );
888 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
889 }
890
891 // test with two points, matching trivially
892 {
893 SphericalPointDistribution::WeightedPolygon_t polygon;
894 polygon += std::make_pair( Vector(1.,0.,0.), 1);
895 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
896 SphericalPointDistribution::Polygon_t newpolygon =
897 SPD.get<5>();
898 SphericalPointDistribution::Polygon_t expected = newpolygon;
899 expected.pop_front(); // remove first point
900 expected.pop_front(); // remove second point
901 SphericalPointDistribution::Polygon_t remaining =
902 SphericalPointDistribution::matchSphericalPointDistributions(
903 polygon,
904 newpolygon);
905// CPPUNIT_ASSERT_EQUAL( expected, remaining );
906 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
907 // also slightly perturbed
908 const double amplitude = 0.05;
909 perturbPolygon(polygon, amplitude);
910 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
911 }
912
913 // test with two points, full rotation
914 {
915 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
916 SphericalPointDistribution::WeightedPolygon_t polygon;
917 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180.*M_PI), 1);
918 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180.*M_PI), 1);
919 SphericalPointDistribution::Polygon_t newpolygon =
920 SPD.get<5>();
921 SphericalPointDistribution::Polygon_t expected = newpolygon;
922 expected.pop_front(); // remove first point
923 expected.pop_front(); // remove second point
924 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
925 iter != expected.end(); ++iter)
926 *iter = RotationAxis.rotateVector(*iter, 47.6/180.*M_PI);
927 SphericalPointDistribution::Polygon_t remaining =
928 SphericalPointDistribution::matchSphericalPointDistributions(
929 polygon,
930 newpolygon);
931 // the three remaining points sit on a plane that may be rotated arbitrarily
932 // so we cannot simply check for equality between expected and remaining
933 // hence, we just check that they are orthogonal to the first two points
934 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
935 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
936 fixiter != polygon.end(); ++fixiter) {
937 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
938 iter != remaining.end(); ++iter) {
939 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
940 }
941 }
942 }
943
944 // test with three points, matching trivially
945 {
946 SphericalPointDistribution::WeightedPolygon_t polygon;
947 polygon += std::make_pair( Vector(1.,0.,0.), 1);
948 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
949 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
950 SphericalPointDistribution::Polygon_t newpolygon =
951 SPD.get<5>();
952 SphericalPointDistribution::Polygon_t expected = newpolygon;
953 expected.pop_front(); // remove first point
954 expected.pop_front(); // remove second point
955 expected.pop_front(); // remove third point
956 SphericalPointDistribution::Polygon_t remaining =
957 SphericalPointDistribution::matchSphericalPointDistributions(
958 polygon,
959 newpolygon);
960// CPPUNIT_ASSERT_EQUAL( expected, remaining );
961 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
962 // also slightly perturbed
963 const double amplitude = 0.05;
964 perturbPolygon(polygon, amplitude);
965 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
966 }
967
968 // test with three points, full rotation
969 {
970 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
971 SphericalPointDistribution::WeightedPolygon_t polygon;
972 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
973 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
974 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
975 SphericalPointDistribution::Polygon_t newpolygon =
976 SPD.get<5>();
977 SphericalPointDistribution::Polygon_t expected = newpolygon;
978 expected.pop_front(); // remove first point
979 expected.pop_front(); // remove second point
980 expected.pop_front(); // remove third point
981 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
982 iter != expected.end(); ++iter)
983 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
984 SphericalPointDistribution::Polygon_t remaining =
985 SphericalPointDistribution::matchSphericalPointDistributions(
986 polygon,
987 newpolygon);
988// CPPUNIT_ASSERT_EQUAL( expected, remaining );
989 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
990 // also slightly perturbed
991 const double amplitude = 0.05;
992 perturbPolygon(polygon, amplitude);
993 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
994 }
995}
996
997/** UnitTest for matchSphericalPointDistributions() with six points
998 */
999void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_6()
1000{
1001 SphericalPointDistribution SPD(1.);
1002
1003 // test with one point, matching trivially
1004 {
1005 SphericalPointDistribution::WeightedPolygon_t polygon;
1006 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1007 SphericalPointDistribution::Polygon_t newpolygon =
1008 SPD.get<6>();
1009 SphericalPointDistribution::Polygon_t expected = newpolygon;
1010 expected.pop_front(); // remove first point
1011 SphericalPointDistribution::Polygon_t remaining =
1012 SphericalPointDistribution::matchSphericalPointDistributions(
1013 polygon,
1014 newpolygon);
1015// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1016 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1017 }
1018
1019 // test with one point, just a flip of axis
1020 {
1021 SphericalPointDistribution::WeightedPolygon_t polygon;
1022 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1023 SphericalPointDistribution::Polygon_t newpolygon =
1024 SPD.get<6>();
1025 SphericalPointDistribution::Polygon_t expected = newpolygon;
1026 expected.pop_front(); // remove first point
1027 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1028 iter != expected.end(); ++iter) {
1029 std::swap((*iter)[0], (*iter)[1]);
1030 (*iter)[0] *= -1.;
1031 }
1032 SphericalPointDistribution::Polygon_t remaining =
1033 SphericalPointDistribution::matchSphericalPointDistributions(
1034 polygon,
1035 newpolygon);
1036// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1037 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1038 }
1039
1040 // test with two points, matching trivially
1041 {
1042 SphericalPointDistribution::WeightedPolygon_t polygon;
1043 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1044 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1045 SphericalPointDistribution::Polygon_t newpolygon =
1046 SPD.get<6>();
1047 SphericalPointDistribution::Polygon_t expected = newpolygon;
1048 expected.pop_front(); // remove first point
1049 expected.pop_front(); // remove second spoint
1050 SphericalPointDistribution::Polygon_t remaining =
1051 SphericalPointDistribution::matchSphericalPointDistributions(
1052 polygon,
1053 newpolygon);
1054// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1055 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1056 // also slightly perturbed
1057 const double amplitude = 0.05;
1058 perturbPolygon(polygon, amplitude);
1059 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1060 }
1061
1062 // test with two points, full rotation
1063 {
1064 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1065 SphericalPointDistribution::WeightedPolygon_t polygon;
1066 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1067 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1068 SphericalPointDistribution::Polygon_t newpolygon =
1069 SPD.get<6>();
1070 SphericalPointDistribution::Polygon_t expected = newpolygon;
1071 expected.pop_front(); // remove first point
1072 expected.pop_front(); // remove second spoint
1073 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1074 iter != expected.end(); ++iter)
1075 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1076 SphericalPointDistribution::Polygon_t remaining =
1077 SphericalPointDistribution::matchSphericalPointDistributions(
1078 polygon,
1079 newpolygon);
1080 // the four remaining points sit on a plane that may have been rotated arbitrarily
1081 // so we cannot simply check for equality between expected and remaining
1082 // hence, we just check that they are orthogonal to the first two points
1083 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1084 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1085 fixiter != polygon.end(); ++fixiter) {
1086 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1087 iter != remaining.end(); ++iter) {
1088 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1089 }
1090 }
1091 }
1092
1093 // test with three points, matching trivially
1094 {
1095 SphericalPointDistribution::WeightedPolygon_t polygon;
1096 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1097 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1098 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
1099 SphericalPointDistribution::Polygon_t newpolygon =
1100 SPD.get<6>();
1101 SphericalPointDistribution::Polygon_t expected = newpolygon;
1102 expected.pop_front(); // remove first point
1103 expected.pop_front(); // remove second point
1104 expected.pop_front(); // remove third point
1105 SphericalPointDistribution::Polygon_t remaining =
1106 SphericalPointDistribution::matchSphericalPointDistributions(
1107 polygon,
1108 newpolygon);
1109// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1110 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1111 // also slightly perturbed
1112 const double amplitude = 0.05;
1113 perturbPolygon(polygon, amplitude);
1114 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1115 }
1116
1117 // test with three points, full rotation
1118 {
1119 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1120 SphericalPointDistribution::WeightedPolygon_t polygon;
1121 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1122 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1123 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
1124 SphericalPointDistribution::Polygon_t newpolygon =
1125 SPD.get<6>();
1126 SphericalPointDistribution::Polygon_t expected = newpolygon;
1127 expected.pop_front(); // remove first point
1128 expected.pop_front(); // remove second point
1129 expected.pop_front(); // remove third point
1130 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1131 iter != expected.end(); ++iter)
1132 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1133 SphericalPointDistribution::Polygon_t remaining =
1134 SphericalPointDistribution::matchSphericalPointDistributions(
1135 polygon,
1136 newpolygon);
1137// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1138 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1139 // also slightly perturbed
1140 const double amplitude = 0.05;
1141 perturbPolygon(polygon, amplitude);
1142 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1143 }
1144}
1145
1146/** UnitTest for matchSphericalPointDistributions() with seven points
1147 */
1148void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_7()
1149{
1150 SphericalPointDistribution SPD(1.);
1151
1152 // test with one point, matching trivially
1153 {
1154 SphericalPointDistribution::WeightedPolygon_t polygon;
1155 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1156 SphericalPointDistribution::Polygon_t newpolygon =
1157 SPD.get<7>();
1158 SphericalPointDistribution::Polygon_t expected = newpolygon;
1159 expected.pop_front(); // remove first point
1160 SphericalPointDistribution::Polygon_t remaining =
1161 SphericalPointDistribution::matchSphericalPointDistributions(
1162 polygon,
1163 newpolygon);
1164// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1165 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1166 }
1167
1168 // test with one point, just a flip of axis
1169 {
1170 SphericalPointDistribution::WeightedPolygon_t polygon;
1171 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1172 SphericalPointDistribution::Polygon_t newpolygon =
1173 SPD.get<7>();
1174 SphericalPointDistribution::Polygon_t expected = newpolygon;
1175 expected.pop_front(); // remove first point
1176 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1177 iter != expected.end(); ++iter) {
1178 std::swap((*iter)[0], (*iter)[1]);
1179 (*iter)[0] *= -1.;
1180 }
1181 SphericalPointDistribution::Polygon_t remaining =
1182 SphericalPointDistribution::matchSphericalPointDistributions(
1183 polygon,
1184 newpolygon);
1185// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1186 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1187 }
1188
1189 // test with two points, matching trivially
1190 {
1191 SphericalPointDistribution::WeightedPolygon_t polygon;
1192 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1193 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1194 SphericalPointDistribution::Polygon_t newpolygon =
1195 SPD.get<7>();
1196 SphericalPointDistribution::Polygon_t expected = newpolygon;
1197 expected.pop_front(); // remove first point
1198 expected.pop_front(); // remove second point
1199 SphericalPointDistribution::Polygon_t remaining =
1200 SphericalPointDistribution::matchSphericalPointDistributions(
1201 polygon,
1202 newpolygon);
1203// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1204 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1205 // also slightly perturbed
1206 const double amplitude = 0.05;
1207 perturbPolygon(polygon, amplitude);
1208 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1209 }
1210
1211 // test with two points, full rotation
1212 {
1213 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1214 SphericalPointDistribution::WeightedPolygon_t polygon;
1215 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1216 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1217 SphericalPointDistribution::Polygon_t newpolygon =
1218 SPD.get<7>();
1219 SphericalPointDistribution::Polygon_t expected = newpolygon;
1220 expected.pop_front(); // remove first point
1221 expected.pop_front(); // remove second point
1222 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1223 iter != expected.end(); ++iter)
1224 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1225 SphericalPointDistribution::Polygon_t remaining =
1226 SphericalPointDistribution::matchSphericalPointDistributions(
1227 polygon,
1228 newpolygon);
1229 // the five remaining points sit on a plane that may have been rotated arbitrarily
1230 // so we cannot simply check for equality between expected and remaining
1231 // hence, we just check that they are orthogonal to the first two points
1232 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1233 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1234 fixiter != polygon.end(); ++fixiter) {
1235 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1236 iter != remaining.end(); ++iter) {
1237 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1238 }
1239 }
1240 }
1241
1242 // test with three points, matching trivially
1243 {
1244 SphericalPointDistribution::WeightedPolygon_t polygon;
1245 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1246 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1247 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
1248 SphericalPointDistribution::Polygon_t newpolygon =
1249 SPD.get<7>();
1250 SphericalPointDistribution::Polygon_t expected = newpolygon;
1251 expected.pop_front(); // remove first point
1252 expected.pop_front(); // remove second point
1253 expected.pop_front(); // remove third point
1254 SphericalPointDistribution::Polygon_t remaining =
1255 SphericalPointDistribution::matchSphericalPointDistributions(
1256 polygon,
1257 newpolygon);
1258// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1259 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1260 // also slightly perturbed
1261 const double amplitude = 0.05;
1262 perturbPolygon(polygon, amplitude);
1263 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1264 }
1265
1266 // test with three points, full rotation
1267 {
1268 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1269 SphericalPointDistribution::WeightedPolygon_t polygon;
1270 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1271 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1272 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
1273 SphericalPointDistribution::Polygon_t newpolygon =
1274 SPD.get<7>();
1275 SphericalPointDistribution::Polygon_t expected = newpolygon;
1276 expected.pop_front(); // remove first point
1277 expected.pop_front(); // remove second point
1278 expected.pop_front(); // remove third point
1279 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1280 iter != expected.end(); ++iter)
1281 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1282 SphericalPointDistribution::Polygon_t remaining =
1283 SphericalPointDistribution::matchSphericalPointDistributions(
1284 polygon,
1285 newpolygon);
1286// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1287 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1288 // also slightly perturbed
1289 const double amplitude = 0.05;
1290 perturbPolygon(polygon, amplitude);
1291 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1292 }
1293}
1294
1295/** UnitTest for matchSphericalPointDistributions() with eight points
1296 */
1297void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_8()
1298{
1299 SphericalPointDistribution SPD(1.);
1300
1301 // test with one point, matching trivially
1302 {
1303 SphericalPointDistribution::WeightedPolygon_t polygon;
1304 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1305 SphericalPointDistribution::Polygon_t newpolygon =
1306 SPD.get<8>();
1307 SphericalPointDistribution::Polygon_t expected = newpolygon;
1308 expected.pop_front(); // remove first point
1309 SphericalPointDistribution::Polygon_t remaining =
1310 SphericalPointDistribution::matchSphericalPointDistributions(
1311 polygon,
1312 newpolygon);
1313// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1314 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1315 }
1316
1317 // test with one point, just a flip of axis
1318 {
1319 SphericalPointDistribution::WeightedPolygon_t polygon;
1320 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1321 SphericalPointDistribution::Polygon_t newpolygon =
1322 SPD.get<8>();
1323 SphericalPointDistribution::Polygon_t expected = newpolygon;
1324 expected.pop_front(); // remove first point
1325 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1326 iter != expected.end(); ++iter) {
1327 std::swap((*iter)[0], (*iter)[1]);
1328 (*iter)[0] *= -1.;
1329 }
1330 SphericalPointDistribution::Polygon_t remaining =
1331 SphericalPointDistribution::matchSphericalPointDistributions(
1332 polygon,
1333 newpolygon);
1334// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1335 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1336 }
1337
1338 // test with two points, matching trivially
1339 {
1340 SphericalPointDistribution::WeightedPolygon_t polygon;
1341 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1342 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1343 SphericalPointDistribution::Polygon_t newpolygon =
1344 SPD.get<8>();
1345 SphericalPointDistribution::Polygon_t expected = newpolygon;
1346 expected.pop_front(); // remove first point
1347 expected.pop_front(); // remove second point
1348 SphericalPointDistribution::Polygon_t remaining =
1349 SphericalPointDistribution::matchSphericalPointDistributions(
1350 polygon,
1351 newpolygon);
1352// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1353 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1354 // also slightly perturbed
1355 const double amplitude = 0.05;
1356 perturbPolygon(polygon, amplitude);
1357 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1358 }
1359
1360 // test with two points, full rotation
1361 {
1362 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1363 SphericalPointDistribution::WeightedPolygon_t polygon;
1364 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1365 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1366 SphericalPointDistribution::Polygon_t newpolygon =
1367 SPD.get<8>();
1368 SphericalPointDistribution::Polygon_t expected = newpolygon;
1369 expected.pop_front(); // remove first point
1370 expected.pop_front(); // remove second point
1371 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1372 iter != expected.end(); ++iter)
1373 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1374 SphericalPointDistribution::Polygon_t remaining =
1375 SphericalPointDistribution::matchSphericalPointDistributions(
1376 polygon,
1377 newpolygon);
1378 // the six remaining points sit on two planes that may have been rotated arbitrarily
1379 // so we cannot simply check for equality between expected and remaining
1380 // hence, we just check that they are orthogonal to the first two points
1381 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1382 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1383 fixiter != polygon.end(); ++fixiter) {
1384 SphericalPointDistribution::Polygon_t::const_iterator expectiter = expected.begin();
1385 SphericalPointDistribution::Polygon_t::const_iterator remainiter = remaining.begin();
1386 for (;remainiter != remaining.end(); ++expectiter, ++remainiter) {
1387 // check that points in expected/remaining have same angle to the given ones
1388// CPPUNIT_ASSERT_EQUAL( (*expectiter).Angle(*fixiter), (*remainiter).Angle(*fixiter) );
1389 CPPUNIT_ASSERT( fabs( (*expectiter).Angle(fixiter->first) - (*remainiter).Angle(fixiter->first) )
1390 < std::numeric_limits<double>::epsilon()*1e4 );
1391 }
1392 }
1393 }
1394
1395 // test with three points, matching trivially
1396 {
1397 SphericalPointDistribution::WeightedPolygon_t polygon;
1398 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1399 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1400 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0, 0.0), 1);
1401 SphericalPointDistribution::Polygon_t newpolygon =
1402 SPD.get<8>();
1403 SphericalPointDistribution::Polygon_t expected = newpolygon;
1404 expected.pop_front(); // remove first point
1405 expected.pop_front(); // remove second point
1406 expected.pop_front(); // remove third point
1407 SphericalPointDistribution::Polygon_t remaining =
1408 SphericalPointDistribution::matchSphericalPointDistributions(
1409 polygon,
1410 newpolygon);
1411// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1412 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1413 // also slightly perturbed
1414 const double amplitude = 0.05;
1415 perturbPolygon(polygon, amplitude);
1416 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1417 }
1418
1419 // test with three points, full rotation
1420 {
1421 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1422 SphericalPointDistribution::WeightedPolygon_t polygon;
1423 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1424 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1425 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0, 0.0), 47.6/180*M_PI), 1);
1426 SphericalPointDistribution::Polygon_t newpolygon =
1427 SPD.get<8>();
1428 SphericalPointDistribution::Polygon_t expected = newpolygon;
1429 expected.pop_front(); // remove first point
1430 expected.pop_front(); // remove second point
1431 expected.pop_front(); // remove third point
1432 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1433 iter != expected.end(); ++iter)
1434 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1435 SphericalPointDistribution::Polygon_t remaining =
1436 SphericalPointDistribution::matchSphericalPointDistributions(
1437 polygon,
1438 newpolygon);
1439// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1440 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1441 // also slightly perturbed
1442 const double amplitude = 0.05;
1443 perturbPolygon(polygon, amplitude);
1444 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1445 }
1446}
Note: See TracBrowser for help on using the repository browser.