source: src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.cpp@ 36bd59

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion GeometryObjects Gui_displays_atomic_force_velocity IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 36bd59 was 2ccdf4, checked in by Frederik Heber <heber@…>, 9 years ago

Fixing getConnectionTest() due to ambiguous tesselation.

  • with N=8 with polygonal faces. Similarly, with N=9,10,11,12,14 we also face ambiguities. As we only need up to N=8, we leave it at less strict test that only checks the number of edges to be within certain bounds.
  • FIX: Fixed memory leak in connection with TesselPointSTLList.
  • Property mode set to 100644
File size: 72.2 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/** The getConnectionTest test functions are templated. We only implement
278 * special cases here where we need to override the behavior found in there.
279 */
280
281/** UnitTest for getConnections()
282 */
283template <>
284void SphericalPointDistributionTest_assistant::getConnectionTest<0>()
285{
286 const int N=0;
287 SphericalPointDistribution SPD(1.);
288
289 // create empty adjacency
290 SphericalPointDistribution::adjacency_t adjacency;
291
292 // get the implemented connections
293 SphericalPointDistribution::adjacency_t expected =
294 SPD.getConnections<N>();
295
296 // and compare the two
297 CPPUNIT_ASSERT_EQUAL( expected, adjacency );
298}
299
300/** UnitTest for getConnections()
301 */
302template <>
303void SphericalPointDistributionTest_assistant::getConnectionTest<1>()
304{
305 const int N=1;
306 SphericalPointDistribution SPD(1.);
307
308 // create empty adjacency
309 SphericalPointDistribution::adjacency_t adjacency;
310
311 // get the implemented connections
312 SphericalPointDistribution::adjacency_t expected =
313 SPD.getConnections<N>();
314
315 // and compare the two
316 CPPUNIT_ASSERT_EQUAL( expected, adjacency );
317}
318
319/** UnitTest for getConnections()
320 */
321template <>
322void SphericalPointDistributionTest_assistant::getConnectionTest<2>()
323{
324 const int N=2;
325 SphericalPointDistribution SPD(1.);
326
327 // create empty adjacency
328 SphericalPointDistribution::adjacency_t adjacency;
329 adjacency +=
330 make_pair<
331 unsigned int,
332 SphericalPointDistribution::IndexSet_t >
333 (0, list_of<unsigned int>(1));
334 adjacency +=
335 make_pair<
336 unsigned int,
337 SphericalPointDistribution::IndexSet_t >
338 (1, list_of<unsigned int>(0));
339
340 // get the implemented connections
341 SphericalPointDistribution::adjacency_t expected =
342 SPD.getConnections<N>();
343
344 // and compare the two
345 CPPUNIT_ASSERT_EQUAL( expected, adjacency );
346}
347
348void freeTesselPointSTLList(TesselPointSTLList &_Corners)
349{
350 for (TesselPointSTLList::iterator iter = _Corners.begin();
351 !_Corners.empty(); iter = _Corners.begin()) {
352 delete *iter;
353 _Corners.erase(iter);
354 }
355}
356
357template <int N> SphericalPointDistribution::adjacency_t getAdjacencyConnections()
358{
359 SphericalPointDistribution SPD(1.);
360 // get the points and convert into TesselPoint list
361 SphericalPointDistribution::Polygon_t newpolygon = SPD.get<N>();
362 TesselPointSTLList Corners;
363 SphericalPointDistribution::IndexList_t indices(N);
364 std::generate(indices.begin(), indices.end(), UniqueNumber);
365 std::transform(
366 newpolygon.begin(), newpolygon.end(),
367 indices.begin(),
368 std::back_inserter(Corners),
369 VectorToTesselPoint());
370
371 // create the tesselation
372 const double SPHERERADIUS = 1.5;
373 Tesselation TesselStruct;
374 PointCloudAdaptor<TesselPointSTLList> cloud(&Corners, "TesselPointSTLList");
375 TesselStruct(cloud, SPHERERADIUS);
376
377 // create a adjacency list from a tesselation of the (convex set of) points
378 SphericalPointDistribution::adjacency_t adjacency;
379 for (LineMap::const_iterator iter = TesselStruct.LinesOnBoundary.begin();
380 iter != TesselStruct.LinesOnBoundary.end(); ++iter) {
381 const BoundaryLineSet * const line = iter->second;
382 {
383 std::pair< SphericalPointDistribution::adjacency_t::iterator, bool > inserter =
384 adjacency.insert(
385 std::make_pair(
386 line->endpoints[0]->Nr,
387 SphericalPointDistribution::IndexSet_t() ));
388 inserter.first->second.insert(line->endpoints[1]->Nr);
389 LOG(6, "DEBUG: Inserting " << line->endpoints[0]->Nr << "," << line->endpoints[1]->Nr);
390 }
391 {
392 std::pair< SphericalPointDistribution::adjacency_t::iterator, bool > inserter =
393 adjacency.insert(
394 std::make_pair(
395 line->endpoints[1]->Nr,
396 SphericalPointDistribution::IndexSet_t() ));
397 inserter.first->second.insert(line->endpoints[0]->Nr);
398 LOG(6, "DEBUG: Inserting " << line->endpoints[1]->Nr << "," << line->endpoints[0]->Nr);
399 }
400 }
401
402 // free allocated TesselPoints
403 freeTesselPointSTLList(Corners);
404
405 LOG(2, "INFO: adjacency is " << adjacency);
406
407 return adjacency;
408}
409
410template <int N> SphericalPointDistribution::adjacency_t getExpectedConnections()
411{
412 SphericalPointDistribution SPD(1.);
413
414 // get the implemented connections
415 SphericalPointDistribution::adjacency_t expected =
416 SPD.getConnections<N>();
417
418 LOG(2, "INFO: expected is " << expected);
419
420 return expected;
421}
422
423/** UnitTest for getConnections()
424 */
425template <>
426void SphericalPointDistributionTest_assistant::getConnectionTest<8>()
427{
428 const int N=8;
429
430 SphericalPointDistribution::adjacency_t adjacency = getAdjacencyConnections<N>();
431 SphericalPointDistribution::adjacency_t expected = getExpectedConnections<N>();
432
433 // and compare the two
434// CPPUNIT_ASSERT_EQUAL( expected, adjacency );
435
436 // with eight points we obtain a cube. The problem is that each side
437 // is a polygon with four corners that is ambiguous in the tesselation
438 // it receives. Hence, we cannot directly test the linking but only
439 // the properties.
440 size_t NumberEdges_expected = 0;
441 for (SphericalPointDistribution::adjacency_t::const_iterator iter = expected.begin();
442 iter != expected.begin(); ++iter) {
443 NumberEdges_expected += iter->second.size();
444 CPPUNIT_ASSERT( iter->second.size() >= 3 );
445 CPPUNIT_ASSERT( iter->second.size() <= 6 );
446 }
447 size_t NumberEdges_adjacency = 0;
448 for (SphericalPointDistribution::adjacency_t::const_iterator iter = adjacency.begin();
449 iter != adjacency.begin(); ++iter) {
450 NumberEdges_adjacency += iter->second.size();
451 CPPUNIT_ASSERT( iter->second.size() >= 3 );
452 CPPUNIT_ASSERT( iter->second.size() <= 6 );
453 }
454 CPPUNIT_ASSERT_EQUAL( NumberEdges_expected, NumberEdges_adjacency);
455}
456
457/** UnitTest for getConnections()
458 */
459template <>
460void SphericalPointDistributionTest_assistant::getConnectionTest<9>()
461{
462 const int N=9;
463
464 SphericalPointDistribution::adjacency_t adjacency = getAdjacencyConnections<N>();
465 SphericalPointDistribution::adjacency_t expected = getExpectedConnections<N>();
466
467 // and compare the two
468// CPPUNIT_ASSERT_EQUAL( expected, adjacency );
469
470 // with nine points we have a square on one end and an pentagon on the hand with
471 // some ambiguity. The problem is that each side
472 // is a polygon with four/five corners that is ambiguous in the tesselation
473 // it receives. Hence, we cannot directly test the linking but only
474 // the properties.
475 size_t NumberEdges_expected = 0;
476 for (SphericalPointDistribution::adjacency_t::const_iterator iter = expected.begin();
477 iter != expected.begin(); ++iter) {
478 NumberEdges_expected += iter->second.size();
479 CPPUNIT_ASSERT( iter->second.size() >= 4 );
480 CPPUNIT_ASSERT( iter->second.size() <= 5 );
481 }
482 size_t NumberEdges_adjacency = 0;
483 for (SphericalPointDistribution::adjacency_t::const_iterator iter = adjacency.begin();
484 iter != adjacency.begin(); ++iter) {
485 NumberEdges_adjacency += iter->second.size();
486 CPPUNIT_ASSERT( iter->second.size() >= 4 );
487 CPPUNIT_ASSERT( iter->second.size() <= 5 );
488 }
489 CPPUNIT_ASSERT_EQUAL( NumberEdges_expected, NumberEdges_adjacency);
490}
491
492/** UnitTest for getConnections()
493 */
494template <>
495void SphericalPointDistributionTest_assistant::getConnectionTest<10>()
496{
497 const int N=10;
498
499 SphericalPointDistribution::adjacency_t adjacency = getAdjacencyConnections<N>();
500 SphericalPointDistribution::adjacency_t expected = getExpectedConnections<N>();
501
502 // and compare the two
503// CPPUNIT_ASSERT_EQUAL( expected, adjacency );
504
505 // with ten points we have two pentagons with some ambiguity. The problem is
506 // that each side is a polygon with five corners that is ambiguous in the
507 // tesselation it receives. Hence, we cannot directly test the linking but only
508 // the properties.
509 size_t NumberEdges_expected = 0;
510 for (SphericalPointDistribution::adjacency_t::const_iterator iter = expected.begin();
511 iter != expected.begin(); ++iter) {
512 NumberEdges_expected += iter->second.size();
513 CPPUNIT_ASSERT( iter->second.size() >= 4 );
514 CPPUNIT_ASSERT( iter->second.size() <= 5 );
515 }
516 size_t NumberEdges_adjacency = 0;
517 for (SphericalPointDistribution::adjacency_t::const_iterator iter = adjacency.begin();
518 iter != adjacency.begin(); ++iter) {
519 NumberEdges_adjacency += iter->second.size();
520 CPPUNIT_ASSERT( iter->second.size() >= 4 );
521 CPPUNIT_ASSERT( iter->second.size() <= 5 );
522 }
523 CPPUNIT_ASSERT_EQUAL( NumberEdges_expected, NumberEdges_adjacency);
524}
525
526/** UnitTest for getConnections()
527 */
528template <>
529void SphericalPointDistributionTest_assistant::getConnectionTest<11>()
530{
531 const int N=11;
532
533 SphericalPointDistribution::adjacency_t adjacency = getAdjacencyConnections<N>();
534 SphericalPointDistribution::adjacency_t expected = getExpectedConnections<N>();
535
536 // and compare the two
537// CPPUNIT_ASSERT_EQUAL( expected, adjacency );
538
539 // again, we only check properties as tesselation has ambiguities.
540 size_t NumberEdges_expected = 0;
541 for (SphericalPointDistribution::adjacency_t::const_iterator iter = expected.begin();
542 iter != expected.begin(); ++iter) {
543 NumberEdges_expected += iter->second.size();
544 CPPUNIT_ASSERT( iter->second.size() >= 4 );
545 CPPUNIT_ASSERT( iter->second.size() <= 6 );
546 }
547 size_t NumberEdges_adjacency = 0;
548 for (SphericalPointDistribution::adjacency_t::const_iterator iter = adjacency.begin();
549 iter != adjacency.begin(); ++iter) {
550 NumberEdges_adjacency += iter->second.size();
551 CPPUNIT_ASSERT( iter->second.size() >= 4 );
552 CPPUNIT_ASSERT( iter->second.size() <= 6 );
553 }
554 CPPUNIT_ASSERT_EQUAL( NumberEdges_expected, NumberEdges_adjacency);
555}
556
557/** UnitTest for getConnections()
558 */
559template <>
560void SphericalPointDistributionTest_assistant::getConnectionTest<12>()
561{
562 const int N=12;
563
564 SphericalPointDistribution::adjacency_t adjacency = getAdjacencyConnections<N>();
565 SphericalPointDistribution::adjacency_t expected = getExpectedConnections<N>();
566
567 // and compare the two
568// CPPUNIT_ASSERT_EQUAL( expected, adjacency );
569
570 // again, we only check properties as tesselation has ambiguities.
571 size_t NumberEdges_expected = 0;
572 for (SphericalPointDistribution::adjacency_t::const_iterator iter = expected.begin();
573 iter != expected.begin(); ++iter) {
574 NumberEdges_expected += iter->second.size();
575 CPPUNIT_ASSERT( iter->second.size() >= 5 );
576 CPPUNIT_ASSERT( iter->second.size() <= 5 );
577 }
578 size_t NumberEdges_adjacency = 0;
579 for (SphericalPointDistribution::adjacency_t::const_iterator iter = adjacency.begin();
580 iter != adjacency.begin(); ++iter) {
581 NumberEdges_adjacency += iter->second.size();
582 CPPUNIT_ASSERT( iter->second.size() >= 5 );
583 CPPUNIT_ASSERT( iter->second.size() <= 5 );
584 }
585 CPPUNIT_ASSERT_EQUAL( NumberEdges_expected, NumberEdges_adjacency);
586}
587
588/** UnitTest for getConnections()
589 */
590template <>
591void SphericalPointDistributionTest_assistant::getConnectionTest<14>()
592{
593 const int N=14;
594
595 SphericalPointDistribution::adjacency_t adjacency = getAdjacencyConnections<N>();
596 SphericalPointDistribution::adjacency_t expected = getExpectedConnections<N>();
597
598 // and compare the two
599// CPPUNIT_ASSERT_EQUAL( expected, adjacency );
600
601 // again, we only check properties as tesselation has ambiguities.
602 size_t NumberEdges_expected = 0;
603 for (SphericalPointDistribution::adjacency_t::const_iterator iter = expected.begin();
604 iter != expected.begin(); ++iter) {
605 NumberEdges_expected += iter->second.size();
606 CPPUNIT_ASSERT( iter->second.size() >= 5 );
607 CPPUNIT_ASSERT( iter->second.size() <= 6 );
608 }
609 size_t NumberEdges_adjacency = 0;
610 for (SphericalPointDistribution::adjacency_t::const_iterator iter = adjacency.begin();
611 iter != adjacency.begin(); ++iter) {
612 NumberEdges_adjacency += iter->second.size();
613 CPPUNIT_ASSERT( iter->second.size() >= 5 );
614 CPPUNIT_ASSERT( iter->second.size() <= 6 );
615 }
616 CPPUNIT_ASSERT_EQUAL( NumberEdges_expected, NumberEdges_adjacency);
617}
618
619void perturbPolygon(
620 SphericalPointDistribution::WeightedPolygon_t &_polygon,
621 double _amplitude
622 )
623{
624 for (SphericalPointDistribution::WeightedPolygon_t::iterator iter = _polygon.begin();
625 iter != _polygon.end(); ++iter) {
626 Vector perturber;
627 perturber.GetOneNormalVector(iter->first);
628 perturber.Scale(_amplitude);
629 iter->first = iter->first + perturber;
630 (iter->first).Normalize();
631 }
632}
633
634/** UnitTest for joinPoints()
635 */
636void SphericalPointDistributionTest::joinPointsTest()
637{
638 // test with simple configuration of three points
639 {
640 SphericalPointDistribution::Polygon_t newpolygon;
641 newpolygon += Vector(1.,0.,0.);
642 newpolygon += Vector(0.,1.,0.);
643 newpolygon += Vector(0.,0.,1.);
644 SphericalPointDistribution::Polygon_t expectedpolygon = newpolygon;
645 SphericalPointDistribution::IndexTupleList_t matching;
646 matching += SphericalPointDistribution::IndexList_t(1,0);
647 matching += SphericalPointDistribution::IndexList_t(1,1);
648 matching += SphericalPointDistribution::IndexList_t(1,2);
649 SphericalPointDistribution::IndexList_t IndexList =
650 SphericalPointDistribution::joinPoints(
651 newpolygon,
652 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
653 matching);
654 SphericalPointDistribution::IndexList_t expected;
655 expected += 0,1,2;
656 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
657 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
658 }
659
660 // test with simple configuration of three points, only two are picked
661 {
662 SphericalPointDistribution::Polygon_t newpolygon;
663 newpolygon += Vector(1.,0.,0.);
664 newpolygon += Vector(0.,1.,0.);
665 newpolygon += Vector(0.,0.,1.);
666 SphericalPointDistribution::Polygon_t expectedpolygon = newpolygon;
667 SphericalPointDistribution::IndexTupleList_t matching;
668 matching += SphericalPointDistribution::IndexList_t(1,1);
669 matching += SphericalPointDistribution::IndexList_t(1,2);
670 SphericalPointDistribution::IndexList_t IndexList =
671 SphericalPointDistribution::joinPoints(
672 newpolygon,
673 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
674 matching);
675 SphericalPointDistribution::IndexList_t expected;
676 expected += 1,2;
677 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
678 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
679 }
680
681 // test with simple configuration of three points, two are joined
682 {
683 SphericalPointDistribution::Polygon_t newpolygon;
684 newpolygon += Vector(1.,0.,0.);
685 newpolygon += Vector(0.,1.,0.);
686 newpolygon += Vector(0.,0.,1.);
687 SphericalPointDistribution::Polygon_t expectedpolygon;
688 expectedpolygon += Vector(1.,0.,0.);
689 expectedpolygon += Vector(0.,M_SQRT1_2,M_SQRT1_2);
690 SphericalPointDistribution::IndexTupleList_t matching;
691 SphericalPointDistribution::IndexList_t joined;
692 joined += 1,2;
693 matching += SphericalPointDistribution::IndexList_t(1,0);
694 matching += joined;
695 SphericalPointDistribution::IndexList_t IndexList =
696 SphericalPointDistribution::joinPoints(
697 newpolygon,
698 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
699 matching);
700 SphericalPointDistribution::IndexList_t expected;
701 expected += 0,1;
702 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
703 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
704 }
705
706 // test with simple configuration of six points, two are joined, jumbled indices
707 {
708 SphericalPointDistribution::Polygon_t newpolygon;
709 newpolygon += Vector(1.,0.,1.);
710 newpolygon += Vector(1.,0.,0.);
711 newpolygon += Vector(1.,1.,0.);
712 newpolygon += Vector(0.,1.,0.);
713 newpolygon += Vector(0.,0.,1.);
714 newpolygon += Vector(1.,0.,1.);
715 SphericalPointDistribution::Polygon_t expectedpolygon;
716 expectedpolygon += Vector(1.,0.,1.);
717 expectedpolygon += Vector(1.,0.,0.);
718 expectedpolygon += Vector(1.,1.,0.);
719 expectedpolygon += Vector(1.,0.,1.);
720 expectedpolygon += Vector(0.,M_SQRT1_2,M_SQRT1_2); // new centers go last
721 SphericalPointDistribution::IndexTupleList_t matching;
722 SphericalPointDistribution::IndexList_t joined;
723 joined += 3,4;
724 matching += SphericalPointDistribution::IndexList_t(1,1);
725 matching += joined;
726 SphericalPointDistribution::IndexList_t IndexList =
727 SphericalPointDistribution::joinPoints(
728 newpolygon,
729 SphericalPointDistribution::VectorArray_t(newpolygon.begin(), newpolygon.end()),
730 matching);
731 SphericalPointDistribution::IndexList_t expected;
732 expected += 1,4;
733 CPPUNIT_ASSERT_EQUAL( expected, IndexList );
734 CPPUNIT_ASSERT_EQUAL( expectedpolygon, newpolygon );
735 }
736}
737
738/** UnitTest for matchSphericalPointDistributions() with two points
739 */
740void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_2()
741{
742 SphericalPointDistribution SPD(1.);
743 // test with one point, matching trivially
744 {
745 SphericalPointDistribution::WeightedPolygon_t polygon;
746 polygon += std::make_pair(Vector(1.,0.,0.), 1);
747 SphericalPointDistribution::Polygon_t newpolygon =
748 SPD.get<2>();
749 SphericalPointDistribution::Polygon_t expected;
750 expected += Vector(-1.,0.,0.);
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 }
758
759 // test with one point, just a flip of axis
760 {
761 SphericalPointDistribution::WeightedPolygon_t polygon;
762 polygon += std::make_pair( Vector(0.,1.,0.), 1);
763 SphericalPointDistribution::Polygon_t newpolygon =
764 SPD.get<2>();
765 SphericalPointDistribution::Polygon_t expected;
766 expected += Vector(0.,-1.,0.);
767 SphericalPointDistribution::Polygon_t remaining =
768 SphericalPointDistribution::matchSphericalPointDistributions(
769 polygon,
770 newpolygon);
771// CPPUNIT_ASSERT_EQUAL( expected, remaining );
772 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
773 }
774
775 // test with one point, just a flip to another axis
776 {
777 SphericalPointDistribution::WeightedPolygon_t polygon;
778 polygon += std::make_pair( Vector(0.,0.,-1.), 1);
779 SphericalPointDistribution::Polygon_t newpolygon =
780 SPD.get<2>();
781 SphericalPointDistribution::Polygon_t expected;
782 expected += Vector(0.,0.,1.);
783 SphericalPointDistribution::Polygon_t remaining =
784 SphericalPointDistribution::matchSphericalPointDistributions(
785 polygon,
786 newpolygon);
787// CPPUNIT_ASSERT_EQUAL( expected, remaining );
788 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
789 }
790
791 // test with one point, full rotation
792 {
793 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
794 SphericalPointDistribution::WeightedPolygon_t polygon;
795 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
796 SphericalPointDistribution::Polygon_t newpolygon =
797 SPD.get<2>();
798 SphericalPointDistribution::Polygon_t expected;
799 expected += RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI);
800 SphericalPointDistribution::Polygon_t remaining =
801 SphericalPointDistribution::matchSphericalPointDistributions(
802 polygon,
803 newpolygon);
804// CPPUNIT_ASSERT_EQUAL( expected, remaining );
805 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
806 }
807}
808
809/** UnitTest for matchSphericalPointDistributions() with three points
810 */
811void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_3()
812{
813 SphericalPointDistribution SPD(1.);
814
815 // test with one point, matching trivially
816 {
817 SphericalPointDistribution::WeightedPolygon_t polygon;
818 polygon += std::make_pair( Vector(1.,0.,0.), 1);
819 SphericalPointDistribution::Polygon_t newpolygon =
820 SPD.get<3>();
821 SphericalPointDistribution::Polygon_t expected = newpolygon;
822 expected.pop_front(); // remove first point
823 SphericalPointDistribution::Polygon_t remaining =
824 SphericalPointDistribution::matchSphericalPointDistributions(
825 polygon,
826 newpolygon);
827// CPPUNIT_ASSERT_EQUAL( expected, remaining );
828 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
829 }
830
831 // test with one point, just a flip of x and y axis
832 {
833 SphericalPointDistribution::WeightedPolygon_t polygon;
834 polygon += std::make_pair( Vector(0.,1.,0.), 1);
835 SphericalPointDistribution::Polygon_t newpolygon =
836 SPD.get<3>();
837 SphericalPointDistribution::Polygon_t expected = newpolygon;
838 expected.pop_front(); // remove first point
839 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
840 iter != expected.end(); ++iter) {
841 std::swap((*iter)[0], (*iter)[1]);
842 (*iter)[0] *= -1.;
843 }
844 SphericalPointDistribution::Polygon_t remaining =
845 SphericalPointDistribution::matchSphericalPointDistributions(
846 polygon,
847 newpolygon);
848// CPPUNIT_ASSERT_EQUAL( expected, remaining );
849 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
850 }
851
852 // test with two points, matching trivially
853 {
854 SphericalPointDistribution::WeightedPolygon_t polygon;
855 polygon += std::make_pair( Vector(1.,0.,0.), 1);
856 polygon += std::make_pair( Vector(-0.5, sqrt(3)*0.5,0.), 1);
857 SphericalPointDistribution::Polygon_t newpolygon =
858 SPD.get<3>();
859 SphericalPointDistribution::Polygon_t expected = newpolygon;
860 expected.pop_front(); // remove first point
861 expected.pop_front(); // remove second 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 // also slightly perturbed
869 const double amplitude = 0.05;
870 perturbPolygon(polygon, amplitude);
871 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
872 }
873
874 // test with two points, full rotation
875 {
876 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
877 SphericalPointDistribution::WeightedPolygon_t polygon;
878 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
879 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
880 SphericalPointDistribution::Polygon_t newpolygon =
881 SPD.get<3>();
882 SphericalPointDistribution::Polygon_t expected = newpolygon;
883 expected.pop_front(); // remove first point
884 expected.pop_front(); // remove second point
885 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
886 iter != expected.end(); ++iter)
887 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
888 SphericalPointDistribution::Polygon_t remaining =
889 SphericalPointDistribution::matchSphericalPointDistributions(
890 polygon,
891 newpolygon);
892// CPPUNIT_ASSERT_EQUAL( expected, remaining );
893 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
894 // also slightly perturbed
895 const double amplitude = 0.05;
896 perturbPolygon(polygon, amplitude);
897 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
898 }
899
900 // test with three points, matching trivially
901 {
902 SphericalPointDistribution::WeightedPolygon_t polygon;
903 polygon += std::make_pair( Vector(1.,0.,0.), 1);
904 polygon += std::make_pair( Vector(-0.5, sqrt(3)*0.5,0.), 1);
905 polygon += std::make_pair( Vector(-0.5, -sqrt(3)*0.5,0.), 1);
906 SphericalPointDistribution::Polygon_t newpolygon =
907 SPD.get<3>();
908 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
909 SphericalPointDistribution::Polygon_t remaining =
910 SphericalPointDistribution::matchSphericalPointDistributions(
911 polygon,
912 newpolygon);
913// CPPUNIT_ASSERT_EQUAL( expected, remaining );
914 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
915 // also slightly perturbed
916 const double amplitude = 0.05;
917 perturbPolygon(polygon, amplitude);
918 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
919 }
920
921
922 // test with three points, full rotation
923 {
924 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
925 SphericalPointDistribution::WeightedPolygon_t polygon;
926 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
927 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
928 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, -sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
929 SphericalPointDistribution::Polygon_t newpolygon =
930 SPD.get<3>();
931 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
932 SphericalPointDistribution::Polygon_t remaining =
933 SphericalPointDistribution::matchSphericalPointDistributions(
934 polygon,
935 newpolygon);
936// CPPUNIT_ASSERT_EQUAL( expected, remaining );
937 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
938 // also slightly perturbed
939 const double amplitude = 0.05;
940 perturbPolygon(polygon, amplitude);
941 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
942 }
943}
944
945/** UnitTest for matchSphericalPointDistributions() with four points
946 */
947void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_4()
948{
949 SphericalPointDistribution SPD(1.);
950
951 // test with one point, matching trivially
952 {
953 SphericalPointDistribution::WeightedPolygon_t polygon;
954 polygon += std::make_pair( Vector(1.,0.,0.), 1);
955 SphericalPointDistribution::Polygon_t newpolygon =
956 SPD.get<4>();
957 SphericalPointDistribution::Polygon_t expected = newpolygon;
958 expected.pop_front(); // remove first point
959 SphericalPointDistribution::Polygon_t remaining =
960 SphericalPointDistribution::matchSphericalPointDistributions(
961 polygon,
962 newpolygon);
963 // CPPUNIT_ASSERT_EQUAL( expected, remaining );
964 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
965 }
966
967 // test with one point, just a flip of axis
968 {
969 SphericalPointDistribution::WeightedPolygon_t polygon;
970 polygon += std::make_pair( Vector(0.,1.,0.), 1);
971 SphericalPointDistribution::Polygon_t newpolygon =
972 SPD.get<4>();
973 SphericalPointDistribution::Polygon_t expected = newpolygon;
974 expected.pop_front(); // remove first point
975 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
976 iter != expected.end(); ++iter) {
977 std::swap((*iter)[0], (*iter)[1]);
978 (*iter)[0] *= -1.;
979 }
980 SphericalPointDistribution::Polygon_t remaining =
981 SphericalPointDistribution::matchSphericalPointDistributions(
982 polygon,
983 newpolygon);
984// CPPUNIT_ASSERT_EQUAL( expected, remaining );
985 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
986 }
987
988 // test with two points, matching trivially
989 {
990 SphericalPointDistribution::WeightedPolygon_t polygon;
991 polygon += std::make_pair( Vector(1.,0.,0.), 1);
992 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
993 SphericalPointDistribution::Polygon_t newpolygon =
994 SPD.get<4>();
995 SphericalPointDistribution::Polygon_t expected = newpolygon;
996 expected.pop_front(); // remove first point
997 expected.pop_front(); // remove second point
998 SphericalPointDistribution::Polygon_t remaining =
999 SphericalPointDistribution::matchSphericalPointDistributions(
1000 polygon,
1001 newpolygon);
1002// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1003 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1004 // also slightly perturbed
1005 const double amplitude = 0.05;
1006 perturbPolygon(polygon, amplitude);
1007 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1008 }
1009
1010 // test with two points, matching trivially, also with slightly perturbed
1011 {
1012 SphericalPointDistribution::WeightedPolygon_t polygon;
1013 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1014 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
1015 SphericalPointDistribution::Polygon_t newpolygon =
1016 SPD.get<4>();
1017 SphericalPointDistribution::Polygon_t expected = newpolygon;
1018 expected.pop_front(); // remove first point
1019 expected.pop_front(); // remove second point
1020 SphericalPointDistribution::Polygon_t remaining =
1021 SphericalPointDistribution::matchSphericalPointDistributions(
1022 polygon,
1023 newpolygon);
1024// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1025 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1026 // also slightly perturbed
1027 const double amplitude = 0.05;
1028 perturbPolygon(polygon, amplitude);
1029 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1030 }
1031
1032 // test with two points, full rotation
1033 {
1034 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1035 SphericalPointDistribution::WeightedPolygon_t polygon;
1036 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1037 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 47.6/180*M_PI), 1);
1038 SphericalPointDistribution::Polygon_t newpolygon =
1039 SPD.get<4>();
1040 SphericalPointDistribution::Polygon_t expected = newpolygon;
1041 expected.pop_front(); // remove first point
1042 expected.pop_front(); // remove second point
1043 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1044 iter != expected.end(); ++iter)
1045 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1046 SphericalPointDistribution::Polygon_t remaining =
1047 SphericalPointDistribution::matchSphericalPointDistributions(
1048 polygon,
1049 newpolygon);
1050// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1051 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1052 // also slightly perturbed
1053 const double amplitude = 0.05;
1054 perturbPolygon(polygon, amplitude);
1055 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1056 }
1057
1058 // test with three points, matching trivially
1059 {
1060 SphericalPointDistribution::WeightedPolygon_t polygon;
1061 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1062 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
1063 polygon += std::make_pair( Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 1);
1064 SphericalPointDistribution::Polygon_t newpolygon =
1065 SPD.get<4>();
1066 SphericalPointDistribution::Polygon_t expected = newpolygon;
1067 expected.pop_front(); // remove first point
1068 expected.pop_front(); // remove second point
1069 expected.pop_front(); // remove third point
1070 SphericalPointDistribution::Polygon_t remaining =
1071 SphericalPointDistribution::matchSphericalPointDistributions(
1072 polygon,
1073 newpolygon);
1074// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1075 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1076 // also slightly perturbed
1077 const double amplitude = 0.05;
1078 perturbPolygon(polygon, amplitude);
1079 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1080 }
1081
1082 // test with three points, full rotation
1083 {
1084 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1085 SphericalPointDistribution::WeightedPolygon_t polygon;
1086 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1087 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 47.6/180*M_PI), 1);
1088 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 47.6/180*M_PI), 1);
1089 SphericalPointDistribution::Polygon_t newpolygon =
1090 SPD.get<4>();
1091 SphericalPointDistribution::Polygon_t expected = newpolygon;
1092 expected.pop_front(); // remove first point
1093 expected.pop_front(); // remove second point
1094 expected.pop_front(); // remove third point
1095 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1096 iter != expected.end(); ++iter)
1097 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1098 SphericalPointDistribution::Polygon_t remaining =
1099 SphericalPointDistribution::matchSphericalPointDistributions(
1100 polygon,
1101 newpolygon);
1102// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1103 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1104 // also slightly perturbed
1105 const double amplitude = 0.05;
1106 perturbPolygon(polygon, amplitude);
1107 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1108 }
1109}
1110
1111/** UnitTest for matchSphericalPointDistributions() with four points and weights
1112 * not all equal to one.
1113 */
1114void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_multiple()
1115{
1116 SphericalPointDistribution SPD(1.);
1117
1118 // test with four points: one point having weight of two
1119 {
1120 SphericalPointDistribution::WeightedPolygon_t polygon;
1121 polygon += std::make_pair( Vector(1.,0.,0.), 2);
1122 SphericalPointDistribution::Polygon_t newpolygon =
1123 SPD.get<4>();
1124 SphericalPointDistribution::Polygon_t expected;
1125 expected += Vector(-0.5773502691896,-5.551115123126e-17,0.8164965809277);
1126 expected += Vector(-0.5773502691896,-5.551115123126e-17,-0.8164965809277);
1127 SphericalPointDistribution::Polygon_t remaining =
1128 SphericalPointDistribution::matchSphericalPointDistributions(
1129 polygon,
1130 newpolygon);
1131// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
1132// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1133 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1134 }
1135
1136 // test with five points: one point having weight of two
1137 {
1138 SphericalPointDistribution::WeightedPolygon_t polygon;
1139 polygon += std::make_pair( Vector(1.,0.,0.), 2);
1140 SphericalPointDistribution::Polygon_t newpolygon =
1141 SPD.get<5>();
1142 SphericalPointDistribution::Polygon_t expected;
1143 expected += Vector(-0.7071067811865,0.7071067811865,0);
1144 expected += Vector(-0.3535533905933,-0.3535533905933,0.8660254037844);
1145 expected += Vector(-0.3535533905933,-0.3535533905933,-0.8660254037844);
1146 SphericalPointDistribution::Polygon_t remaining =
1147 SphericalPointDistribution::matchSphericalPointDistributions(
1148 polygon,
1149 newpolygon);
1150// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
1151// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1152 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1153 }
1154
1155
1156 // test with five points: one point having weight of two, one weight of one
1157 {
1158 SphericalPointDistribution::WeightedPolygon_t polygon;
1159 polygon += std::make_pair( Vector(M_SQRT1_2,M_SQRT1_2,0.), 2);
1160 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1161 SphericalPointDistribution::Polygon_t newpolygon =
1162 SPD.get<5>();
1163 SphericalPointDistribution::Polygon_t expected;
1164 expected += Vector(0.3535533786708,-0.3535533955317,-0.8660254066357);
1165 expected += Vector(0.3535534025157,-0.3535533856548,0.8660254009332);
1166 SphericalPointDistribution::Polygon_t remaining =
1167 SphericalPointDistribution::matchSphericalPointDistributions(
1168 polygon,
1169 newpolygon);
1170// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
1171// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1172 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1173 }
1174
1175 // test with six points: two points each having weight of two
1176 {
1177 SphericalPointDistribution::WeightedPolygon_t polygon;
1178 polygon += std::make_pair( Vector(M_SQRT1_2,-M_SQRT1_2,0.), 2);
1179 polygon += std::make_pair( Vector(-M_SQRT1_2,M_SQRT1_2,0.), 2);
1180 SphericalPointDistribution::Polygon_t newpolygon =
1181 SPD.get<6>();
1182 SphericalPointDistribution::Polygon_t expected;
1183 expected += Vector(0.,0.,-1.);
1184 expected += Vector(0.,0.,1.);
1185 SphericalPointDistribution::Polygon_t remaining =
1186 SphericalPointDistribution::matchSphericalPointDistributions(
1187 polygon,
1188 newpolygon);
1189// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
1190// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1191 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1192 }
1193}
1194
1195/** UnitTest for matchSphericalPointDistributions() with five points
1196 */
1197void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_5()
1198{
1199 SphericalPointDistribution SPD(1.);
1200
1201 // test with one point, matching trivially
1202 {
1203 SphericalPointDistribution::WeightedPolygon_t polygon;
1204 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1205 SphericalPointDistribution::Polygon_t newpolygon =
1206 SPD.get<5>();
1207 SphericalPointDistribution::Polygon_t expected = newpolygon;
1208 expected.pop_front(); // remove first point
1209 SphericalPointDistribution::Polygon_t remaining =
1210 SphericalPointDistribution::matchSphericalPointDistributions(
1211 polygon,
1212 newpolygon);
1213// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1214 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1215 }
1216
1217 // test with one point, just a flip of axis
1218 {
1219 SphericalPointDistribution::WeightedPolygon_t polygon;
1220 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1221 SphericalPointDistribution::Polygon_t newpolygon =
1222 SPD.get<5>();
1223 SphericalPointDistribution::Polygon_t expected = newpolygon;
1224 expected.pop_front(); // remove first point
1225 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1226 iter != expected.end(); ++iter) {
1227 std::swap((*iter)[0], (*iter)[1]);
1228 (*iter)[0] *= -1.;
1229 }
1230 SphericalPointDistribution::Polygon_t remaining =
1231 SphericalPointDistribution::matchSphericalPointDistributions(
1232 polygon,
1233 newpolygon);
1234// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1235 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1236 }
1237
1238 // test with two points, matching trivially
1239 {
1240 SphericalPointDistribution::WeightedPolygon_t polygon;
1241 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1242 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1243 SphericalPointDistribution::Polygon_t newpolygon =
1244 SPD.get<5>();
1245 SphericalPointDistribution::Polygon_t expected = newpolygon;
1246 expected.pop_front(); // remove first point
1247 expected.pop_front(); // remove second point
1248 SphericalPointDistribution::Polygon_t remaining =
1249 SphericalPointDistribution::matchSphericalPointDistributions(
1250 polygon,
1251 newpolygon);
1252// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1253 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1254 // also slightly perturbed
1255 const double amplitude = 0.05;
1256 perturbPolygon(polygon, amplitude);
1257 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1258 }
1259
1260 // test with two points, full rotation
1261 {
1262 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1263 SphericalPointDistribution::WeightedPolygon_t polygon;
1264 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180.*M_PI), 1);
1265 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180.*M_PI), 1);
1266 SphericalPointDistribution::Polygon_t newpolygon =
1267 SPD.get<5>();
1268 SphericalPointDistribution::Polygon_t expected = newpolygon;
1269 expected.pop_front(); // remove first point
1270 expected.pop_front(); // remove second point
1271 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1272 iter != expected.end(); ++iter)
1273 *iter = RotationAxis.rotateVector(*iter, 47.6/180.*M_PI);
1274 SphericalPointDistribution::Polygon_t remaining =
1275 SphericalPointDistribution::matchSphericalPointDistributions(
1276 polygon,
1277 newpolygon);
1278 // the three remaining points sit on a plane that may be rotated arbitrarily
1279 // so we cannot simply check for equality between expected and remaining
1280 // hence, we just check that they are orthogonal to the first two points
1281 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1282 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1283 fixiter != polygon.end(); ++fixiter) {
1284 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1285 iter != remaining.end(); ++iter) {
1286 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1287 }
1288 }
1289 }
1290
1291 // test with three points, matching trivially
1292 {
1293 SphericalPointDistribution::WeightedPolygon_t polygon;
1294 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1295 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1296 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
1297 SphericalPointDistribution::Polygon_t newpolygon =
1298 SPD.get<5>();
1299 SphericalPointDistribution::Polygon_t expected = newpolygon;
1300 expected.pop_front(); // remove first point
1301 expected.pop_front(); // remove second point
1302 expected.pop_front(); // remove third point
1303 SphericalPointDistribution::Polygon_t remaining =
1304 SphericalPointDistribution::matchSphericalPointDistributions(
1305 polygon,
1306 newpolygon);
1307// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1308 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1309 // also slightly perturbed
1310 const double amplitude = 0.05;
1311 perturbPolygon(polygon, amplitude);
1312 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1313 }
1314
1315 // test with three points, full rotation
1316 {
1317 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1318 SphericalPointDistribution::WeightedPolygon_t polygon;
1319 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1320 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1321 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
1322 SphericalPointDistribution::Polygon_t newpolygon =
1323 SPD.get<5>();
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 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1329 iter != expected.end(); ++iter)
1330 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1331 SphericalPointDistribution::Polygon_t remaining =
1332 SphericalPointDistribution::matchSphericalPointDistributions(
1333 polygon,
1334 newpolygon);
1335// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1336 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1337 // also slightly perturbed
1338 const double amplitude = 0.05;
1339 perturbPolygon(polygon, amplitude);
1340 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1341 }
1342}
1343
1344/** UnitTest for matchSphericalPointDistributions() with six points
1345 */
1346void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_6()
1347{
1348 SphericalPointDistribution SPD(1.);
1349
1350 // test with one point, matching trivially
1351 {
1352 SphericalPointDistribution::WeightedPolygon_t polygon;
1353 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1354 SphericalPointDistribution::Polygon_t newpolygon =
1355 SPD.get<6>();
1356 SphericalPointDistribution::Polygon_t expected = newpolygon;
1357 expected.pop_front(); // remove first point
1358 SphericalPointDistribution::Polygon_t remaining =
1359 SphericalPointDistribution::matchSphericalPointDistributions(
1360 polygon,
1361 newpolygon);
1362// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1363 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1364 }
1365
1366 // test with one point, just a flip of axis
1367 {
1368 SphericalPointDistribution::WeightedPolygon_t polygon;
1369 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1370 SphericalPointDistribution::Polygon_t newpolygon =
1371 SPD.get<6>();
1372 SphericalPointDistribution::Polygon_t expected = newpolygon;
1373 expected.pop_front(); // remove first point
1374 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1375 iter != expected.end(); ++iter) {
1376 std::swap((*iter)[0], (*iter)[1]);
1377 (*iter)[0] *= -1.;
1378 }
1379 SphericalPointDistribution::Polygon_t remaining =
1380 SphericalPointDistribution::matchSphericalPointDistributions(
1381 polygon,
1382 newpolygon);
1383// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1384 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1385 }
1386
1387 // test with two points, matching trivially
1388 {
1389 SphericalPointDistribution::WeightedPolygon_t polygon;
1390 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1391 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1392 SphericalPointDistribution::Polygon_t newpolygon =
1393 SPD.get<6>();
1394 SphericalPointDistribution::Polygon_t expected = newpolygon;
1395 expected.pop_front(); // remove first point
1396 expected.pop_front(); // remove second spoint
1397 SphericalPointDistribution::Polygon_t remaining =
1398 SphericalPointDistribution::matchSphericalPointDistributions(
1399 polygon,
1400 newpolygon);
1401// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1402 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1403 // also slightly perturbed
1404 const double amplitude = 0.05;
1405 perturbPolygon(polygon, amplitude);
1406 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1407 }
1408
1409 // test with two points, full rotation
1410 {
1411 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1412 SphericalPointDistribution::WeightedPolygon_t polygon;
1413 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1414 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1415 SphericalPointDistribution::Polygon_t newpolygon =
1416 SPD.get<6>();
1417 SphericalPointDistribution::Polygon_t expected = newpolygon;
1418 expected.pop_front(); // remove first point
1419 expected.pop_front(); // remove second spoint
1420 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1421 iter != expected.end(); ++iter)
1422 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1423 SphericalPointDistribution::Polygon_t remaining =
1424 SphericalPointDistribution::matchSphericalPointDistributions(
1425 polygon,
1426 newpolygon);
1427 // the four remaining points sit on a plane that may have been rotated arbitrarily
1428 // so we cannot simply check for equality between expected and remaining
1429 // hence, we just check that they are orthogonal to the first two points
1430 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1431 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1432 fixiter != polygon.end(); ++fixiter) {
1433 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1434 iter != remaining.end(); ++iter) {
1435 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1436 }
1437 }
1438 }
1439
1440 // test with three points, matching trivially
1441 {
1442 SphericalPointDistribution::WeightedPolygon_t polygon;
1443 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1444 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1445 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
1446 SphericalPointDistribution::Polygon_t newpolygon =
1447 SPD.get<6>();
1448 SphericalPointDistribution::Polygon_t expected = newpolygon;
1449 expected.pop_front(); // remove first point
1450 expected.pop_front(); // remove second point
1451 expected.pop_front(); // remove third point
1452 SphericalPointDistribution::Polygon_t remaining =
1453 SphericalPointDistribution::matchSphericalPointDistributions(
1454 polygon,
1455 newpolygon);
1456// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1457 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1458 // also slightly perturbed
1459 const double amplitude = 0.05;
1460 perturbPolygon(polygon, amplitude);
1461 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1462 }
1463
1464 // test with three points, full rotation
1465 {
1466 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1467 SphericalPointDistribution::WeightedPolygon_t polygon;
1468 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1469 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1470 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
1471 SphericalPointDistribution::Polygon_t newpolygon =
1472 SPD.get<6>();
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 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1478 iter != expected.end(); ++iter)
1479 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1480 SphericalPointDistribution::Polygon_t remaining =
1481 SphericalPointDistribution::matchSphericalPointDistributions(
1482 polygon,
1483 newpolygon);
1484// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1485 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1486 // also slightly perturbed
1487 const double amplitude = 0.05;
1488 perturbPolygon(polygon, amplitude);
1489 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1490 }
1491}
1492
1493/** UnitTest for matchSphericalPointDistributions() with seven points
1494 */
1495void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_7()
1496{
1497 SphericalPointDistribution SPD(1.);
1498
1499 // test with one point, matching trivially
1500 {
1501 SphericalPointDistribution::WeightedPolygon_t polygon;
1502 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1503 SphericalPointDistribution::Polygon_t newpolygon =
1504 SPD.get<7>();
1505 SphericalPointDistribution::Polygon_t expected = newpolygon;
1506 expected.pop_front(); // remove first point
1507 SphericalPointDistribution::Polygon_t remaining =
1508 SphericalPointDistribution::matchSphericalPointDistributions(
1509 polygon,
1510 newpolygon);
1511// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1512 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1513 }
1514
1515 // test with one point, just a flip of axis
1516 {
1517 SphericalPointDistribution::WeightedPolygon_t polygon;
1518 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1519 SphericalPointDistribution::Polygon_t newpolygon =
1520 SPD.get<7>();
1521 SphericalPointDistribution::Polygon_t expected = newpolygon;
1522 expected.pop_front(); // remove first point
1523 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1524 iter != expected.end(); ++iter) {
1525 std::swap((*iter)[0], (*iter)[1]);
1526 (*iter)[0] *= -1.;
1527 }
1528 SphericalPointDistribution::Polygon_t remaining =
1529 SphericalPointDistribution::matchSphericalPointDistributions(
1530 polygon,
1531 newpolygon);
1532// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1533 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1534 }
1535
1536 // test with two points, matching trivially
1537 {
1538 SphericalPointDistribution::WeightedPolygon_t polygon;
1539 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1540 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1541 SphericalPointDistribution::Polygon_t newpolygon =
1542 SPD.get<7>();
1543 SphericalPointDistribution::Polygon_t expected = newpolygon;
1544 expected.pop_front(); // remove first point
1545 expected.pop_front(); // remove second point
1546 SphericalPointDistribution::Polygon_t remaining =
1547 SphericalPointDistribution::matchSphericalPointDistributions(
1548 polygon,
1549 newpolygon);
1550// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1551 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1552 // also slightly perturbed
1553 const double amplitude = 0.05;
1554 perturbPolygon(polygon, amplitude);
1555 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1556 }
1557
1558 // test with two points, full rotation
1559 {
1560 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1561 SphericalPointDistribution::WeightedPolygon_t polygon;
1562 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1563 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1564 SphericalPointDistribution::Polygon_t newpolygon =
1565 SPD.get<7>();
1566 SphericalPointDistribution::Polygon_t expected = newpolygon;
1567 expected.pop_front(); // remove first point
1568 expected.pop_front(); // remove second point
1569 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1570 iter != expected.end(); ++iter)
1571 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1572 SphericalPointDistribution::Polygon_t remaining =
1573 SphericalPointDistribution::matchSphericalPointDistributions(
1574 polygon,
1575 newpolygon);
1576 // the five remaining points sit on a plane that may have been rotated arbitrarily
1577 // so we cannot simply check for equality between expected and remaining
1578 // hence, we just check that they are orthogonal to the first two points
1579 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1580 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1581 fixiter != polygon.end(); ++fixiter) {
1582 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1583 iter != remaining.end(); ++iter) {
1584 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1585 }
1586 }
1587 }
1588
1589 // test with three points, matching trivially
1590 {
1591 SphericalPointDistribution::WeightedPolygon_t polygon;
1592 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1593 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1594 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
1595 SphericalPointDistribution::Polygon_t newpolygon =
1596 SPD.get<7>();
1597 SphericalPointDistribution::Polygon_t expected = newpolygon;
1598 expected.pop_front(); // remove first point
1599 expected.pop_front(); // remove second point
1600 expected.pop_front(); // remove third point
1601 SphericalPointDistribution::Polygon_t remaining =
1602 SphericalPointDistribution::matchSphericalPointDistributions(
1603 polygon,
1604 newpolygon);
1605// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1606 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1607 // also slightly perturbed
1608 const double amplitude = 0.05;
1609 perturbPolygon(polygon, amplitude);
1610 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1611 }
1612
1613 // test with three points, full rotation
1614 {
1615 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1616 SphericalPointDistribution::WeightedPolygon_t polygon;
1617 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1618 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1619 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
1620 SphericalPointDistribution::Polygon_t newpolygon =
1621 SPD.get<7>();
1622 SphericalPointDistribution::Polygon_t expected = newpolygon;
1623 expected.pop_front(); // remove first point
1624 expected.pop_front(); // remove second point
1625 expected.pop_front(); // remove third point
1626 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1627 iter != expected.end(); ++iter)
1628 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1629 SphericalPointDistribution::Polygon_t remaining =
1630 SphericalPointDistribution::matchSphericalPointDistributions(
1631 polygon,
1632 newpolygon);
1633// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1634 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1635 // also slightly perturbed
1636 const double amplitude = 0.05;
1637 perturbPolygon(polygon, amplitude);
1638 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1639 }
1640}
1641
1642/** UnitTest for matchSphericalPointDistributions() with eight points
1643 */
1644void SphericalPointDistributionTest::matchSphericalPointDistributionsTest_8()
1645{
1646 SphericalPointDistribution SPD(1.);
1647
1648 // test with one point, matching trivially
1649 {
1650 SphericalPointDistribution::WeightedPolygon_t polygon;
1651 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1652 SphericalPointDistribution::Polygon_t newpolygon =
1653 SPD.get<8>();
1654 SphericalPointDistribution::Polygon_t expected = newpolygon;
1655 expected.pop_front(); // remove first point
1656 SphericalPointDistribution::Polygon_t remaining =
1657 SphericalPointDistribution::matchSphericalPointDistributions(
1658 polygon,
1659 newpolygon);
1660// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1661 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1662 }
1663
1664 // test with one point, just a flip of axis
1665 {
1666 SphericalPointDistribution::WeightedPolygon_t polygon;
1667 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1668 SphericalPointDistribution::Polygon_t newpolygon =
1669 SPD.get<8>();
1670 SphericalPointDistribution::Polygon_t expected = newpolygon;
1671 expected.pop_front(); // remove first point
1672 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1673 iter != expected.end(); ++iter) {
1674 std::swap((*iter)[0], (*iter)[1]);
1675 (*iter)[0] *= -1.;
1676 }
1677 SphericalPointDistribution::Polygon_t remaining =
1678 SphericalPointDistribution::matchSphericalPointDistributions(
1679 polygon,
1680 newpolygon);
1681// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1682 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1683 }
1684
1685 // test with two points, matching trivially
1686 {
1687 SphericalPointDistribution::WeightedPolygon_t polygon;
1688 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1689 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1690 SphericalPointDistribution::Polygon_t newpolygon =
1691 SPD.get<8>();
1692 SphericalPointDistribution::Polygon_t expected = newpolygon;
1693 expected.pop_front(); // remove first point
1694 expected.pop_front(); // remove second point
1695 SphericalPointDistribution::Polygon_t remaining =
1696 SphericalPointDistribution::matchSphericalPointDistributions(
1697 polygon,
1698 newpolygon);
1699// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1700 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1701 // also slightly perturbed
1702 const double amplitude = 0.05;
1703 perturbPolygon(polygon, amplitude);
1704 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1705 }
1706
1707 // test with two points, full rotation
1708 {
1709 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1710 SphericalPointDistribution::WeightedPolygon_t polygon;
1711 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1712 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1713 SphericalPointDistribution::Polygon_t newpolygon =
1714 SPD.get<8>();
1715 SphericalPointDistribution::Polygon_t expected = newpolygon;
1716 expected.pop_front(); // remove first point
1717 expected.pop_front(); // remove second point
1718 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1719 iter != expected.end(); ++iter)
1720 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1721 SphericalPointDistribution::Polygon_t remaining =
1722 SphericalPointDistribution::matchSphericalPointDistributions(
1723 polygon,
1724 newpolygon);
1725 // the six remaining points sit on two planes that may have been rotated arbitrarily
1726 // so we cannot simply check for equality between expected and remaining
1727 // hence, we just check that they are orthogonal to the first two points
1728 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
1729 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1730 fixiter != polygon.end(); ++fixiter) {
1731 SphericalPointDistribution::Polygon_t::const_iterator expectiter = expected.begin();
1732 SphericalPointDistribution::Polygon_t::const_iterator remainiter = remaining.begin();
1733 for (;remainiter != remaining.end(); ++expectiter, ++remainiter) {
1734 // check that points in expected/remaining have same angle to the given ones
1735// CPPUNIT_ASSERT_EQUAL( (*expectiter).Angle(*fixiter), (*remainiter).Angle(*fixiter) );
1736 CPPUNIT_ASSERT( fabs( (*expectiter).Angle(fixiter->first) - (*remainiter).Angle(fixiter->first) )
1737 < std::numeric_limits<double>::epsilon()*1e4 );
1738 }
1739 }
1740 }
1741
1742 // test with three points, matching trivially
1743 {
1744 SphericalPointDistribution::WeightedPolygon_t polygon;
1745 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1746 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1747 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0, 0.0), 1);
1748 SphericalPointDistribution::Polygon_t newpolygon =
1749 SPD.get<8>();
1750 SphericalPointDistribution::Polygon_t expected = newpolygon;
1751 expected.pop_front(); // remove first point
1752 expected.pop_front(); // remove second point
1753 expected.pop_front(); // remove third point
1754 SphericalPointDistribution::Polygon_t remaining =
1755 SphericalPointDistribution::matchSphericalPointDistributions(
1756 polygon,
1757 newpolygon);
1758// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1759 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1760 // also slightly perturbed
1761 const double amplitude = 0.05;
1762 perturbPolygon(polygon, amplitude);
1763 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1764 }
1765
1766 // test with three points, full rotation
1767 {
1768 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1769 SphericalPointDistribution::WeightedPolygon_t polygon;
1770 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1771 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1772 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0, 0.0), 47.6/180*M_PI), 1);
1773 SphericalPointDistribution::Polygon_t newpolygon =
1774 SPD.get<8>();
1775 SphericalPointDistribution::Polygon_t expected = newpolygon;
1776 expected.pop_front(); // remove first point
1777 expected.pop_front(); // remove second point
1778 expected.pop_front(); // remove third point
1779 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1780 iter != expected.end(); ++iter)
1781 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1782 SphericalPointDistribution::Polygon_t remaining =
1783 SphericalPointDistribution::matchSphericalPointDistributions(
1784 polygon,
1785 newpolygon);
1786// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1787 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1788 // also slightly perturbed
1789 const double amplitude = 0.05;
1790 perturbPolygon(polygon, amplitude);
1791 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1792 }
1793}
Note: See TracBrowser for help on using the repository browser.