source: src/Fragmentation/Exporters/unittests/SphericalPointDistributionUnitTest.cpp@ 13e5be

stable v1.7.0
Last change on this file since 13e5be was 2390e6, checked in by Frederik Heber <frederik.heber@…>, 4 years ago

SaturateAction may use outer shell information.

  • when considering the outer shell, then we look at both occupied and unoccupied orbitals. The ideal polygon will be created for the number of all orbitals, but only the unoccupied will be allowed to be taken by either present bonds or saturation hydrogens.
  • SphericalPointDistribution allows to occupy less than present points.
  • I have tested this manually by adding oxygen, saturation, adding carbon, saturating again, then turning oxygen into nitrogen and saturating. Results were always exactly as hoped for.
  • DOCU: Added note to action in userguide.
  • Property mode set to 100644
File size: 66.4 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2014 Frederik Heber. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * SphericalPointDistributionUnitTest.cpp
25 *
26 * Created on: May 29, 2014
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35using namespace std;
36
37#include <cppunit/CompilerOutputter.h>
38#include <cppunit/extensions/TestFactoryRegistry.h>
39#include <cppunit/ui/text/TestRunner.h>
40
41// include headers that implement a archive in simple text format
42#include <boost/archive/text_oarchive.hpp>
43#include <boost/archive/text_iarchive.hpp>
44
45#include "SphericalPointDistributionUnitTest.hpp"
46
47#include <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 getRemainingPoints() with two points
739 */
740void SphericalPointDistributionTest::getRemainingPointsTest_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 expected;
748 expected += Vector(-1.,0.,0.);
749 SphericalPointDistribution::Polygon_t remaining =
750 SPD.getRemainingPoints(polygon, 2, 2);
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 =
762 SPD.getRemainingPoints(polygon, 2, 2);
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 =
774 SPD.getRemainingPoints(polygon, 2, 2);
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 =
787 SPD.getRemainingPoints(polygon, 2, 2);
788// CPPUNIT_ASSERT_EQUAL( expected, remaining );
789 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
790 }
791}
792
793/** UnitTest for getRemainingPoints() with three points
794 */
795void SphericalPointDistributionTest::getRemainingPointsTest_3()
796{
797 SphericalPointDistribution SPD(1.);
798
799 // test with one point, matching trivially
800 {
801 SphericalPointDistribution::WeightedPolygon_t polygon;
802 polygon += std::make_pair( Vector(1.,0.,0.), 1);
803 SphericalPointDistribution::Polygon_t expected =
804 SPD.get<3>();
805 expected.pop_front(); // remove first point
806 SphericalPointDistribution::Polygon_t remaining =
807 SPD.getRemainingPoints(polygon, 3, 3);
808// CPPUNIT_ASSERT_EQUAL( expected, remaining );
809 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
810 }
811
812 // test with one point, just a flip of x and y axis
813 {
814 SphericalPointDistribution::WeightedPolygon_t polygon;
815 polygon += std::make_pair( Vector(0.,1.,0.), 1);
816 SphericalPointDistribution::Polygon_t expected =
817 SPD.get<3>();
818 expected.pop_front(); // remove first point
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 }
824 SphericalPointDistribution::Polygon_t remaining =
825 SPD.getRemainingPoints(polygon, 3, 3);
826// CPPUNIT_ASSERT_EQUAL( expected, remaining );
827 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
828 }
829
830 // test with two points, matching trivially
831 {
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);
835 SphericalPointDistribution::Polygon_t expected =
836 SPD.get<3>();
837 expected.pop_front(); // remove first point
838 expected.pop_front(); // remove second point
839 SphericalPointDistribution::Polygon_t remaining =
840 SPD.getRemainingPoints(polygon, 3, 3);
841// CPPUNIT_ASSERT_EQUAL( expected, remaining );
842 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
843 // also slightly perturbed
844 const double amplitude = 0.05;
845 perturbPolygon(polygon, amplitude);
846 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
847 }
848
849 // test with two points, full rotation
850 {
851 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
855 SphericalPointDistribution::Polygon_t expected =
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 =
863 SPD.getRemainingPoints(polygon, 3, 3);
864// CPPUNIT_ASSERT_EQUAL( expected, remaining );
865 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
866 // also slightly perturbed
867 const double amplitude = 0.05;
868 perturbPolygon(polygon, amplitude);
869 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
870 }
871
872 // test with three points, matching trivially
873 {
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);
878 SphericalPointDistribution::Polygon_t newpolygon =
879 SPD.get<3>();
880 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
881 SphericalPointDistribution::Polygon_t remaining =
882 SPD.getRemainingPoints(polygon, 3, 3);
883// CPPUNIT_ASSERT_EQUAL( expected, remaining );
884 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
885 // also slightly perturbed
886 const double amplitude = 0.05;
887 perturbPolygon(polygon, amplitude);
888 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
889 }
890
891
892 // test with three points, full rotation
893 {
894 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
899 SphericalPointDistribution::Polygon_t newpolygon =
900 SPD.get<3>();
901 SphericalPointDistribution::Polygon_t expected; // empty cause none are vacant
902 SphericalPointDistribution::Polygon_t remaining =
903 SPD.getRemainingPoints(polygon, 3, 3);
904// CPPUNIT_ASSERT_EQUAL( expected, remaining );
905 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
906 // also slightly perturbed
907 const double amplitude = 0.05;
908 perturbPolygon(polygon, amplitude);
909 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
910 }
911}
912
913/** UnitTest for getRemainingPoints() with four points
914 */
915void SphericalPointDistributionTest::getRemainingPointsTest_4()
916{
917 SphericalPointDistribution SPD(1.);
918
919 // test with one point, matching trivially
920 {
921 SphericalPointDistribution::WeightedPolygon_t polygon;
922 polygon += std::make_pair( Vector(1.,0.,0.), 1);
923 SphericalPointDistribution::Polygon_t expected =
924 SPD.get<4>();
925 expected.pop_front(); // remove first point
926 SphericalPointDistribution::Polygon_t remaining =
927 SPD.getRemainingPoints(polygon, 4, 4);
928 // CPPUNIT_ASSERT_EQUAL( expected, remaining );
929 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
930 }
931
932 // test with one point, just a flip of axis
933 {
934 SphericalPointDistribution::WeightedPolygon_t polygon;
935 polygon += std::make_pair( Vector(0.,1.,0.), 1);
936 SphericalPointDistribution::Polygon_t expected =
937 SPD.get<4>();
938 expected.pop_front(); // remove first point
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 }
944 SphericalPointDistribution::Polygon_t remaining =
945 SPD.getRemainingPoints(polygon, 4, 4);
946// CPPUNIT_ASSERT_EQUAL( expected, remaining );
947 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
948 }
949
950 // test with two points, matching trivially
951 {
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);
955 SphericalPointDistribution::Polygon_t expected =
956 SPD.get<4>();
957 expected.pop_front(); // remove first point
958 expected.pop_front(); // remove second point
959 SphericalPointDistribution::Polygon_t remaining =
960 SPD.getRemainingPoints(polygon, 4, 4);
961// CPPUNIT_ASSERT_EQUAL( expected, remaining );
962 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
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 {
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);
974 SphericalPointDistribution::Polygon_t expected =
975 SPD.get<4>();
976 expected.pop_front(); // remove first point
977 expected.pop_front(); // remove second point
978 SphericalPointDistribution::Polygon_t remaining =
979 SPD.getRemainingPoints(polygon, 4, 4);
980// CPPUNIT_ASSERT_EQUAL( expected, remaining );
981 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
982 // also slightly perturbed
983 const double amplitude = 0.05;
984 perturbPolygon(polygon, amplitude);
985 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
986 }
987
988 // test with two points, full rotation
989 {
990 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
994 SphericalPointDistribution::Polygon_t expected =
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 =
1002 SPD.getRemainingPoints(polygon, 4, 4);
1003// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1004 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1005 // also slightly perturbed
1006 const double amplitude = 0.05;
1007 perturbPolygon(polygon, amplitude);
1008 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1009 }
1010
1011 // test with three points, matching trivially
1012 {
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);
1017 SphericalPointDistribution::Polygon_t expected =
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 =
1023 SPD.getRemainingPoints(polygon, 4, 4);
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 three 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 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1./3.0, -M_SQRT2/3.0, M_SQRT2/sqrt(3)), 47.6/180*M_PI), 1);
1039 SphericalPointDistribution::Polygon_t expected =
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 =
1048 SPD.getRemainingPoints(polygon, 4, 4);
1049// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1050 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1051 // also slightly perturbed
1052 const double amplitude = 0.05;
1053 perturbPolygon(polygon, amplitude);
1054 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1055 }
1056}
1057
1058/** UnitTest for getRemainingPoints() with four points and weights
1059 * not all equal to one.
1060 */
1061void SphericalPointDistributionTest::getRemainingPointsTest_multiple()
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 =
1075 SPD.getRemainingPoints(polygon, 4, 4);
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 =
1092 SPD.getRemainingPoints(polygon, 5, 5);
1093 std::cout << std::setprecision(13) << "Matched polygon is " << remaining << std::endl;
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 =
1110 SPD.getRemainingPoints(polygon, 5, 5);
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.);
1125 expected += Vector(0.,0.,-1.);
1126 SphericalPointDistribution::Polygon_t remaining =
1127 SPD.getRemainingPoints(polygon, 6, 6);
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
1134/** UnitTest for getRemainingPoints() with five points
1135 */
1136void SphericalPointDistributionTest::getRemainingPointsTest_5()
1137{
1138 SphericalPointDistribution SPD(1.);
1139
1140 // test with one point, matching trivially
1141 {
1142 SphericalPointDistribution::WeightedPolygon_t polygon;
1143 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1144 SphericalPointDistribution::Polygon_t expected =
1145 SPD.get<5>();
1146 expected.pop_front(); // remove first point
1147 SphericalPointDistribution::Polygon_t remaining =
1148 SPD.getRemainingPoints(polygon, 5, 5);
1149// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1150 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1151 }
1152
1153 // test with one point, just a flip of axis
1154 {
1155 SphericalPointDistribution::WeightedPolygon_t polygon;
1156 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1157 SphericalPointDistribution::Polygon_t expected =
1158 SPD.get<5>();
1159 expected.pop_front(); // remove first point
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 }
1165 SphericalPointDistribution::Polygon_t remaining =
1166 SPD.getRemainingPoints(polygon, 5, 5);
1167// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1168 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1169 }
1170
1171 // test with two points, matching trivially
1172 {
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);
1176 SphericalPointDistribution::Polygon_t expected =
1177 SPD.get<5>();
1178 expected.pop_front(); // remove first point
1179 expected.pop_front(); // remove second point
1180 SphericalPointDistribution::Polygon_t remaining =
1181 SPD.getRemainingPoints(polygon, 5, 5);
1182// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1183 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1184 // also slightly perturbed
1185 const double amplitude = 0.05;
1186 perturbPolygon(polygon, amplitude);
1187 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1188 }
1189
1190 // test with two points, full rotation
1191 {
1192 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
1196 SphericalPointDistribution::Polygon_t expected =
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 =
1204 SPD.getRemainingPoints(polygon, 5, 5);
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() );
1209 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1210 fixiter != polygon.end(); ++fixiter) {
1211 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1212 iter != remaining.end(); ++iter) {
1213 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1214 }
1215 }
1216 }
1217
1218 // test with three points, matching trivially
1219 {
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);
1224 SphericalPointDistribution::Polygon_t expected =
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 =
1230 SPD.getRemainingPoints(polygon, 5, 5);
1231// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1232 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1233 // also slightly perturbed
1234 const double amplitude = 0.05;
1235 perturbPolygon(polygon, amplitude);
1236 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1237 }
1238
1239 // test with three points, full rotation
1240 {
1241 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
1246 SphericalPointDistribution::Polygon_t expected =
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 =
1255 SPD.getRemainingPoints(polygon, 5, 5);
1256// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1257 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1258 // also slightly perturbed
1259 const double amplitude = 0.05;
1260 perturbPolygon(polygon, amplitude);
1261 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1262 }
1263}
1264
1265/** UnitTest for getRemainingPoints() with six points
1266 */
1267void SphericalPointDistributionTest::getRemainingPointsTest_6()
1268{
1269 SphericalPointDistribution SPD(1.);
1270
1271 // test with one point, matching trivially
1272 {
1273 SphericalPointDistribution::WeightedPolygon_t polygon;
1274 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1275 SphericalPointDistribution::Polygon_t expected =
1276 SPD.get<6>();
1277 expected.pop_front(); // remove first point
1278 SphericalPointDistribution::Polygon_t remaining =
1279 SPD.getRemainingPoints(polygon, 6, 6);
1280// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1281 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1282 }
1283
1284 // test with one point, just a flip of axis
1285 {
1286 SphericalPointDistribution::WeightedPolygon_t polygon;
1287 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1288 SphericalPointDistribution::Polygon_t expected =
1289 SPD.get<6>();
1290 expected.pop_front(); // remove first point
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 }
1296 SphericalPointDistribution::Polygon_t remaining =
1297 SPD.getRemainingPoints(polygon, 6, 6);
1298// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1299 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1300 }
1301
1302 // test with two points, matching trivially
1303 {
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);
1307 SphericalPointDistribution::Polygon_t expected =
1308 SPD.get<6>();
1309 expected.pop_front(); // remove first point
1310 expected.pop_front(); // remove second spoint
1311 SphericalPointDistribution::Polygon_t remaining =
1312 SPD.getRemainingPoints(polygon, 6, 6);
1313// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1314 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1315 // also slightly perturbed
1316 const double amplitude = 0.05;
1317 perturbPolygon(polygon, amplitude);
1318 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1319 }
1320
1321 // test with two points, full rotation
1322 {
1323 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
1327 SphericalPointDistribution::Polygon_t expected =
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 =
1335 SPD.getRemainingPoints(polygon, 6, 6);
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() );
1340 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1341 fixiter != polygon.end(); ++fixiter) {
1342 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1343 iter != remaining.end(); ++iter) {
1344 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1345 }
1346 }
1347 }
1348
1349 // test with three points, matching trivially
1350 {
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);
1355 SphericalPointDistribution::Polygon_t expected =
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 =
1361 SPD.getRemainingPoints(polygon, 6, 6);
1362// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1363 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1364 // also slightly perturbed
1365 const double amplitude = 0.05;
1366 perturbPolygon(polygon, amplitude);
1367 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1368 }
1369
1370 // test with three points, full rotation
1371 {
1372 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
1377 SphericalPointDistribution::Polygon_t expected =
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 =
1386 SPD.getRemainingPoints(polygon, 6, 6);
1387// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1388 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1389 // also slightly perturbed
1390 const double amplitude = 0.05;
1391 perturbPolygon(polygon, amplitude);
1392 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1393 }
1394}
1395
1396/** UnitTest for getRemainingPoints() with seven points
1397 */
1398void SphericalPointDistributionTest::getRemainingPointsTest_7()
1399{
1400 SphericalPointDistribution SPD(1.);
1401
1402 // test with one point, matching trivially
1403 {
1404 SphericalPointDistribution::WeightedPolygon_t polygon;
1405 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1406 SphericalPointDistribution::Polygon_t expected =
1407 SPD.get<7>();
1408 expected.pop_front(); // remove first point
1409 SphericalPointDistribution::Polygon_t remaining =
1410 SPD.getRemainingPoints(polygon, 7, 7);
1411// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1412 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1413 }
1414
1415 // test with one point, just a flip of axis
1416 {
1417 SphericalPointDistribution::WeightedPolygon_t polygon;
1418 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1419 SphericalPointDistribution::Polygon_t expected =
1420 SPD.get<7>();
1421 expected.pop_front(); // remove first point
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 }
1427 SphericalPointDistribution::Polygon_t remaining =
1428 SPD.getRemainingPoints(polygon, 7, 7);
1429// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1430 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1431 }
1432
1433 // test with two points, matching trivially
1434 {
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);
1438 SphericalPointDistribution::Polygon_t expected =
1439 SPD.get<7>();
1440 expected.pop_front(); // remove first point
1441 expected.pop_front(); // remove second point
1442 SphericalPointDistribution::Polygon_t remaining =
1443 SPD.getRemainingPoints(polygon, 7, 7);
1444// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1445 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1446 // also slightly perturbed
1447 const double amplitude = 0.05;
1448 perturbPolygon(polygon, amplitude);
1449 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1450 }
1451
1452 // test with two points, full rotation
1453 {
1454 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
1458 SphericalPointDistribution::Polygon_t expected =
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 =
1466 SPD.getRemainingPoints(polygon, 7, 7);
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() );
1471 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
1472 fixiter != polygon.end(); ++fixiter) {
1473 for (SphericalPointDistribution::Polygon_t::const_iterator iter = remaining.begin();
1474 iter != remaining.end(); ++iter) {
1475 CPPUNIT_ASSERT( (fixiter->first).IsNormalTo(*iter) );
1476 }
1477 }
1478 }
1479
1480 // test with three points, matching trivially
1481 {
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);
1486 SphericalPointDistribution::Polygon_t expected =
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 =
1492 SPD.getRemainingPoints(polygon, 7, 7);
1493// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1494 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1495 // also slightly perturbed
1496 const double amplitude = 0.05;
1497 perturbPolygon(polygon, amplitude);
1498 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1499 }
1500
1501 // test with three points, full rotation
1502 {
1503 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
1508 SphericalPointDistribution::Polygon_t expected =
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 =
1517 SPD.getRemainingPoints(polygon, 7, 7);
1518// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1519 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1520 // also slightly perturbed
1521 const double amplitude = 0.05;
1522 perturbPolygon(polygon, amplitude);
1523 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1524 }
1525}
1526
1527/** UnitTest for getRemainingPoints() with eight points
1528 */
1529void SphericalPointDistributionTest::getRemainingPointsTest_8()
1530{
1531 SphericalPointDistribution SPD(1.);
1532
1533 // test with one point, matching trivially
1534 {
1535 SphericalPointDistribution::WeightedPolygon_t polygon;
1536 polygon += std::make_pair( Vector(1.,0.,0.), 1);
1537 SphericalPointDistribution::Polygon_t expected =
1538 SPD.get<8>();
1539 expected.pop_front(); // remove first point
1540 SphericalPointDistribution::Polygon_t remaining =
1541 SPD.getRemainingPoints(polygon, 8, 8);
1542// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1543 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1544 }
1545
1546 // test with one point, just a flip of axis
1547 {
1548 SphericalPointDistribution::WeightedPolygon_t polygon;
1549 polygon += std::make_pair( Vector(0.,1.,0.), 1);
1550 SphericalPointDistribution::Polygon_t expected =
1551 SPD.get<8>();
1552 expected.pop_front(); // remove first point
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 }
1558 SphericalPointDistribution::Polygon_t remaining =
1559 SPD.getRemainingPoints(polygon, 8, 8);
1560// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1561 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1562 }
1563
1564 // test with two points, matching trivially
1565 {
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);
1569 SphericalPointDistribution::Polygon_t expected =
1570 SPD.get<8>();
1571 expected.pop_front(); // remove first point
1572 expected.pop_front(); // remove second point
1573 SphericalPointDistribution::Polygon_t remaining =
1574 SPD.getRemainingPoints(polygon, 8, 8);
1575// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1576 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1577 // also slightly perturbed
1578 const double amplitude = 0.05;
1579 perturbPolygon(polygon, amplitude);
1580 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1581 }
1582
1583 // test with two points, full rotation
1584 {
1585 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
1586 SphericalPointDistribution::WeightedPolygon_t polygon;
1587 polygon += std::make_pair(RotationAxis.rotateVector(Vector(1.,0.,0.), 47.6/180*M_PI), 1);
1588 polygon += std::make_pair(RotationAxis.rotateVector(Vector(-1.,0.,0.), 47.6/180*M_PI), 1);
1589 SphericalPointDistribution::Polygon_t expected =
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 =
1597 SPD.getRemainingPoints(polygon, 8, 8);
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() );
1602 for (SphericalPointDistribution::WeightedPolygon_t::const_iterator fixiter = polygon.begin();
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) );
1609 CPPUNIT_ASSERT( fabs( (*expectiter).Angle(fixiter->first) - (*remainiter).Angle(fixiter->first) )
1610 < std::numeric_limits<double>::epsilon()*1e4 );
1611 }
1612 }
1613 }
1614
1615 // test with three points, matching trivially
1616 {
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);
1621 SphericalPointDistribution::Polygon_t expected =
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 =
1627 SPD.getRemainingPoints(polygon, 8, 8);
1628// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1629 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1630 // also slightly perturbed
1631 const double amplitude = 0.05;
1632 perturbPolygon(polygon, amplitude);
1633 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1634 }
1635
1636 // test with three points, full rotation
1637 {
1638 Line RotationAxis(zeroVec, Vector(0.2, 0.43, 0.6893248));
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);
1643 SphericalPointDistribution::Polygon_t expected =
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 =
1652 SPD.getRemainingPoints(polygon, 8, 8);
1653// CPPUNIT_ASSERT_EQUAL( expected, remaining );
1654 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, CenterAccuracy) );
1655 // also slightly perturbed
1656 const double amplitude = 0.05;
1657 perturbPolygon(polygon, amplitude);
1658 CPPUNIT_ASSERT( areEqualToWithinBounds(expected, remaining, amplitude) );
1659 }
1660}
Note: See TracBrowser for help on using the repository browser.