source: src/Tesselation/BoundaryLineSet.cpp@ 4464ef

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_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_levmar Subpackage_vmg ThirdParty_MPQC_rebuilt_buildsystem TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps Ubuntu_1604_changes stable
Last change on this file since 4464ef was b8d215, checked in by Frederik Heber <heber@…>, 10 years ago

Changed some verbosities in Tesselation code.

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. 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 * BoundaryLineSet.cpp
25 *
26 * Created on: Jul 29, 2010
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35#include "CodePatterns/MemDebug.hpp"
36
37#include "BoundaryLineSet.hpp"
38
39#include <iostream>
40
41#include "BoundaryPointSet.hpp"
42#include "BoundaryTriangleSet.hpp"
43#include "Atom/TesselPoint.hpp"
44
45#include "CodePatterns/Assert.hpp"
46#include "CodePatterns/Info.hpp"
47#include "CodePatterns/Log.hpp"
48#include "CodePatterns/Verbose.hpp"
49#include "tesselationhelpers.hpp"
50#include "LinearAlgebra/Vector.hpp"
51
52using namespace std;
53
54/** Constructor of BoundaryLineSet.
55 */
56BoundaryLineSet::BoundaryLineSet() :
57 Nr(-1)
58{
59 //Info FunctionInfo(__func__);
60 for (int i = 0; i < 2; i++)
61 endpoints[i] = NULL;
62}
63;
64
65/** Constructor of BoundaryLineSet with two endpoints.
66 * Adds line automatically to each endpoints' LineMap
67 * \param *Point[2] array of two boundary points
68 * \param number number of the list
69 */
70BoundaryLineSet::BoundaryLineSet(BoundaryPointSet * const Point[2], const int number)
71{
72 //Info FunctionInfo(__func__);
73 // set number
74 Nr = number;
75 // set endpoints in ascending order
76 SetEndpointsOrdered(endpoints, Point[0], Point[1]);
77 // add this line to the hash maps of both endpoints
78 Point[0]->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding.
79 Point[1]->AddLine(this); //
80 // set skipped to false
81 skipped = false;
82 // clear triangles list
83 LOG(5, "DEBUG: New Line with endpoints " << *this << ".");
84}
85;
86
87/** Constructor of BoundaryLineSet with two endpoints.
88 * Adds line automatically to each endpoints' LineMap
89 * \param *Point1 first boundary point
90 * \param *Point2 second boundary point
91 * \param number number of the list
92 */
93BoundaryLineSet::BoundaryLineSet(BoundaryPointSet * const Point1, BoundaryPointSet * const Point2, const int number) :
94 Nr(number),
95 skipped(false)
96{
97 //Info FunctionInfo(__func__);
98 // set endpoints in ascending order
99 SetEndpointsOrdered(endpoints, Point1, Point2);
100 // add this line to the hash maps of both endpoints
101 Point1->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding.
102 Point2->AddLine(this); //
103 // clear triangles list
104 LOG(5, "DEBUG: New Line with endpoints " << *this << ".");
105}
106;
107
108/** Destructor for BoundaryLineSet.
109 * Removes itself from each endpoints' LineMap, calling RemoveTrianglePoint() when point not connected anymore.
110 * \note When removing lines from a class Tesselation, use RemoveTesselationLine()
111 */
112BoundaryLineSet::~BoundaryLineSet()
113{
114 //Info FunctionInfo(__func__);
115 int Numbers[2];
116
117 // get other endpoint number of finding copies of same line
118 if (endpoints[1] != NULL)
119 Numbers[0] = endpoints[1]->Nr;
120 else
121 Numbers[0] = -1;
122 if (endpoints[0] != NULL)
123 Numbers[1] = endpoints[0]->Nr;
124 else
125 Numbers[1] = -1;
126
127 for (int i = 0; i < 2; i++) {
128 if (endpoints[i] != NULL) {
129 if (Numbers[i] != -1) { // as there may be multiple lines with same endpoints, we have to go through each and find in the endpoint's line list this line set
130 pair<LineMap::iterator, LineMap::iterator> erasor = endpoints[i]->lines.equal_range(Numbers[i]);
131 for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++)
132 if ((*Runner).second == this) {
133 //LOG(0, "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << ".");
134 endpoints[i]->lines.erase(Runner);
135 break;
136 }
137 } else { // there's just a single line left
138 if (endpoints[i]->lines.erase(Nr)) {
139 //LOG(0, "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << ".");
140 }
141 }
142 if (endpoints[i]->lines.empty()) {
143 //LOG(0, *endpoints[i] << " has no more lines it's attached to, erasing.");
144 if (endpoints[i] != NULL) {
145 delete (endpoints[i]);
146 endpoints[i] = NULL;
147 }
148 }
149 }
150 }
151 if (!triangles.empty())
152 ELOG(2, "Memory Leak! I " << *this << " am still connected to some triangles.");
153}
154;
155
156/** Add triangle to TriangleMap of this boundary line.
157 * \param *triangle to add
158 */
159void BoundaryLineSet::AddTriangle(BoundaryTriangleSet * const triangle)
160{
161 //Info FunctionInfo(__func__);
162 LOG(5, "DEBUG: Add " << triangle->Nr << " to line " << *this << ".");
163 triangles.insert(TrianglePair(triangle->Nr, triangle));
164}
165;
166
167/** Checks whether we have a common endpoint with given \a *line.
168 * \param *line other line to test
169 * \return true - common endpoint present, false - not connected
170 */
171bool BoundaryLineSet::IsConnectedTo(const BoundaryLineSet * const line) const
172{
173 //Info FunctionInfo(__func__);
174 if ((endpoints[0] == line->endpoints[0]) || (endpoints[1] == line->endpoints[0]) || (endpoints[0] == line->endpoints[1]) || (endpoints[1] == line->endpoints[1]))
175 return true;
176 else
177 return false;
178}
179;
180
181/** Checks whether the adjacent triangles of a baseline are convex or not.
182 * We sum the two angles of each height vector with respect to the center of the baseline.
183 * If greater/equal M_PI than we are convex.
184 * \param *out output stream for debugging
185 * \return true - triangles are convex, false - concave or less than two triangles connected
186 */
187bool BoundaryLineSet::CheckConvexityCriterion() const
188{
189 //Info FunctionInfo(__func__);
190 double angle = CalculateConvexity();
191 if (angle > -MYEPSILON) {
192 LOG(3, "ACCEPT: Angle is greater than pi: convex.");
193 return true;
194 } else {
195 LOG(3, "REJECT: Angle is less than pi: concave.");
196 return false;
197 }
198}
199
200
201/** Calculates the angle between two triangles with respect to their normal vector.
202 * We sum the two angles of each height vector with respect to the center of the baseline.
203 * \return angle > 0 then convex, if < 0 then concave
204 */
205double BoundaryLineSet::CalculateConvexity() const
206{
207 //Info FunctionInfo(__func__);
208 Vector BaseLineCenter, BaseLineNormal, BaseLine, helper[2], NormalCheck;
209 // get the two triangles
210 if (triangles.size() != 2) {
211 ELOG(0, "Baseline " << *this << " is connected to less than two triangles, Tesselation incomplete!");
212 return true;
213 }
214 // check normal vectors
215 // have a normal vector on the base line pointing outwards
216 //LOG(0, "INFO: " << *this << " has vectors at " << *(endpoints[0]->node->node) << " and at " << *(endpoints[1]->node->node) << ".");
217 BaseLineCenter = (1./2.)*((endpoints[0]->node->getPosition()) + (endpoints[1]->node->getPosition()));
218 BaseLine = (endpoints[0]->node->getPosition()) - (endpoints[1]->node->getPosition());
219
220 //LOG(0, "INFO: Baseline is " << BaseLine << " and its center is at " << BaseLineCenter << ".");
221
222 BaseLineNormal.Zero();
223 NormalCheck.Zero();
224 double sign = -1.;
225 int i = 0;
226 class BoundaryPointSet *node = NULL;
227 for (TriangleMap::const_iterator runner = triangles.begin(); runner != triangles.end(); runner++) {
228 //LOG(0, "INFO: NormalVector of " << *(runner->second) << " is " << runner->second->NormalVector << ".");
229 NormalCheck += runner->second->NormalVector;
230 NormalCheck *= sign;
231 sign = -sign;
232 if (runner->second->NormalVector.NormSquared() > MYEPSILON)
233 BaseLineNormal = runner->second->NormalVector; // yes, copy second on top of first
234 else {
235 ELOG(0, "Triangle " << *runner->second << " has zero normal vector!");
236 }
237 node = runner->second->GetThirdEndpoint(this);
238 if (node != NULL) {
239 //LOG(0, "INFO: Third node for triangle " << *(runner->second) << " is " << *node << " at " << *(node->node->node) << ".");
240 helper[i] = (node->node->getPosition()) - BaseLineCenter;
241 helper[i].MakeNormalTo(BaseLine); // we want to compare the triangle's heights' angles!
242 //LOG(0, "INFO: Height vector with respect to baseline is " << helper[i] << ".");
243 i++;
244 } else {
245 ELOG(1, "I cannot find third node in triangle, something's wrong.");
246 return true;
247 }
248 }
249 //LOG(0, "INFO: BaselineNormal is " << BaseLineNormal << ".");
250 if (NormalCheck.NormSquared() < MYEPSILON) {
251 LOG(3, "ACCEPT: Normalvectors of both triangles are the same: convex.");
252 return true;
253 }
254 BaseLineNormal.Scale(-1.);
255 double angle = GetAngle(helper[0], helper[1], BaseLineNormal);
256 return (angle - M_PI);
257}
258
259/** Checks whether point is any of the two endpoints this line contains.
260 * \param *point point to test
261 * \return true - point is of the line, false - is not
262 */
263bool BoundaryLineSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const
264{
265 //Info FunctionInfo(__func__);
266 for (int i = 0; i < 2; i++)
267 if (point == endpoints[i])
268 return true;
269 return false;
270}
271;
272
273/** Returns other endpoint of the line.
274 * \param *point other endpoint
275 * \return NULL - if endpoint not contained in BoundaryLineSet::lines, or pointer to BoundaryPointSet otherwise
276 */
277class BoundaryPointSet *BoundaryLineSet::GetOtherEndpoint(const BoundaryPointSet * const point) const
278{
279 //Info FunctionInfo(__func__);
280 if (endpoints[0] == point)
281 return endpoints[1];
282 else if (endpoints[1] == point)
283 return endpoints[0];
284 else
285 return NULL;
286}
287;
288
289/** Returns other triangle of the line.
290 * \param *point other endpoint
291 * \return NULL - if triangle not contained in BoundaryLineSet::triangles, or pointer to BoundaryTriangleSet otherwise
292 */
293class BoundaryTriangleSet *BoundaryLineSet::GetOtherTriangle(const BoundaryTriangleSet * const triangle) const
294{
295 //Info FunctionInfo(__func__);
296 if (triangles.size() == 2) {
297 for (TriangleMap::const_iterator TriangleRunner = triangles.begin(); TriangleRunner != triangles.end(); ++TriangleRunner)
298 if (TriangleRunner->second != triangle)
299 return TriangleRunner->second;
300 }
301 return NULL;
302}
303;
304
305/** output operator for BoundaryLineSet.
306 * \param &ost output stream
307 * \param &a boundary line
308 */
309ostream & operator <<(ostream &ost, const BoundaryLineSet &a)
310{
311 ost << "[" << a.Nr << "|" << a.endpoints[0]->node->getName() << "," << a.endpoints[1]->node->getName() << "]";
312 //ost << "[" << a.Nr << "|" << a.endpoints[0]->node->getName() << " at " << a.endpoints[0]->node->getPosition() << "," << a.endpoints[1]->node->getName() << " at " << a.endpoints[1]->node->getPosition() << "]";
313 return ost;
314}
315;
Note: See TracBrowser for help on using the repository browser.