/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010-2012 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * triangleintersectionlist.cpp * * This files encapsulates the TriangleIntersectionList class where all matters related to points in space being how close to * a tesselated surface are answered, i.e. distance, is inside, ... * * Created on: Mar 1, 2010 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include "triangleintersectionlist.hpp" #include "tesselation.hpp" #include "BoundaryMaps.hpp" #include "BoundaryPointSet.hpp" #include "BoundaryLineSet.hpp" #include "BoundaryTriangleSet.hpp" #include "CodePatterns/Info.hpp" #include "CodePatterns/Log.hpp" #include "CodePatterns/Verbose.hpp" #include "Helpers/defs.hpp" #include "LinearAlgebra/Vector.hpp" /** Constructor for class TriangleIntersectionList. * */ TriangleIntersectionList::TriangleIntersectionList(const Vector &x, const Tesselation *surface, const LinkedCell_deprecated* LC) : Point(x), Tess(surface), Vicinity(LC) { Info FunctionInfo(__func__); GatherIntersectionsWithTriangles(); }; /** Destructor for class TriangleIntersectionList. * Free's all allocated intersection vectors */ TriangleIntersectionList::~TriangleIntersectionList() { Info FunctionInfo(__func__); for (TriangleVectorMap::iterator Runner = IntersectionList.begin(); Runner != IntersectionList.end(); Runner++) delete((*Runner).second); }; /** Returns the smallest distance between TriangleIntersectionList::Point and the surface given by * TriangleIntersectionList::Tess. * \return distance >=0, -1 if no specific distance could be found */ double TriangleIntersectionList::GetSmallestDistance() const { Info FunctionInfo(__func__); FillDistanceList(); if (!DistanceList.empty()) return DistanceList.begin()->first; else // return reference, if none can be found return -1.; }; /** Returns the vector of closest intersection between TriangleIntersectionList::Point and the surface * TriangleIntersectionList::Tess. * \return Intersection vector or TriangleIntersectionList::Point if none could be found */ Vector TriangleIntersectionList::GetClosestIntersection() const { Info FunctionInfo(__func__); TriangleVectorMap::const_iterator runner; runner = GetIteratortoSmallestDistance(); if (runner != IntersectionList.end()) { return *((*runner).second); } // return reference, if none can be found return Point; }; /** Returns the triangle closest to TriangleIntersectionList::Point and the surface * TriangleIntersectionList::Tess. * \return pointer to triangle or NULL if none could be found */ BoundaryTriangleSet * TriangleIntersectionList::GetClosestTriangle() const { Info FunctionInfo(__func__); TriangleVectorMap::const_iterator runner; runner = GetIteratortoSmallestDistance(); if (runner != IntersectionList.end()) { return ((*runner).first); } // return reference, if none can be found return NULL; }; /** Checks whether reference TriangleIntersectionList::Point of this class is inside or outside. * \return true - TriangleIntersectionList::Point is inside, false - is outside */ bool TriangleIntersectionList::IsInside() const { Info FunctionInfo(__func__); TriangleVectorMap::const_iterator runner; runner = GetIteratortoSmallestDistance(); if (runner != IntersectionList.end()) { // if we have found one, check Scalarproduct between the vector Vector TestVector = (Point) - (*(*runner).second); if (fabs(TestVector.NormSquared()) < MYEPSILON) // return true; const double sign = (*runner).first->NormalVector.ScalarProduct(TestVector); if (sign < 0) { return true; } else { return false; } } // so far away from surface that there are no triangles in list return false; }; /** Puts all triangles in vicinity (by \a *LC) into a hash map with Intersection vectors. * Private function for constructor of TriangleIntersectionList. */ void TriangleIntersectionList::GatherIntersectionsWithTriangles() { Info FunctionInfo(__func__); // get closest points boost::scoped_ptr< DistanceToPointMap > points(Tess->FindClosestBoundaryPointsToVector(Point,Vicinity)); if (points == NULL) { ELOG(1, "There is no nearest point: too far away from the surface."); return; } // gather all triangles in *LC-neighbourhood TriangleSet triangles; for (DistanceToPointMap::iterator Runner = points->begin(); Runner != points->end(); Runner++) for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) for (TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++) triangles.insert(TriangleRunner->second); Vector *Intersection = NULL; for (TriangleSet::const_iterator TriangleRunner = triangles.begin(); TriangleRunner != triangles.end(); TriangleRunner++) { // get intersection with triangle plane Intersection = new Vector; (*TriangleRunner)->GetClosestPointInsideTriangle(Point, *Intersection); //LOG(1, "Intersection between " << Point << " and " << **TriangleRunner << " is at " << *Intersection << "."); IntersectionList.insert( pair (*TriangleRunner, Intersection) ); } }; /** Fills the private distance list */ void TriangleIntersectionList::FillDistanceList() const { Info FunctionInfo(__func__); if (DistanceList.empty()) for (TriangleVectorMap::const_iterator runner = IntersectionList.begin(); runner != IntersectionList.end(); runner++) DistanceList.insert( pair (Point.distance(*(*runner).second), (*runner).first) ); //for (DistanceTriangleMap::const_iterator runner = DistanceList.begin(); runner != DistanceList.end(); runner++) // LOG(1, (*runner).first << " away from " << *(*runner).second); }; /** Returns the iterator in VectorTriangleMap to the smallest distance. * This is a private helper function as the iterator is then evaluated in some other functions. * \return iterator or TriangleIntersectionList::IntersectionList.end() if none could be found */ TriangleVectorMap::const_iterator TriangleIntersectionList::GetIteratortoSmallestDistance() const { Info FunctionInfo(__func__); FillDistanceList(); // do we have any intersections? TriangleVectorMap::const_iterator runner; if (!DistanceList.empty()) { // get closest triangle runner = IntersectionList.find(DistanceList.begin()->second); } return runner; };