source: src/Tesselation/BoundaryTriangleSet.cpp@ b4f72c

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing 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_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since b4f72c was 94d5ac6, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: As we use GSL internally, we are as of now required to use GPL v2 license.

  • GNU Scientific Library is used at every place in the code, especially the sub-package LinearAlgebra is based on it which in turn is used really everywhere in the remainder of MoleCuilder. Hence, we have to use the GPL license for the whole of MoleCuilder. In effect, GPL's COPYING was present all along and stated the terms of the GPL v2 license.
  • Hence, I added the default GPL v2 disclaimer to every source file and removed the note about a (actually missing) LICENSE file.
  • also, I added a help-redistribute action which again gives the disclaimer of the GPL v2.
  • also, I changed in the disclaimer that is printed at every program start in builder_init.cpp.
  • TEST: Added check on GPL statement present in every module to test CodeChecks project-disclaimer.
  • Property mode set to 100644
File size: 21.1 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 * BoundaryTriangleSet.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 "BoundaryTriangleSet.hpp"
38
39#include <iostream>
40
41#include "BoundaryLineSet.hpp"
42#include "BoundaryPointSet.hpp"
43#include "Atom/TesselPoint.hpp"
44
45#include "Helpers/defs.hpp"
46
47#include "CodePatterns/Assert.hpp"
48#include "CodePatterns/Info.hpp"
49#include "CodePatterns/Log.hpp"
50#include "CodePatterns/Verbose.hpp"
51#include "LinearAlgebra/Exceptions.hpp"
52#include "LinearAlgebra/Line.hpp"
53#include "LinearAlgebra/Plane.hpp"
54#include "LinearAlgebra/Vector.hpp"
55
56using namespace std;
57
58/** Constructor for BoundaryTriangleSet.
59 */
60BoundaryTriangleSet::BoundaryTriangleSet() :
61 Nr(-1)
62{
63 //Info FunctionInfo(__func__);
64 for (int i = 0; i < 3; i++) {
65 endpoints[i] = NULL;
66 lines[i] = NULL;
67 }
68}
69;
70
71/** Constructor for BoundaryTriangleSet with three lines.
72 * \param *line[3] lines that make up the triangle
73 * \param number number of triangle
74 */
75BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet * const line[3], const int number) :
76 Nr(number)
77{
78 //Info FunctionInfo(__func__);
79 // set number
80 // set lines
81 for (int i = 0; i < 3; i++) {
82 lines[i] = line[i];
83 lines[i]->AddTriangle(this);
84 }
85 // get ascending order of endpoints
86 PointMap OrderMap;
87 for (int i = 0; i < 3; i++) {
88 // for all three lines
89 for (int j = 0; j < 2; j++) { // for both endpoints
90 OrderMap.insert(pair<int, class BoundaryPointSet *> (line[i]->endpoints[j]->Nr, line[i]->endpoints[j]));
91 // and we don't care whether insertion fails
92 }
93 }
94 // set endpoints
95 int Counter = 0;
96 LOG(4, "DEBUG: New triangle " << Nr << " with end points: ");
97 for (PointMap::iterator runner = OrderMap.begin(); runner != OrderMap.end(); runner++) {
98 endpoints[Counter] = runner->second;
99 LOG(4, "DEBUG: " << *endpoints[Counter]);
100 Counter++;
101 }
102 ASSERT(Counter >= 3,"We have a triangle with only two distinct endpoints!");
103};
104
105
106/** Destructor of BoundaryTriangleSet.
107 * Removes itself from each of its lines' LineMap and removes them if necessary.
108 * \note When removing triangles from a class Tesselation, use RemoveTesselationTriangle()
109 */
110BoundaryTriangleSet::~BoundaryTriangleSet()
111{
112 //Info FunctionInfo(__func__);
113 for (int i = 0; i < 3; i++) {
114 if (lines[i] != NULL) {
115 if (lines[i]->triangles.erase(Nr)) {
116 //LOG(5, "DEBUG: Triangle Nr." << Nr << " erased in line " << *lines[i] << ".");
117 }
118 if (lines[i]->triangles.empty()) {
119 //LOG(5, "DEBUG: " << *lines[i] << " is no more attached to any triangle, erasing.");
120 delete (lines[i]);
121 lines[i] = NULL;
122 }
123 }
124 }
125 //LOG(5, "DEBUG: Erasing triangle Nr." << Nr << " itself.");
126}
127;
128
129/** Calculates the area of this triangle.
130 *
131 * @return surface area in between the tree points of this triangle
132 */
133double BoundaryTriangleSet::getArea() const
134{
135 Vector x;
136 Vector y;
137 x = getEndpoint(0) - getEndpoint(1);
138 y = getEndpoint(0) - getEndpoint(2);
139 const double a = x.Norm();
140 const double b = y.Norm();
141 const double c = getEndpoint(2).distance(getEndpoint(1));
142 const double area = sqrt(((a + b + c) * (a + b + c) - 2 * (a * a + b * b + c * c)) / 16.); // area of tesselated triangle
143 return area;
144}
145
146/** Calculates the normal vector for this triangle.
147 * Is made unique by comparison with \a OtherVector to point in the other direction.
148 * \param &OtherVector direction vector to make normal vector unique.
149 */
150void BoundaryTriangleSet::GetNormalVector(const Vector &OtherVector)
151{
152 //Info FunctionInfo(__func__);
153 // get normal vector
154 NormalVector = Plane((endpoints[0]->node->getPosition()),
155 (endpoints[1]->node->getPosition()),
156 (endpoints[2]->node->getPosition())).getNormal();
157
158 // make it always point inward (any offset vector onto plane projected onto normal vector suffices)
159 if (NormalVector.ScalarProduct(OtherVector) > 0.)
160 NormalVector.Scale(-1.);
161 LOG(4, "DEBUG: Normal Vector of " << *this << " is " << NormalVector << ".");
162}
163;
164
165/** Finds the point on the triangle \a *BTS through which the line defined by \a *MolCenter and \a *x crosses.
166 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane
167 * Thus we test if it's really on the plane and whether it's inside the triangle on the plane or not.
168 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line
169 * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between
170 * the first two basepoints) or not.
171 * \param *out output stream for debugging
172 * \param &MolCenter offset vector of line
173 * \param &x second endpoint of line, minus \a *MolCenter is directional vector of line
174 * \param &Intersection intersection on plane on return
175 * \return true - \a *Intersection contains intersection on plane defined by triangle, false - zero vector if outside of triangle.
176 */
177
178bool BoundaryTriangleSet::GetIntersectionInsideTriangle(const Vector & MolCenter, const Vector & x, Vector &Intersection) const
179{
180 //Info FunctionInfo(__func__);
181 Vector CrossPoint;
182 Vector helper;
183
184 try {
185 Line centerLine = makeLineThrough(MolCenter, x);
186 Intersection = Plane(NormalVector, (endpoints[0]->node->getPosition())).GetIntersection(centerLine);
187
188 LOG(4, "DEBUG: Triangle is " << *this << ".");
189 LOG(4, "DEBUG: Line is from " << MolCenter << " to " << x << ".");
190 LOG(4, "DEBUG: Intersection is " << Intersection << ".");
191
192 if (Intersection.DistanceSquared(endpoints[0]->node->getPosition()) < MYEPSILON) {
193 LOG(4, "DEBUG: Intersection coindices with first endpoint.");
194 return true;
195 } else if (Intersection.DistanceSquared(endpoints[1]->node->getPosition()) < MYEPSILON) {
196 LOG(4, "DEBUG: Intersection coindices with second endpoint.");
197 return true;
198 } else if (Intersection.DistanceSquared(endpoints[2]->node->getPosition()) < MYEPSILON) {
199 LOG(4, "DEBUG: Intersection coindices with third endpoint.");
200 return true;
201 }
202 // Calculate cross point between one baseline and the line from the third endpoint to intersection
203 int i = 0;
204 do {
205 Line line1 = makeLineThrough((endpoints[i%3]->node->getPosition()),(endpoints[(i+1)%3]->node->getPosition()));
206 Line line2 = makeLineThrough((endpoints[(i+2)%3]->node->getPosition()),Intersection);
207 CrossPoint = line1.getIntersection(line2);
208 helper = (endpoints[(i+1)%3]->node->getPosition()) - (endpoints[i%3]->node->getPosition());
209 CrossPoint -= (endpoints[i%3]->node->getPosition()); // cross point was returned as absolute vector
210 const double s = CrossPoint.ScalarProduct(helper)/helper.NormSquared();
211 LOG(4, "DEBUG: Factor s is " << s << ".");
212 if ((s < -MYEPSILON) || ((s-1.) > MYEPSILON)) {
213 LOG(4, "DEBUG: Crosspoint " << CrossPoint << "outside of triangle.");
214 return false;
215 }
216 i++;
217 } while (i < 3);
218 LOG(4, "DEBUG: Crosspoint " << CrossPoint << " inside of triangle.");
219 return true;
220 }
221 catch (LinearAlgebraException &excp) {
222 LOG(1, boost::diagnostic_information(excp));
223 ELOG(1, "Alas! Intersection with plane failed - at least numerically - the intersection is not on the plane!");
224 return false;
225 }
226 return true;
227}
228
229
230/** Finds the point on the triangle to the point \a *x.
231 * We call Vector::GetIntersectionWithPlane() with \a * and the center of the triangle to receive an intersection point.
232 * Then we check the in-plane part (the part projected down onto plane). We check whether it crosses one of the
233 * boundary lines. If it does, we return this intersection as closest point, otherwise the projected point down.
234 * Thus we test if it's really on the plane and whether it's inside the triangle on the plane or not.
235 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line
236 * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between
237 * the first two basepoints) or not.
238 * \param *x point
239 * \param *ClosestPoint desired closest point inside triangle to \a *x, is absolute vector
240 * \return Distance squared between \a *x and closest point inside triangle
241 */
242double BoundaryTriangleSet::GetClosestPointInsideTriangle(const Vector &x, Vector &ClosestPoint) const
243{
244 //Info FunctionInfo(__func__);
245 Vector Direction;
246
247 // 1. get intersection with plane
248 LOG(3, "DEBUG: Looking for closest point of triangle " << *this << " to " << x << ".");
249 LOG(3, "DEBUG: endpoints are " << endpoints[0]->node->getPosition() << ","
250 << endpoints[1]->node->getPosition() << ", and " << endpoints[2]->node->getPosition() << ".");
251 try {
252 ClosestPoint = Plane(NormalVector, (endpoints[0]->node->getPosition())).getClosestPoint(x);
253 }
254 catch (LinearAlgebraException &excp) {
255 (ClosestPoint) = (x);
256 }
257 Vector InPlane(ClosestPoint); // points from plane intersection to straight-down point
258 LOG(4, "DEBUG: Closest point on triangle plane is " << ClosestPoint << ".");
259
260 // 2. Calculate in plane part of line (x, intersection)
261
262 // Calculate cross point between one baseline and the desired point such that distance is shortest
263 Vector CrossDirection[3];
264 Vector CrossPoint[3];
265 for (int i = 0; i < 3; i++) {
266 const Vector Direction = (endpoints[i%3]->node->getPosition()) - (endpoints[(i+1)%3]->node->getPosition());
267 // calculate intersection, line can never be parallel to Direction (is the same vector as PlaneNormal);
268 Line l = makeLineThrough((endpoints[i%3]->node->getPosition()), (endpoints[(i+1)%3]->node->getPosition()));
269 CrossPoint[i] = l.getClosestPoint(InPlane);
270 // NOTE: direction of line is normalized, hence s must not necessarily be in [0,1] for the baseline
271 LOG(4, "DEBUG: Closest point on line from " << (endpoints[(i+1)%3]->node->getPosition())
272 << " to " << (endpoints[i%3]->node->getPosition()) << " is " << CrossPoint[i] << ".");
273 CrossPoint[i] -= (endpoints[(i+1)%3]->node->getPosition()); // cross point was returned as absolute vector
274 const double s = CrossPoint[i].ScalarProduct(Direction)/Direction.NormSquared();
275 LOG(5, "DEBUG: Factor s is " << s << ".");
276 if ((s >= -MYEPSILON) && ((s-1.) <= MYEPSILON)) {
277 CrossPoint[i] += (endpoints[(i+1)%3]->node->getPosition()); // make cross point absolute again
278 LOG(5, "DEBUG: Crosspoint is " << CrossPoint[i] << ", intersecting BoundaryLine between "
279 << endpoints[i % 3]->node->getPosition() << " and "
280 << endpoints[(i + 1) % 3]->node->getPosition() << ".");
281 } else {
282 // set to either endpoint of BoundaryLine
283 if (s < -MYEPSILON)
284 CrossPoint[i] = (endpoints[(i+1)%3]->node->getPosition());
285 else
286 CrossPoint[i] = (endpoints[i%3]->node->getPosition());
287 LOG(5, "DEBUG: Crosspoint is " << CrossPoint[i] << ", intersecting outside of BoundaryLine between "
288 << endpoints[i % 3]->node->getPosition() << " and "
289 << endpoints[(i + 1) % 3]->node->getPosition() << ".");
290 }
291 CrossDirection[i] = CrossPoint[i] - InPlane;
292 }
293
294 bool InsideFlag = true;
295 double ShortestDistance = -1.;
296 for (int i = 0; i < 3; i++) {
297 const double sign = CrossDirection[i].ScalarProduct(CrossDirection[(i + 1) % 3]);
298 const double othersign = CrossDirection[i].ScalarProduct(CrossDirection[(i + 2) % 3]);
299
300 if ((sign > -MYEPSILON) && (othersign > -MYEPSILON)) // have different sign
301 InsideFlag = false;
302 // update current best candidate
303 const double distance = CrossPoint[i].DistanceSquared(x);
304 if ((ShortestDistance < 0.) || (ShortestDistance > distance)) {
305 ShortestDistance = distance;
306 (ClosestPoint) = CrossPoint[i];
307 }
308 }
309
310 if (InsideFlag) {
311 (ClosestPoint) = InPlane;
312 ShortestDistance = InPlane.DistanceSquared(x);
313 }
314 LOG(3, "DEBUG: Closest Point is " << ClosestPoint << " with shortest squared distance is " << ShortestDistance << ".");
315
316 return ShortestDistance;
317}
318
319
320/** Checks whether lines is any of the three boundary lines this triangle contains.
321 * \param *line line to test
322 * \return true - line is of the triangle, false - is not
323 */
324bool BoundaryTriangleSet::ContainsBoundaryLine(const BoundaryLineSet * const line) const
325{
326 //Info FunctionInfo(__func__);
327 for (int i = 0; i < 3; i++)
328 if (line == lines[i])
329 return true;
330 return false;
331}
332;
333
334/** Checks whether point is any of the three endpoints this triangle contains.
335 * \param *point point to test
336 * \return true - point is of the triangle, false - is not
337 */
338bool BoundaryTriangleSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const
339{
340 //Info FunctionInfo(__func__);
341 for (int i = 0; i < 3; i++)
342 if (point == endpoints[i])
343 return true;
344 return false;
345}
346;
347
348/** Checks whether point is any of the three endpoints this triangle contains.
349 * \param *point TesselPoint to test
350 * \return true - point is of the triangle, false - is not
351 */
352bool BoundaryTriangleSet::ContainsBoundaryPoint(const TesselPoint * const point) const
353{
354 //Info FunctionInfo(__func__);
355 for (int i = 0; i < 3; i++)
356 if (point == endpoints[i]->node)
357 return true;
358 return false;
359}
360;
361
362/** Checks whether three given \a *Points coincide with triangle's endpoints.
363 * \param *Points[3] pointer to BoundaryPointSet
364 * \return true - is the very triangle, false - is not
365 */
366bool BoundaryTriangleSet::IsPresentTupel(const BoundaryPointSet * const Points[3]) const
367{
368 //Info FunctionInfo(__func__);
369 LOG(1, "INFO: Checking " << Points[0] << "," << Points[1] << "," << Points[2] << " against " << endpoints[0] << "," << endpoints[1] << "," << endpoints[2] << ".");
370 return (((endpoints[0] == Points[0]) || (endpoints[0] == Points[1]) || (endpoints[0] == Points[2])) && ((endpoints[1] == Points[0]) || (endpoints[1] == Points[1]) || (endpoints[1] == Points[2])) && ((endpoints[2] == Points[0]) || (endpoints[2] == Points[1]) || (endpoints[2] == Points[2])
371
372 ));
373}
374;
375
376/** Checks whether three given \a *Points coincide with triangle's endpoints.
377 * \param *Points[3] pointer to BoundaryPointSet
378 * \return true - is the very triangle, false - is not
379 */
380bool BoundaryTriangleSet::IsPresentTupel(const BoundaryTriangleSet * const T) const
381{
382 //Info FunctionInfo(__func__);
383 return (((endpoints[0] == T->endpoints[0]) || (endpoints[0] == T->endpoints[1]) || (endpoints[0] == T->endpoints[2])) && ((endpoints[1] == T->endpoints[0]) || (endpoints[1] == T->endpoints[1]) || (endpoints[1] == T->endpoints[2])) && ((endpoints[2] == T->endpoints[0]) || (endpoints[2] == T->endpoints[1]) || (endpoints[2] == T->endpoints[2])
384
385 ));
386}
387;
388
389/** Checks whether a given point is inside the plane of the triangle and inside the
390 * bounds defined by its BoundaryLineSet's.
391 *
392 * @param point point to check
393 * @return true - point is inside place and inside all BoundaryLine's
394 */
395bool BoundaryTriangleSet::IsInsideTriangle(const Vector &point) const
396{
397 Info FunctionInfo(__func__);
398
399 // check if it's inside the plane
400 try {
401 Plane trianglePlane(
402 endpoints[0]->node->getPosition(),
403 endpoints[1]->node->getPosition(),
404 endpoints[2]->node->getPosition());
405 if (!trianglePlane.isContained(point)) {
406 LOG(1, "INFO: Point " << point << " is not inside plane " << trianglePlane << " by "
407 << trianglePlane.distance(point) << ".");
408 return false;
409 }
410 } catch(LinearDependenceException) {
411 // triangle is degenerated, it's just a line (i.e. one endpoint is right in between two others
412 for (size_t i = 0; i < NDIM; ++i) {
413 try {
414 Line l = makeLineThrough(
415 lines[i]->endpoints[0]->node->getPosition(),
416 lines[i]->endpoints[1]->node->getPosition());
417 if (l.isContained(GetThirdEndpoint(lines[i])->node->getPosition())) {
418 // we have the largest of the three lines
419 LOG(1, "INFO: Linear-dependent case where point " << point << " is on line " << l << ".");
420 return (l.isContained(point));
421 }
422 } catch(ZeroVectorException) {
423 // two points actually coincide
424 try {
425 Line l = makeLineThrough(
426 lines[i]->endpoints[0]->node->getPosition(),
427 GetThirdEndpoint(lines[i])->node->getPosition());
428 LOG(1, "INFO: Degenerated case where point " << point << " is on line " << l << ".");
429 return (l.isContained(point));
430 } catch(ZeroVectorException) {
431 // all three points coincide
432 if (point.DistanceSquared(lines[i]->endpoints[0]->node->getPosition()) < MYEPSILON) {
433 LOG(1, "INFO: Full-Degenerated case where point " << point << " is on three endpoints "
434 << lines[i]->endpoints[0]->node->getPosition() << ".");
435 return true;
436 }
437 else return false;
438 }
439 }
440 }
441 }
442
443 // check whether it lies on the correct side as given by third endpoint for
444 // each BoundaryLine.
445 // NOTE: we assume here that endpoints are linear independent, as the case
446 // has been caught before already extensively
447 for (size_t i = 0; i < NDIM; ++i) {
448 Line l = makeLineThrough(
449 lines[i]->endpoints[0]->node->getPosition(),
450 lines[i]->endpoints[1]->node->getPosition());
451 Vector onLine( l.getClosestPoint(point) );
452 LOG(1, "INFO: Closest point on boundary line is " << onLine << ".");
453 Vector inTriangleDirection( GetThirdEndpoint(lines[i])->node->getPosition() - onLine );
454 Vector inPointDirection(point - onLine);
455 if ((inTriangleDirection.NormSquared() > MYEPSILON) && (inPointDirection.NormSquared() > MYEPSILON))
456 if (inTriangleDirection.ScalarProduct(inPointDirection) < -MYEPSILON)
457 return false;
458 }
459
460 return true;
461}
462
463
464/** Returns the endpoint which is not contained in the given \a *line.
465 * \param *line baseline defining two endpoints
466 * \return pointer third endpoint or NULL if line does not belong to triangle.
467 */
468class BoundaryPointSet *BoundaryTriangleSet::GetThirdEndpoint(const BoundaryLineSet * const line) const
469{
470 //Info FunctionInfo(__func__);
471 // sanity check
472 if (!ContainsBoundaryLine(line))
473 return NULL;
474 for (int i = 0; i < 3; i++)
475 if (!line->ContainsBoundaryPoint(endpoints[i]))
476 return endpoints[i];
477 // actually, that' impossible :)
478 return NULL;
479}
480;
481
482/** Returns the baseline which does not contain the given boundary point \a *point.
483 * \param *point endpoint which is neither endpoint of the desired line
484 * \return pointer to desired third baseline
485 */
486class BoundaryLineSet *BoundaryTriangleSet::GetThirdLine(const BoundaryPointSet * const point) const
487{
488 //Info FunctionInfo(__func__);
489 // sanity check
490 if (!ContainsBoundaryPoint(point))
491 return NULL;
492 for (int i = 0; i < 3; i++)
493 if (!lines[i]->ContainsBoundaryPoint(point))
494 return lines[i];
495 // actually, that' impossible :)
496 return NULL;
497}
498;
499
500/** Calculates the center point of the triangle.
501 * Is third of the sum of all endpoints.
502 * \param *center central point on return.
503 */
504void BoundaryTriangleSet::GetCenter(Vector & center) const
505{
506 //Info FunctionInfo(__func__);
507 center.Zero();
508 for (int i = 0; i < 3; i++)
509 (center) += (endpoints[i]->node->getPosition());
510 center.Scale(1. / 3.);
511 LOG(4, "DEBUG: Center of BoundaryTriangleSet is at " << center << ".");
512}
513
514/**
515 * gets the Plane defined by the three triangle Basepoints
516 */
517Plane BoundaryTriangleSet::getPlane() const{
518 ASSERT(endpoints[0] && endpoints[1] && endpoints[2], "Triangle not fully defined");
519
520 return Plane(endpoints[0]->node->getPosition(),
521 endpoints[1]->node->getPosition(),
522 endpoints[2]->node->getPosition());
523}
524
525Vector BoundaryTriangleSet::getEndpoint(int i) const{
526 ASSERT(i>=0 && i<3,"Index of Endpoint out of Range");
527
528 return endpoints[i]->node->getPosition();
529}
530
531string BoundaryTriangleSet::getEndpointName(int i) const{
532 ASSERT(i>=0 && i<3,"Index of Endpoint out of Range");
533
534 return endpoints[i]->node->getName();
535}
536
537/** output operator for BoundaryTriangleSet.
538 * \param &ost output stream
539 * \param &a boundary triangle
540 */
541ostream &operator <<(ostream &ost, const BoundaryTriangleSet &a)
542{
543 ost << "[" << a.Nr << "|" << a.getEndpointName(0) << "," << a.getEndpointName(1) << "," << a.getEndpointName(2) << "]";
544 // ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << ","
545 // << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "," << a.endpoints[2]->node->Name << " at " << *a.endpoints[2]->node->node << "]";
546 return ost;
547}
548;
549
Note: See TracBrowser for help on using the repository browser.