source: src/Fragmentation/Exporters/SphericalPointDistribution.hpp@ 3da643

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

Using the idea of three points giving a triangle to find rotation axis.

  • we calculate the center of either triangle and rotate the center of the ideal point distribution to match the one from the given points.
  • next we have the triangles normals as axis, take the first matching point and rotate align it.
  • we have to deal with a lot of special cases: What if only zero, one, or two points are given ...
  • in general we assume that the triangle lies relatively flat on the sphere's surface but what if the origin is in the triangle plane or even the calculated center is at the origin ...
  • TESTS: SphericalPointDistributionUnitTest working again, regression tests FragmentMolecule-cylces and StoreSaturatedFragment working.
  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * SphericalPointDistribution.hpp
3 *
4 * Created on: May 29, 2014
5 * Author: heber
6 */
7
8
9#ifndef SPHERICALPOINTDISTRIBUTION_HPP_
10#define SPHERICALPOINTDISTRIBUTION_HPP_
11
12// include config.h
13#ifdef HAVE_CONFIG_H
14#include <config.h>
15#endif
16
17#include "CodePatterns/Assert.hpp"
18
19#include <cmath>
20#include <list>
21
22#include "LinearAlgebra/Vector.hpp"
23
24/** contains getters for the VSEPR model for specific number of electrons.
25 *
26 * This struct contains specialized functions returning a list of Vectors
27 * (points in space) to match the VSEPR model for the given number of electrons.
28 *
29 * This is implemented via template specialization of the function get().
30 *
31 * These specializations are taken from the python script \b CreateVspeShapes.py
32 * by Christian Neuen, 07th May 2009.
33 */
34struct SphericalPointDistribution
35{
36 /** Cstor for SphericalPointDistribution, allows setting radius of sphere
37 *
38 * \param _BondLength desired radius of sphere
39 */
40 SphericalPointDistribution(const double _Bondlength = 1.) :
41 Bondlength(_Bondlength),
42 SQRT_3(sqrt(3.0))
43 {}
44
45 //!> typedef for the list of points
46 typedef std::list<Vector> Polygon_t;
47
48 /** General getter function for the distribution of points on the surface.
49 *
50 * \warn this function needs to be specialized!
51 *
52 * \return Polygon_t with points on the surface centered at (0,0,0)
53 */
54 template <int N> Polygon_t get()
55 {
56 ASSERT(0, "SphericalPointDistribution::get() - not specialized for "+toString(N)+".");
57 }
58
59
60 /** Matches a given spherical distribution with another containing more
61 * points.
62 *
63 * The idea is to produce a matching from all points in \a _polygon to those
64 * in \a _newpolygon in such a way that their distance difference is minimal.
65 * As we just look at numbers of points determined by valency, i.e.
66 * independent of the number of atoms, we simply go through each of the possible
67 * mappings. We stop when the L1 error is below a certain \a threshold,
68 * otherwise we pick the matching with the lowest L2 error.
69 *
70 * This is a helper to determine points where to best insert saturation
71 * hydrogens.
72 *
73 * \param _polygon current occupied positions
74 * \param _newpolygon ideal distribution to match best with current occupied
75 * positions
76 * \return remaining vacant positions relative to \a _polygon
77 */
78 static Polygon_t matchSphericalPointDistributions(
79 const Polygon_t &_polygon,
80 const Polygon_t &_newpolygon
81 );
82
83 //!> default radius of the spherical distribution
84 const double Bondlength;
85 //!> precalculated value for root of 3
86 const double SQRT_3;
87
88 typedef std::pair<Vector, double> Rotation_t;
89
90 typedef std::list<unsigned int> IndexList_t;
91 typedef std::vector<unsigned int> IndexArray_t;
92 typedef std::vector<Vector> VectorArray_t;
93
94 //!> amplitude up to which deviations in checks of rotations are tolerated
95 static const double warn_amplitude;
96
97private:
98 static std::pair<double, double> calculateErrorOfMatching(
99 const std::vector<Vector> &_old,
100 const std::vector<Vector> &_new,
101 const IndexList_t &_Matching);
102
103 static Polygon_t removeMatchingPoints(
104 const VectorArray_t &_points,
105 const IndexList_t &_matchingindices
106 );
107
108 struct MatchingControlStructure {
109 bool foundflag;
110 double bestL2;
111 IndexList_t bestmatching;
112 VectorArray_t oldpoints;
113 VectorArray_t newpoints;
114 };
115
116 static void recurseMatchings(
117 MatchingControlStructure &_MCS,
118 IndexList_t &_matching,
119 IndexList_t _indices,
120 unsigned int _matchingsize);
121
122 static IndexList_t findBestMatching(
123 const Polygon_t &_polygon,
124 const Polygon_t &_newpolygon
125 );
126
127 static Rotation_t findPlaneAligningRotation(
128 const VectorArray_t &_referencepositions,
129 const VectorArray_t &_currentpositions,
130 const IndexList_t &_bestmatching
131 );
132
133 static Rotation_t findPointAligningRotation(
134 const VectorArray_t &remainingold,
135 const VectorArray_t &remainingnew,
136 const IndexList_t &_bestmatching);
137
138};
139
140// declare specializations
141
142template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<0>();
143template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<1>();
144template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<2>();
145template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<3>();
146template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<4>();
147template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<5>();
148template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<6>();
149template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<7>();
150template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<8>();
151template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<9>();
152template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<10>();
153template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<11>();
154template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<12>();
155template <> SphericalPointDistribution::Polygon_t SphericalPointDistribution::get<14>();
156
157#endif /* SPHERICALPOINTDISTRIBUTION_HPP_ */
Note: See TracBrowser for help on using the repository browser.