/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * BoundaryPolygonSet.cpp * * Created on: Jul 29, 2010 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "BoundaryPolygonSet.hpp" #include #include "BoundaryLineSet.hpp" #include "BoundaryPointSet.hpp" #include "BoundaryTriangleSet.hpp" #include "TesselPoint.hpp" #include "CodePatterns/Assert.hpp" #include "CodePatterns/Info.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Verbose.hpp" #include "Helpers/helpers.hpp" #include "LinearAlgebra/Plane.hpp" #include "LinearAlgebra/Vector.hpp" using namespace std; /** Constructor for BoundaryPolygonSet. */ BoundaryPolygonSet::BoundaryPolygonSet() : Nr(-1) { Info FunctionInfo(__func__); } ; /** Destructor of BoundaryPolygonSet. * Just clears endpoints. * \note When removing triangles from a class Tesselation, use RemoveTesselationTriangle() */ BoundaryPolygonSet::~BoundaryPolygonSet() { Info FunctionInfo(__func__); endpoints.clear(); DoLog(1) && (Log() << Verbose(1) << "Erasing polygon Nr." << Nr << " itself." << endl); } ; /** Calculates the normal vector for this triangle. * Is made unique by comparison with \a OtherVector to point in the other direction. * \param &OtherVector direction vector to make normal vector unique. * \return allocated vector in normal direction */ Vector * BoundaryPolygonSet::GetNormalVector(const Vector &OtherVector) const { Info FunctionInfo(__func__); // get normal vector Vector TemporaryNormal; Vector *TotalNormal = new Vector; PointSet::const_iterator Runner[3]; for (int i = 0; i < 3; i++) { Runner[i] = endpoints.begin(); for (int j = 0; j < i; j++) { // go as much further Runner[i]++; if (Runner[i] == endpoints.end()) { DoeLog(0) && (eLog() << Verbose(0) << "There are less than three endpoints in the polygon!" << endl); performCriticalExit(); } } } TotalNormal->Zero(); int counter = 0; for (; Runner[2] != endpoints.end();) { TemporaryNormal = Plane(((*Runner[0])->node->getPosition()), ((*Runner[1])->node->getPosition()), ((*Runner[2])->node->getPosition())).getNormal(); for (int i = 0; i < 3; i++) // increase each of them Runner[i]++; (*TotalNormal) += TemporaryNormal; } TotalNormal->Scale(1. / (double) counter); // make it always point inward (any offset vector onto plane projected onto normal vector suffices) if (TotalNormal->ScalarProduct(OtherVector) > 0.) TotalNormal->Scale(-1.); DoLog(1) && (Log() << Verbose(1) << "Normal Vector is " << *TotalNormal << "." << endl); return TotalNormal; } ; /** Calculates the center point of the triangle. * Is third of the sum of all endpoints. * \param *center central point on return. */ void BoundaryPolygonSet::GetCenter(Vector * const center) const { Info FunctionInfo(__func__); center->Zero(); int counter = 0; for(PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) { (*center) += ((*Runner)->node->getPosition()); counter++; } center->Scale(1. / (double) counter); DoLog(1) && (Log() << Verbose(1) << "Center is at " << *center << "." << endl); } /** Checks whether the polygons contains all three endpoints of the triangle. * \param *triangle triangle to test * \return true - triangle is contained polygon, false - is not */ bool BoundaryPolygonSet::ContainsBoundaryTriangle(const BoundaryTriangleSet * const triangle) const { Info FunctionInfo(__func__); return ContainsPresentTupel(triangle->endpoints, 3); } ; /** Checks whether the polygons contains both endpoints of the line. * \param *line line to test * \return true - line is of the triangle, false - is not */ bool BoundaryPolygonSet::ContainsBoundaryLine(const BoundaryLineSet * const line) const { Info FunctionInfo(__func__); return ContainsPresentTupel(line->endpoints, 2); } ; /** Checks whether point is any of the three endpoints this triangle contains. * \param *point point to test * \return true - point is of the triangle, false - is not */ bool BoundaryPolygonSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const { Info FunctionInfo(__func__); for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) { DoLog(0) && (Log() << Verbose(0) << "Checking against " << **Runner << endl); if (point == (*Runner)) { DoLog(0) && (Log() << Verbose(0) << " Contained." << endl); return true; } } DoLog(0) && (Log() << Verbose(0) << " Not contained." << endl); return false; } ; /** Checks whether point is any of the three endpoints this triangle contains. * \param *point TesselPoint to test * \return true - point is of the triangle, false - is not */ bool BoundaryPolygonSet::ContainsBoundaryPoint(const TesselPoint * const point) const { Info FunctionInfo(__func__); for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) if (point == (*Runner)->node) { DoLog(0) && (Log() << Verbose(0) << " Contained." << endl); return true; } DoLog(0) && (Log() << Verbose(0) << " Not contained." << endl); return false; } ; /** Checks whether given array of \a *Points coincide with polygons's endpoints. * \param **Points pointer to an array of BoundaryPointSet * \param dim dimension of array * \return true - set of points is contained in polygon, false - is not */ bool BoundaryPolygonSet::ContainsPresentTupel(const BoundaryPointSet * const * Points, const int dim) const { Info FunctionInfo(__func__); int counter = 0; DoLog(1) && (Log() << Verbose(1) << "Polygon is " << *this << endl); for (int i = 0; i < dim; i++) { DoLog(1) && (Log() << Verbose(1) << " Testing endpoint " << *Points[i] << endl); if (ContainsBoundaryPoint(Points[i])) { counter++; } } if (counter == dim) return true; else return false; } ; /** Checks whether given PointList coincide with polygons's endpoints. * \param &endpoints PointList * \return true - set of points is contained in polygon, false - is not */ bool BoundaryPolygonSet::ContainsPresentTupel(const PointSet &endpoints) const { Info FunctionInfo(__func__); size_t counter = 0; DoLog(1) && (Log() << Verbose(1) << "Polygon is " << *this << endl); for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) { DoLog(1) && (Log() << Verbose(1) << " Testing endpoint " << **Runner << endl); if (ContainsBoundaryPoint(*Runner)) counter++; } if (counter == endpoints.size()) return true; else return false; } ; /** Checks whether given set of \a *Points coincide with polygons's endpoints. * \param *P pointer to BoundaryPolygonSet * \return true - is the very triangle, false - is not */ bool BoundaryPolygonSet::ContainsPresentTupel(const BoundaryPolygonSet * const P) const { return ContainsPresentTupel((const PointSet) P->endpoints); } ; /** Gathers all the endpoints' triangles in a unique set. * \return set of all triangles */ TriangleSet * BoundaryPolygonSet::GetAllContainedTrianglesFromEndpoints() const { Info FunctionInfo(__func__); pair Tester; TriangleSet *triangles = new TriangleSet; for (PointSet::const_iterator Runner = endpoints.begin(); Runner != endpoints.end(); Runner++) for (LineMap::const_iterator Walker = (*Runner)->lines.begin(); Walker != (*Runner)->lines.end(); Walker++) for (TriangleMap::const_iterator Sprinter = (Walker->second)->triangles.begin(); Sprinter != (Walker->second)->triangles.end(); Sprinter++) { //Log() << Verbose(0) << " Testing triangle " << *(Sprinter->second) << endl; if (ContainsBoundaryTriangle(Sprinter->second)) { Tester = triangles->insert(Sprinter->second); if (Tester.second) DoLog(0) && (Log() << Verbose(0) << "Adding triangle " << *(Sprinter->second) << endl); } } DoLog(1) && (Log() << Verbose(1) << "The Polygon of " << endpoints.size() << " endpoints has " << triangles->size() << " unique triangles in total." << endl); return triangles; } ; /** Fills the endpoints of this polygon from the triangles attached to \a *line. * \param *line lines with triangles attached * \return true - polygon contains endpoints, false - line was NULL */ bool BoundaryPolygonSet::FillPolygonFromTrianglesOfLine(const BoundaryLineSet * const line) { Info FunctionInfo(__func__); pair Tester; if (line == NULL) return false; DoLog(1) && (Log() << Verbose(1) << "Filling polygon from line " << *line << endl); for (TriangleMap::const_iterator Runner = line->triangles.begin(); Runner != line->triangles.end(); Runner++) { for (int i = 0; i < 3; i++) { Tester = endpoints.insert((Runner->second)->endpoints[i]); if (Tester.second) DoLog(1) && (Log() << Verbose(1) << " Inserting endpoint " << *((Runner->second)->endpoints[i]) << endl); } } return true; } ; /** output operator for BoundaryPolygonSet. * \param &ost output stream * \param &a boundary polygon */ ostream &operator <<(ostream &ost, const BoundaryPolygonSet &a) { ost << "[" << a.Nr << "|"; for (PointSet::const_iterator Runner = a.endpoints.begin(); Runner != a.endpoints.end();) { ost << (*Runner)->node->getName(); Runner++; if (Runner != a.endpoints.end()) ost << ","; } ost << "]"; return ost; } ;