source: src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.cpp@ 2ae400

Action_Thermostats Add_AtomRandomPerturbation Add_RotateAroundBondAction Add_SelectAtomByNameAction Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests Automaking_mpqc_open AutomationFragmentation_failures 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_ChronosMutex 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_IntegrationTest 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 StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 2ae400 was fe90ab, checked in by Frederik Heber <heber@…>, 9 years ago

recurseMatching() now takes connections into account.

  • matchSphericalPointDistribution() replaced by getRemainingPoints() as that describes what it does. match...() sounds symmetrical which the function is no longer as connection is associated with former _newpolygon.
  • SphericalPointDistribution now has internal points and adjacency, initialized by initSelf().
  • findBestMatching() and getRemainingPoints() are no longer static functions.
  • all unit tests are working again, including the .._multiple() that tests for joint points due to bond degree greater than 1.
  • the huge case switch in SaturatedFragment::saturateAtom() now resides in initSelf().
  • Property mode set to 100644
File size: 66.2 KB
RevLine 
[64cafb2]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
[6393ff]47#include <algorithm>
[64cafb2]48#include <boost/assign.hpp>
[2ccdf4]49#include <boost/bind.hpp>
50#include <numeric>
[64cafb2]51
52#include "CodePatterns/Assert.hpp"
[8d38e6]53#include "CodePatterns/Log.hpp"
[64cafb2]54
[92bc5c]55#include "LinearAlgebra/Line.hpp"
56
[6393ff]57#include "Atom/TesselPoint.hpp"
[64cafb2]58#include "Fragmentation/Exporters/SphericalPointDistribution.hpp"
[6393ff]59#include "LinkedCell/linkedcell.hpp"
60#include "LinkedCell/PointCloudAdaptor.hpp"
61#include "Tesselation/BoundaryLineSet.hpp"
62#include "Tesselation/tesselation.hpp"
[8e4471]63
[64cafb2]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
[653cea]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);
[64cafb2]79
80void SphericalPointDistributionTest::setUp()
81{
82 // failing asserts should be thrown
83 ASSERT_DO(Assert::Throw);
[8d38e6]84
[6393ff]85 setVerbosity(2);
[64cafb2]86}
87
88
89void SphericalPointDistributionTest::tearDown()
90{
91}
92
[3678eb]93/** UnitTest for calculateCenterOfMinimumDistance()
[64cafb2]94 */
[3678eb]95void SphericalPointDistributionTest::calculateCenterOfMinimumDistanceTest()
[64cafb2]96{
[3678eb]97 // single point
[64cafb2]98 {
[3678eb]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));
[64cafb2]110 }
111
[3678eb]112 // single point, rotated
[64cafb2]113 {
[3678eb]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));
[8d38e6]126 }
127
[3678eb]128 // two points
[8d38e6]129 {
[3678eb]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));
[64cafb2]142 }
[92bc5c]143
[3678eb]144 // two points, rotated
[92bc5c]145 {
146 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[3678eb]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));
[92bc5c]159 }
[64cafb2]160
[3678eb]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));
[b67d89]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) {
[3678eb]212 status &= (*iter).IsEqualTo(*otheriter, _amplitude);
[b67d89]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
[2ccdf4]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
[6393ff]281/** UnitTest for getConnections()
[3678eb]282 */
[6393ff]283template <>
284void SphericalPointDistributionTest_assistant::getConnectionTest<0>()
[3678eb]285{
[6393ff]286 const int N=0;
[3678eb]287 SphericalPointDistribution SPD(1.);
288
[6393ff]289 // create empty adjacency
290 SphericalPointDistribution::adjacency_t adjacency;
[3678eb]291
[6393ff]292 // get the implemented connections
293 SphericalPointDistribution::adjacency_t expected =
294 SPD.getConnections<N>();
[3678eb]295
[6393ff]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 );
[3678eb]346}
347
[2ccdf4]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
[3678eb]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
[450adf]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}
[b67d89]737
[fe90ab]738/** UnitTest for getRemainingPoints() with two points
[6393ff]739 */
[fe90ab]740void SphericalPointDistributionTest::getRemainingPointsTest_2()
[6393ff]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 expected;
748 expected += Vector(-1.,0.,0.);
749 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]750 SPD.getRemainingPoints(polygon, 2);
[6393ff]751// CPPUNIT_ASSERT_EQUAL( expected, remaining );
752 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
753 }
754
755 // test with one point, just a flip of axis
756 {
757 SphericalPointDistribution::WeightedPolygon_t polygon;
758 polygon += std::make_pair( Vector(0.,1.,0.), 1);
759 SphericalPointDistribution::Polygon_t expected;
760 expected += Vector(0.,-1.,0.);
761 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]762 SPD.getRemainingPoints(polygon, 2);
[6393ff]763// CPPUNIT_ASSERT_EQUAL( expected, remaining );
764 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
765 }
766
767 // test with one point, just a flip to another axis
768 {
769 SphericalPointDistribution::WeightedPolygon_t polygon;
770 polygon += std::make_pair( Vector(0.,0.,-1.), 1);
771 SphericalPointDistribution::Polygon_t expected;
772 expected += Vector(0.,0.,1.);
773 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]774 SPD.getRemainingPoints(polygon, 2);
[6393ff]775// CPPUNIT_ASSERT_EQUAL( expected, remaining );
776 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
777 }
778
779 // test with one point, full rotation
780 {
781 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
782 SphericalPointDistribution::WeightedPolygon_t polygon;
783 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
784 SphericalPointDistribution::Polygon_t expected;
785 expected += RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI);
786 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]787 SPD.getRemainingPoints(polygon, 2);
[6393ff]788// CPPUNIT_ASSERT_EQUAL( expected, remaining );
789 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
790 }
791}
792
[fe90ab]793/** UnitTest for getRemainingPoints() with three points
[64cafb2]794 */
[fe90ab]795void SphericalPointDistributionTest::getRemainingPointsTest_3()
[64cafb2]796{
797 SphericalPointDistribution SPD(1.);
798
799 // test with one point, matching trivially
800 {
[2199c2]801 SphericalPointDistribution::WeightedPolygon_t polygon;
802 polygon += std::make_pair( Vector(1.,0.,0.), 1);
[fe90ab]803 SphericalPointDistribution::Polygon_t expected =
[64cafb2]804 SPD.get<3>();
805 expected.pop_front(); // remove first point
806 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]807 SPD.getRemainingPoints(polygon, 3);
[3678eb]808// CPPUNIT_ASSERT_EQUAL( expected, remaining );
809 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[64cafb2]810 }
[8d38e6]811
[92bc5c]812 // test with one point, just a flip of x and y axis
[8d38e6]813 {
[2199c2]814 SphericalPointDistribution::WeightedPolygon_t polygon;
815 polygon += std::make_pair( Vector(0.,1.,0.), 1);
[fe90ab]816 SphericalPointDistribution::Polygon_t expected =
[8d38e6]817 SPD.get<3>();
818 expected.pop_front(); // remove first point
[92bc5c]819 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
820 iter != expected.end(); ++iter) {
821 std::swap((*iter)[0], (*iter)[1]);
822 (*iter)[0] *= -1.;
823 }
[8d38e6]824 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]825 SPD.getRemainingPoints(polygon, 3);
[3678eb]826// CPPUNIT_ASSERT_EQUAL( expected, remaining );
827 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]828 }
[158ecb]829
830 // test with two points, matching trivially
831 {
[2199c2]832 SphericalPointDistribution::WeightedPolygon_t polygon;
833 polygon += std::make_pair( Vector(1.,0.,0.), 1);
834 polygon += std::make_pair( Vector(-0.5, sqrt(3)*0.5,0.), 1);
[fe90ab]835 SphericalPointDistribution::Polygon_t expected =
[158ecb]836 SPD.get<3>();
837 expected.pop_front(); // remove first point
838 expected.pop_front(); // remove second point
839 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]840 SPD.getRemainingPoints(polygon, 3);
[3678eb]841// CPPUNIT_ASSERT_EQUAL( expected, remaining );
842 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]843 // also slightly perturbed
844 const double amplitude = 0.05;
845 perturbPolygon(polygon, amplitude);
846 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]847 }
848
849 // test with two points, full rotation
850 {
851 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]852 SphericalPointDistribution::WeightedPolygon_t polygon;
853 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
854 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
[fe90ab]855 SphericalPointDistribution::Polygon_t expected =
[158ecb]856 SPD.get<3>();
857 expected.pop_front(); // remove first point
858 expected.pop_front(); // remove second point
859 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
860 iter != expected.end(); ++iter)
861 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
862 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]863 SPD.getRemainingPoints(polygon, 3);
[3678eb]864// CPPUNIT_ASSERT_EQUAL( expected, remaining );
865 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]866 // also slightly perturbed
867 const double amplitude = 0.05;
868 perturbPolygon(polygon, amplitude);
869 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]870 }
871
872 // test with three points, matching trivially
873 {
[2199c2]874 SphericalPointDistribution::WeightedPolygon_t polygon;
875 polygon += std::make_pair( Vector(1.,0.,0.), 1);
876 polygon += std::make_pair( Vector(-0.5, sqrt(3)*0.5,0.), 1);
877 polygon += std::make_pair( Vector(-0.5, -sqrt(3)*0.5,0.), 1);
[158ecb]878 SphericalPointDistribution::Polygon_t newpolygon =
879 SPD.get<3>();
880 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
881 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]882 SPD.getRemainingPoints(polygon, 3);
[3678eb]883// CPPUNIT_ASSERT_EQUAL( expected, remaining );
884 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]885 // also slightly perturbed
886 const double amplitude = 0.05;
887 perturbPolygon(polygon, amplitude);
888 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]889 }
890
891
892 // test with three points, full rotation
893 {
894 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]895 SphericalPointDistribution::WeightedPolygon_t polygon;
896 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
897 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
898 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-0.5, -sqrt(3)*0.5,0.), 47.6/180*M_PI), 1);
[158ecb]899 SphericalPointDistribution::Polygon_t newpolygon =
900 SPD.get<3>();
901 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
902 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]903 SPD.getRemainingPoints(polygon, 3);
[3678eb]904// CPPUNIT_ASSERT_EQUAL( expected, remaining );
905 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]906 // also slightly perturbed
907 const double amplitude = 0.05;
908 perturbPolygon(polygon, amplitude);
909 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]910 }
[8d38e6]911}
912
[fe90ab]913/** UnitTest for getRemainingPoints() with four points
[8d38e6]914 */
[fe90ab]915void SphericalPointDistributionTest::getRemainingPointsTest_4()
[8d38e6]916{
917 SphericalPointDistribution SPD(1.);
918
919 // test with one point, matching trivially
920 {
[2199c2]921 SphericalPointDistribution::WeightedPolygon_t polygon;
922 polygon += std::make_pair( Vector(1.,0.,0.), 1);
[fe90ab]923 SphericalPointDistribution::Polygon_t expected =
[8d38e6]924 SPD.get<4>();
925 expected.pop_front(); // remove first point
926 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]927 SPD.getRemainingPoints(polygon, 4);
[3678eb]928 // CPPUNIT_ASSERT_EQUAL( expected, remaining );
929 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]930 }
931
932 // test with one point, just a flip of axis
933 {
[2199c2]934 SphericalPointDistribution::WeightedPolygon_t polygon;
935 polygon += std::make_pair( Vector(0.,1.,0.), 1);
[fe90ab]936 SphericalPointDistribution::Polygon_t expected =
[8d38e6]937 SPD.get<4>();
938 expected.pop_front(); // remove first point
[92bc5c]939 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
940 iter != expected.end(); ++iter) {
941 std::swap((*iter)[0], (*iter)[1]);
942 (*iter)[0] *= -1.;
943 }
[8d38e6]944 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]945 SPD.getRemainingPoints(polygon, 4);
[3678eb]946// CPPUNIT_ASSERT_EQUAL( expected, remaining );
947 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]948 }
[158ecb]949
950 // test with two points, matching trivially
951 {
[2199c2]952 SphericalPointDistribution::WeightedPolygon_t polygon;
953 polygon += std::make_pair( Vector(1.,0.,0.), 1);
954 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
[fe90ab]955 SphericalPointDistribution::Polygon_t expected =
[158ecb]956 SPD.get<4>();
957 expected.pop_front(); // remove first point
958 expected.pop_front(); // remove second point
959 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]960 SPD.getRemainingPoints(polygon, 4);
[3678eb]961// CPPUNIT_ASSERT_EQUAL( expected, remaining );
962 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]963 // also slightly perturbed
964 const double amplitude = 0.05;
965 perturbPolygon(polygon, amplitude);
966 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
967 }
968
969 // test with two points, matching trivially, also with slightly perturbed
970 {
[2199c2]971 SphericalPointDistribution::WeightedPolygon_t polygon;
972 polygon += std::make_pair( Vector(1.,0.,0.), 1);
973 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
[fe90ab]974 SphericalPointDistribution::Polygon_t expected =
[b67d89]975 SPD.get<4>();
976 expected.pop_front(); // remove first point
977 expected.pop_front(); // remove second point
978 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]979 SPD.getRemainingPoints(polygon, 4);
[3678eb]980// CPPUNIT_ASSERT_EQUAL( expected, remaining );
981 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]982 // also slightly perturbed
983 const double amplitude = 0.05;
984 perturbPolygon(polygon, amplitude);
985 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]986 }
987
988 // test with two points, full rotation
989 {
990 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]991 SphericalPointDistribution::WeightedPolygon_t polygon;
992 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
993 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 47.6/180*M_PI), 1);
[fe90ab]994 SphericalPointDistribution::Polygon_t expected =
[158ecb]995 SPD.get<4>();
996 expected.pop_front(); // remove first point
997 expected.pop_front(); // remove second point
998 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
999 iter != expected.end(); ++iter)
1000 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1001 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1002 SPD.getRemainingPoints(polygon, 4);
[3678eb]1003// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1004 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1005 // also slightly perturbed
1006 const double amplitude = 0.05;
1007 perturbPolygon(polygon, amplitude);
1008 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1009 }
1010
1011 // test with three points, matching trivially
1012 {
[2199c2]1013 SphericalPointDistribution::WeightedPolygon_t polygon;
1014 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1015 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0,0.), 1);
1016 polygon += std::make_pair( Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 1);
[fe90ab]1017 SphericalPointDistribution::Polygon_t expected =
[158ecb]1018 SPD.get<4>();
1019 expected.pop_front(); // remove first point
1020 expected.pop_front(); // remove second point
1021 expected.pop_front(); // remove third point
1022 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1023 SPD.getRemainingPoints(polygon, 4);
[3678eb]1024// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1025 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1026 // also slightly perturbed
1027 const double amplitude = 0.05;
1028 perturbPolygon(polygon, amplitude);
1029 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1030 }
1031
1032 // test with three points, full rotation
1033 {
1034 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]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 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 47.6/180*M_PI), 1);
[fe90ab]1039 SphericalPointDistribution::Polygon_t expected =
[158ecb]1040 SPD.get<4>();
1041 expected.pop_front(); // remove first point
1042 expected.pop_front(); // remove second point
1043 expected.pop_front(); // remove third point
1044 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1045 iter != expected.end(); ++iter)
1046 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1047 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1048 SPD.getRemainingPoints(polygon, 4);
[3678eb]1049// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1050 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1051 // also slightly perturbed
1052 const double amplitude = 0.05;
1053 perturbPolygon(polygon, amplitude);
1054 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1055 }
[8d38e6]1056}
1057
[fe90ab]1058/** UnitTest for getRemainingPoints() with four points and weights
[653cea]1059 * not all equal to one.
1060 */
[fe90ab]1061void SphericalPointDistributionTest::getRemainingPointsTest_multiple()
[653cea]1062{
1063 SphericalPointDistribution SPD(1.);
1064
1065 // test with four points: one point having weight of two
1066 {
1067 SphericalPointDistribution::WeightedPolygon_t polygon;
1068 polygon += std::make_pair( Vector(1.,0.,0.), 2);
1069 SphericalPointDistribution::Polygon_t newpolygon =
1070 SPD.get<4>();
1071 SphericalPointDistribution::Polygon_t expected;
1072 expected += Vector(-0.5773502691896,-5.551115123126e-17,0.8164965809277);
1073 expected += Vector(-0.5773502691896,-5.551115123126e-17,-0.8164965809277);
1074 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1075 SPD.getRemainingPoints(polygon, 4);
[653cea]1076// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
1077// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1078 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1079 }
1080
1081 // test with five points: one point having weight of two
1082 {
1083 SphericalPointDistribution::WeightedPolygon_t polygon;
1084 polygon += std::make_pair( Vector(1.,0.,0.), 2);
1085 SphericalPointDistribution::Polygon_t newpolygon =
1086 SPD.get<5>();
1087 SphericalPointDistribution::Polygon_t expected;
1088 expected += Vector(-0.7071067811865,0.7071067811865,0);
1089 expected += Vector(-0.3535533905933,-0.3535533905933,0.8660254037844);
1090 expected += Vector(-0.3535533905933,-0.3535533905933,-0.8660254037844);
1091 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1092 SPD.getRemainingPoints(polygon, 5);
1093 std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
[653cea]1094// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1095 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1096 }
1097
1098
1099 // test with five points: one point having weight of two, one weight of one
1100 {
1101 SphericalPointDistribution::WeightedPolygon_t polygon;
1102 polygon += std::make_pair( Vector(M_SQRT1_2,M_SQRT1_2,0.), 2);
1103 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
1104 SphericalPointDistribution::Polygon_t newpolygon =
1105 SPD.get<5>();
1106 SphericalPointDistribution::Polygon_t expected;
1107 expected += Vector(0.3535533786708,-0.3535533955317,-0.8660254066357);
1108 expected += Vector(0.3535534025157,-0.3535533856548,0.8660254009332);
1109 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1110 SPD.getRemainingPoints(polygon, 5);
[653cea]1111// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
1112// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1113 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1114 }
1115
1116 // test with six points: two points each having weight of two
1117 {
1118 SphericalPointDistribution::WeightedPolygon_t polygon;
1119 polygon += std::make_pair( Vector(M_SQRT1_2,-M_SQRT1_2,0.), 2);
1120 polygon += std::make_pair( Vector(-M_SQRT1_2,M_SQRT1_2,0.), 2);
1121 SphericalPointDistribution::Polygon_t newpolygon =
1122 SPD.get<6>();
1123 SphericalPointDistribution::Polygon_t expected;
1124 expected += Vector(0.,0.,1.);
[fe90ab]1125 expected += Vector(0.,0.,-1.);
[653cea]1126 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1127 SPD.getRemainingPoints(polygon, 6);
[653cea]1128// std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
1129// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1130 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1131 }
1132}
1133
[fe90ab]1134/** UnitTest for getRemainingPoints() with five points
[8d38e6]1135 */
[fe90ab]1136void SphericalPointDistributionTest::getRemainingPointsTest_5()
[8d38e6]1137{
1138 SphericalPointDistribution SPD(1.);
1139
1140 // test with one point, matching trivially
1141 {
[2199c2]1142 SphericalPointDistribution::WeightedPolygon_t polygon;
1143 polygon += std::make_pair( Vector(1.,0.,0.), 1);
[fe90ab]1144 SphericalPointDistribution::Polygon_t expected =
[8d38e6]1145 SPD.get<5>();
1146 expected.pop_front(); // remove first point
1147 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1148 SPD.getRemainingPoints(polygon, 5);
[3678eb]1149// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1150 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]1151 }
1152
1153 // test with one point, just a flip of axis
1154 {
[2199c2]1155 SphericalPointDistribution::WeightedPolygon_t polygon;
1156 polygon += std::make_pair( Vector(0.,1.,0.), 1);
[fe90ab]1157 SphericalPointDistribution::Polygon_t expected =
[8d38e6]1158 SPD.get<5>();
1159 expected.pop_front(); // remove first point
[92bc5c]1160 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1161 iter != expected.end(); ++iter) {
1162 std::swap((*iter)[0], (*iter)[1]);
1163 (*iter)[0] *= -1.;
1164 }
[8d38e6]1165 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1166 SPD.getRemainingPoints(polygon, 5);
[3678eb]1167// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1168 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]1169 }
[158ecb]1170
1171 // test with two points, matching trivially
1172 {
[2199c2]1173 SphericalPointDistribution::WeightedPolygon_t polygon;
1174 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1175 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
[fe90ab]1176 SphericalPointDistribution::Polygon_t expected =
[158ecb]1177 SPD.get<5>();
1178 expected.pop_front(); // remove first point
1179 expected.pop_front(); // remove second point
1180 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1181 SPD.getRemainingPoints(polygon, 5);
[3678eb]1182// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1183 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1184 // also slightly perturbed
1185 const double amplitude = 0.05;
1186 perturbPolygon(polygon, amplitude);
1187 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1188 }
1189
1190 // test with two points, full rotation
1191 {
1192 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]1193 SphericalPointDistribution::WeightedPolygon_t polygon;
1194 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180.*M_PI), 1);
1195 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180.*M_PI), 1);
[fe90ab]1196 SphericalPointDistribution::Polygon_t expected =
[158ecb]1197 SPD.get<5>();
1198 expected.pop_front(); // remove first point
1199 expected.pop_front(); // remove second point
1200 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1201 iter != expected.end(); ++iter)
1202 *iter = RotationAxis.rotateVector(*iter, 47.6/180.*M_PI);
1203 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1204 SPD.getRemainingPoints(polygon, 5);
[158ecb]1205 // the three remaining points sit on a plane that may be rotated arbitrarily
1206 // so we cannot simply check for equality between expected and remaining
1207 // hence, we just check that they are orthogonal to the first two points
1208 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
[2199c2]1209 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
[158ecb]1210 fixiter != polygon.end(); ++fixiter) {
1211 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1212 iter != remaining.end(); ++iter) {
[2199c2]1213 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
[158ecb]1214 }
1215 }
1216 }
1217
1218 // test with three points, matching trivially
1219 {
[2199c2]1220 SphericalPointDistribution::WeightedPolygon_t polygon;
1221 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1222 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1223 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
[fe90ab]1224 SphericalPointDistribution::Polygon_t expected =
[158ecb]1225 SPD.get<5>();
1226 expected.pop_front(); // remove first point
1227 expected.pop_front(); // remove second point
1228 expected.pop_front(); // remove third point
1229 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1230 SPD.getRemainingPoints(polygon, 5);
[3678eb]1231// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1232 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1233 // also slightly perturbed
1234 const double amplitude = 0.05;
1235 perturbPolygon(polygon, amplitude);
1236 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1237 }
1238
1239 // test with three points, full rotation
1240 {
1241 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]1242 SphericalPointDistribution::WeightedPolygon_t polygon;
1243 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1244 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1245 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
[fe90ab]1246 SphericalPointDistribution::Polygon_t expected =
[158ecb]1247 SPD.get<5>();
1248 expected.pop_front(); // remove first point
1249 expected.pop_front(); // remove second point
1250 expected.pop_front(); // remove third point
1251 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1252 iter != expected.end(); ++iter)
1253 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1254 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1255 SPD.getRemainingPoints(polygon, 5);
[3678eb]1256// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1257 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1258 // also slightly perturbed
1259 const double amplitude = 0.05;
1260 perturbPolygon(polygon, amplitude);
1261 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1262 }
[8d38e6]1263}
1264
[fe90ab]1265/** UnitTest for getRemainingPoints() with six points
[8d38e6]1266 */
[fe90ab]1267void SphericalPointDistributionTest::getRemainingPointsTest_6()
[8d38e6]1268{
1269 SphericalPointDistribution SPD(1.);
1270
1271 // test with one point, matching trivially
1272 {
[2199c2]1273 SphericalPointDistribution::WeightedPolygon_t polygon;
1274 polygon += std::make_pair( Vector(1.,0.,0.), 1);
[fe90ab]1275 SphericalPointDistribution::Polygon_t expected =
[8d38e6]1276 SPD.get<6>();
1277 expected.pop_front(); // remove first point
1278 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1279 SPD.getRemainingPoints(polygon, 6);
[3678eb]1280// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1281 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]1282 }
1283
1284 // test with one point, just a flip of axis
1285 {
[2199c2]1286 SphericalPointDistribution::WeightedPolygon_t polygon;
1287 polygon += std::make_pair( Vector(0.,1.,0.), 1);
[fe90ab]1288 SphericalPointDistribution::Polygon_t expected =
[8d38e6]1289 SPD.get<6>();
1290 expected.pop_front(); // remove first point
[92bc5c]1291 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1292 iter != expected.end(); ++iter) {
1293 std::swap((*iter)[0], (*iter)[1]);
1294 (*iter)[0] *= -1.;
1295 }
[8d38e6]1296 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1297 SPD.getRemainingPoints(polygon, 6);
[3678eb]1298// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1299 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]1300 }
[158ecb]1301
1302 // test with two points, matching trivially
1303 {
[2199c2]1304 SphericalPointDistribution::WeightedPolygon_t polygon;
1305 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1306 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
[fe90ab]1307 SphericalPointDistribution::Polygon_t expected =
[158ecb]1308 SPD.get<6>();
1309 expected.pop_front(); // remove first point
1310 expected.pop_front(); // remove second spoint
1311 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1312 SPD.getRemainingPoints(polygon, 6);
[3678eb]1313// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1314 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1315 // also slightly perturbed
1316 const double amplitude = 0.05;
1317 perturbPolygon(polygon, amplitude);
1318 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1319 }
1320
1321 // test with two points, full rotation
1322 {
1323 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]1324 SphericalPointDistribution::WeightedPolygon_t polygon;
1325 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1326 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
[fe90ab]1327 SphericalPointDistribution::Polygon_t expected =
[158ecb]1328 SPD.get<6>();
1329 expected.pop_front(); // remove first point
1330 expected.pop_front(); // remove second spoint
1331 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1332 iter != expected.end(); ++iter)
1333 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1334 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1335 SPD.getRemainingPoints(polygon, 6);
[158ecb]1336 // the four remaining points sit on a plane that may have been rotated arbitrarily
1337 // so we cannot simply check for equality between expected and remaining
1338 // hence, we just check that they are orthogonal to the first two points
1339 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
[2199c2]1340 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
[158ecb]1341 fixiter != polygon.end(); ++fixiter) {
1342 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1343 iter != remaining.end(); ++iter) {
[2199c2]1344 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
[158ecb]1345 }
1346 }
1347 }
1348
1349 // test with three points, matching trivially
1350 {
[2199c2]1351 SphericalPointDistribution::WeightedPolygon_t polygon;
1352 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1353 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1354 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
[fe90ab]1355 SphericalPointDistribution::Polygon_t expected =
[158ecb]1356 SPD.get<6>();
1357 expected.pop_front(); // remove first point
1358 expected.pop_front(); // remove second point
1359 expected.pop_front(); // remove third point
1360 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1361 SPD.getRemainingPoints(polygon, 6);
[3678eb]1362// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1363 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1364 // also slightly perturbed
1365 const double amplitude = 0.05;
1366 perturbPolygon(polygon, amplitude);
1367 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1368 }
1369
1370 // test with three points, full rotation
1371 {
1372 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]1373 SphericalPointDistribution::WeightedPolygon_t polygon;
1374 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1375 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1376 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
[fe90ab]1377 SphericalPointDistribution::Polygon_t expected =
[158ecb]1378 SPD.get<6>();
1379 expected.pop_front(); // remove first point
1380 expected.pop_front(); // remove second point
1381 expected.pop_front(); // remove third point
1382 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1383 iter != expected.end(); ++iter)
1384 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1385 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1386 SPD.getRemainingPoints(polygon, 6);
[3678eb]1387// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1388 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1389 // also slightly perturbed
1390 const double amplitude = 0.05;
1391 perturbPolygon(polygon, amplitude);
1392 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1393 }
[8d38e6]1394}
1395
[fe90ab]1396/** UnitTest for getRemainingPoints() with seven points
[8d38e6]1397 */
[fe90ab]1398void SphericalPointDistributionTest::getRemainingPointsTest_7()
[8d38e6]1399{
1400 SphericalPointDistribution SPD(1.);
1401
1402 // test with one point, matching trivially
1403 {
[2199c2]1404 SphericalPointDistribution::WeightedPolygon_t polygon;
1405 polygon += std::make_pair( Vector(1.,0.,0.), 1);
[fe90ab]1406 SphericalPointDistribution::Polygon_t expected =
[8d38e6]1407 SPD.get<7>();
1408 expected.pop_front(); // remove first point
1409 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1410 SPD.getRemainingPoints(polygon, 7);
[3678eb]1411// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1412 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]1413 }
1414
1415 // test with one point, just a flip of axis
1416 {
[2199c2]1417 SphericalPointDistribution::WeightedPolygon_t polygon;
1418 polygon += std::make_pair( Vector(0.,1.,0.), 1);
[fe90ab]1419 SphericalPointDistribution::Polygon_t expected =
[8d38e6]1420 SPD.get<7>();
1421 expected.pop_front(); // remove first point
[92bc5c]1422 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1423 iter != expected.end(); ++iter) {
1424 std::swap((*iter)[0], (*iter)[1]);
1425 (*iter)[0] *= -1.;
1426 }
[8d38e6]1427 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1428 SPD.getRemainingPoints(polygon, 7);
[3678eb]1429// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1430 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]1431 }
[158ecb]1432
1433 // test with two points, matching trivially
1434 {
[2199c2]1435 SphericalPointDistribution::WeightedPolygon_t polygon;
1436 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1437 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
[fe90ab]1438 SphericalPointDistribution::Polygon_t expected =
[158ecb]1439 SPD.get<7>();
1440 expected.pop_front(); // remove first point
1441 expected.pop_front(); // remove second point
1442 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1443 SPD.getRemainingPoints(polygon, 7);
[3678eb]1444// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1445 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1446 // also slightly perturbed
1447 const double amplitude = 0.05;
1448 perturbPolygon(polygon, amplitude);
1449 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1450 }
1451
1452 // test with two points, full rotation
1453 {
1454 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]1455 SphericalPointDistribution::WeightedPolygon_t polygon;
1456 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1457 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
[fe90ab]1458 SphericalPointDistribution::Polygon_t expected =
[158ecb]1459 SPD.get<7>();
1460 expected.pop_front(); // remove first point
1461 expected.pop_front(); // remove second point
1462 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1463 iter != expected.end(); ++iter)
1464 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1465 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1466 SPD.getRemainingPoints(polygon, 7);
[158ecb]1467 // the five remaining points sit on a plane that may have been rotated arbitrarily
1468 // so we cannot simply check for equality between expected and remaining
1469 // hence, we just check that they are orthogonal to the first two points
1470 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
[2199c2]1471 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
[158ecb]1472 fixiter != polygon.end(); ++fixiter) {
1473 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1474 iter != remaining.end(); ++iter) {
[2199c2]1475 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
[158ecb]1476 }
1477 }
1478 }
1479
1480 // test with three points, matching trivially
1481 {
[2199c2]1482 SphericalPointDistribution::WeightedPolygon_t polygon;
1483 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1484 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1485 polygon += std::make_pair( Vector(0.0, 1., 0.0), 1);
[fe90ab]1486 SphericalPointDistribution::Polygon_t expected =
[158ecb]1487 SPD.get<7>();
1488 expected.pop_front(); // remove first point
1489 expected.pop_front(); // remove second point
1490 expected.pop_front(); // remove third point
1491 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1492 SPD.getRemainingPoints(polygon, 7);
[3678eb]1493// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1494 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1495 // also slightly perturbed
1496 const double amplitude = 0.05;
1497 perturbPolygon(polygon, amplitude);
1498 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1499 }
1500
1501 // test with three points, full rotation
1502 {
1503 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]1504 SphericalPointDistribution::WeightedPolygon_t polygon;
1505 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1506 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1507 polygon += std::make_pair(RotationAxis.rotateVector(Vector(0.0, 1., 0.0), 47.6/180*M_PI), 1);
[fe90ab]1508 SphericalPointDistribution::Polygon_t expected =
[158ecb]1509 SPD.get<7>();
1510 expected.pop_front(); // remove first point
1511 expected.pop_front(); // remove second point
1512 expected.pop_front(); // remove third point
1513 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1514 iter != expected.end(); ++iter)
1515 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1516 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1517 SPD.getRemainingPoints(polygon, 7);
[3678eb]1518// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1519 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1520 // also slightly perturbed
1521 const double amplitude = 0.05;
1522 perturbPolygon(polygon, amplitude);
1523 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1524 }
[8d38e6]1525}
1526
[fe90ab]1527/** UnitTest for getRemainingPoints() with eight points
[8d38e6]1528 */
[fe90ab]1529void SphericalPointDistributionTest::getRemainingPointsTest_8()
[8d38e6]1530{
1531 SphericalPointDistribution SPD(1.);
1532
1533 // test with one point, matching trivially
1534 {
[2199c2]1535 SphericalPointDistribution::WeightedPolygon_t polygon;
1536 polygon += std::make_pair( Vector(1.,0.,0.), 1);
[fe90ab]1537 SphericalPointDistribution::Polygon_t expected =
[8d38e6]1538 SPD.get<8>();
1539 expected.pop_front(); // remove first point
1540 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1541 SPD.getRemainingPoints(polygon, 8);
[3678eb]1542// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1543 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]1544 }
1545
1546 // test with one point, just a flip of axis
1547 {
[2199c2]1548 SphericalPointDistribution::WeightedPolygon_t polygon;
1549 polygon += std::make_pair( Vector(0.,1.,0.), 1);
[fe90ab]1550 SphericalPointDistribution::Polygon_t expected =
[8d38e6]1551 SPD.get<8>();
1552 expected.pop_front(); // remove first point
[92bc5c]1553 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1554 iter != expected.end(); ++iter) {
1555 std::swap((*iter)[0], (*iter)[1]);
1556 (*iter)[0] *= -1.;
1557 }
[fe90ab]1558 SphericalPointDistribution::Polygon_t remaining =
1559 SPD.getRemainingPoints(polygon, 8);
[3678eb]1560// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1561 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[8d38e6]1562 }
[158ecb]1563
1564 // test with two points, matching trivially
1565 {
[2199c2]1566 SphericalPointDistribution::WeightedPolygon_t polygon;
1567 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1568 polygon += std::make_pair( Vector(-1.,0.,0.), 1);
[fe90ab]1569 SphericalPointDistribution::Polygon_t expected =
[158ecb]1570 SPD.get<8>();
1571 expected.pop_front(); // remove first point
1572 expected.pop_front(); // remove second point
1573 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1574 SPD.getRemainingPoints(polygon, 8);
[3678eb]1575// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1576 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1577 // also slightly perturbed
1578 const double amplitude = 0.05;
1579 perturbPolygon(polygon, amplitude);
1580 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1581 }
1582
1583 // test with two points, full rotation
1584 {
1585 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]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);
[fe90ab]1589 SphericalPointDistribution::Polygon_t expected =
[158ecb]1590 SPD.get<8>();
1591 expected.pop_front(); // remove first point
1592 expected.pop_front(); // remove second point
1593 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1594 iter != expected.end(); ++iter)
1595 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1596 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1597 SPD.getRemainingPoints(polygon, 8);
[158ecb]1598 // the six remaining points sit on two planes that may have been rotated arbitrarily
1599 // so we cannot simply check for equality between expected and remaining
1600 // hence, we just check that they are orthogonal to the first two points
1601 CPPUNIT_ASSERT_EQUAL( expected.size(), remaining.size() );
[2199c2]1602 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
[158ecb]1603 fixiter != polygon.end(); ++fixiter) {
1604 SphericalPointDistribution::Polygon_t::const_iterator expectiter = expected.begin();
1605 SphericalPointDistribution::Polygon_t::const_iterator remainiter = remaining.begin();
1606 for (;remainiter != remaining.end(); ++expectiter, ++remainiter) {
1607 // check that points in expected/remaining have same angle to the given ones
1608// CPPUNIT_ASSERT_EQUAL( (*expectiter).Angle(*fixiter), (*remainiter).Angle(*fixiter) );
[2199c2]1609 CPPUNIT_ASSERT( fabs( (*expectiter).Angle(fixiter->first) - (*remainiter).Angle(fixiter->first) )
[158ecb]1610 < std::numeric_limits<double>::epsilon()*1e4 );
1611 }
1612 }
1613 }
1614
1615 // test with three points, matching trivially
1616 {
[2199c2]1617 SphericalPointDistribution::WeightedPolygon_t polygon;
1618 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1619 polygon += std::make_pair( Vector(-1., 0.0, 0.0), 1);
1620 polygon += std::make_pair( Vector(-1./3.0, 2.0*M_SQRT2/3.0, 0.0), 1);
[fe90ab]1621 SphericalPointDistribution::Polygon_t expected =
[158ecb]1622 SPD.get<8>();
1623 expected.pop_front(); // remove first point
1624 expected.pop_front(); // remove second point
1625 expected.pop_front(); // remove third point
1626 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1627 SPD.getRemainingPoints(polygon, 8);
[3678eb]1628// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1629 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1630 // also slightly perturbed
1631 const double amplitude = 0.05;
1632 perturbPolygon(polygon, amplitude);
1633 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1634 }
1635
1636 // test with three points, full rotation
1637 {
1638 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
[2199c2]1639 SphericalPointDistribution::WeightedPolygon_t polygon;
1640 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1641 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1., 0.0, 0.0), 47.6/180*M_PI), 1);
1642 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, 2.0*M_SQRT2/3.0, 0.0), 47.6/180*M_PI), 1);
[fe90ab]1643 SphericalPointDistribution::Polygon_t expected =
[158ecb]1644 SPD.get<8>();
1645 expected.pop_front(); // remove first point
1646 expected.pop_front(); // remove second point
1647 expected.pop_front(); // remove third point
1648 for (SphericalPointDistribution::Polygon_t::iterator iter = expected.begin();
1649 iter != expected.end(); ++iter)
1650 *iter = RotationAxis.rotateVector(*iter, 47.6/180*M_PI);
1651 SphericalPointDistribution::Polygon_t remaining =
[fe90ab]1652 SPD.getRemainingPoints(polygon, 8);
[3678eb]1653// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1654 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
[b67d89]1655 // also slightly perturbed
1656 const double amplitude = 0.05;
1657 perturbPolygon(polygon, amplitude);
1658 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
[158ecb]1659 }
[64cafb2]1660}
Note: See TracBrowser for help on using the repository browser.