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

Last change on this file since a52369 was 46e561, checked in by Frederik Heber <heber@…>, 9 years ago

Fixing getConnectionTest() due to ambiguous tesselation.

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