Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/tesselation.cpp

    r27ac00 rb32dbb  
    1717#include "triangleintersectionlist.hpp"
    1818#include "vector.hpp"
    19 #include "Line.hpp"
    2019#include "vector_ops.hpp"
    2120#include "verbose.hpp"
     
    230229{
    231230  Info FunctionInfo(__func__);
     231  double angle = CalculateConvexity();
     232  if (angle > -MYEPSILON) {
     233    DoLog(0) && (Log() << Verbose(0) << "ACCEPT: Angle is greater than pi: convex." << endl);
     234    return true;
     235  } else {
     236    DoLog(0) && (Log() << Verbose(0) << "REJECT: Angle is less than pi: concave." << endl);
     237    return false;
     238  }
     239}
     240
     241
     242/** Calculates the angle between two triangles with respect to their normal vector.
     243 * We sum the two angles of each height vector with respect to the center of the baseline.
     244 * \return angle > 0 then convex, if < 0 then concave
     245 */
     246double BoundaryLineSet::CalculateConvexity() const
     247{
     248  Info FunctionInfo(__func__);
    232249  Vector BaseLineCenter, BaseLineNormal, BaseLine, helper[2], NormalCheck;
    233250  // get the two triangles
     
    278295  BaseLineNormal.Scale(-1.);
    279296  double angle = GetAngle(helper[0], helper[1], BaseLineNormal);
    280   if ((angle - M_PI) > -MYEPSILON) {
    281     DoLog(0) && (Log() << Verbose(0) << "ACCEPT: Angle is greater than pi: convex." << endl);
    282     return true;
    283   } else {
    284     DoLog(0) && (Log() << Verbose(0) << "REJECT: Angle is less than pi: concave." << endl);
    285     return false;
    286   }
     297  return (angle - M_PI);
    287298}
    288299
     
    303314/** Returns other endpoint of the line.
    304315 * \param *point other endpoint
    305  * \return NULL - if endpoint not contained in BoundaryLineSet, or pointer to BoundaryPointSet otherwise
     316 * \return NULL - if endpoint not contained in BoundaryLineSet::lines, or pointer to BoundaryPointSet otherwise
    306317 */
    307318class BoundaryPointSet *BoundaryLineSet::GetOtherEndpoint(const BoundaryPointSet * const point) const
     
    314325  else
    315326    return NULL;
     327}
     328;
     329
     330/** Returns other triangle of the line.
     331 * \param *point other endpoint
     332 * \return NULL - if triangle not contained in BoundaryLineSet::triangles, or pointer to BoundaryTriangleSet otherwise
     333 */
     334class BoundaryTriangleSet *BoundaryLineSet::GetOtherTriangle(const BoundaryTriangleSet * const triangle) const
     335{
     336  Info FunctionInfo(__func__);
     337  if (triangles.size() == 2) {
     338    for (TriangleMap::const_iterator TriangleRunner = triangles.begin(); TriangleRunner != triangles.end(); ++TriangleRunner)
     339      if (TriangleRunner->second != triangle)
     340        return TriangleRunner->second;
     341  }
     342  return NULL;
    316343}
    317344;
     
    442469
    443470  try {
    444     Line centerLine = makeLineThrough(*MolCenter, *x);
    445     *Intersection = Plane(NormalVector, *(endpoints[0]->node->node)).GetIntersection(centerLine);
    446 
    447     DoLog(1) && (Log() << Verbose(1) << "INFO: Triangle is " << *this << "." << endl);
    448     DoLog(1) && (Log() << Verbose(1) << "INFO: Line is from " << *MolCenter << " to " << *x << "." << endl);
    449     DoLog(1) && (Log() << Verbose(1) << "INFO: Intersection is " << *Intersection << "." << endl);
    450 
    451     if (Intersection->DistanceSquared(*endpoints[0]->node->node) < MYEPSILON) {
    452       DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with first endpoint." << endl);
    453       return true;
    454     }   else if (Intersection->DistanceSquared(*endpoints[1]->node->node) < MYEPSILON) {
    455       DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with second endpoint." << endl);
    456       return true;
    457     }   else if (Intersection->DistanceSquared(*endpoints[2]->node->node) < MYEPSILON) {
    458       DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with third endpoint." << endl);
    459       return true;
    460     }
    461     // Calculate cross point between one baseline and the line from the third endpoint to intersection
    462     int i = 0;
    463     do {
    464       Line line1 = makeLineThrough(*(endpoints[i%3]->node->node),*(endpoints[(i+1)%3]->node->node));
    465       Line line2 = makeLineThrough(*(endpoints[(i+2)%3]->node->node),*Intersection);
    466       CrossPoint = line1.getIntersection(line2);
     471    *Intersection = Plane(NormalVector, *(endpoints[0]->node->node)).GetIntersection(*MolCenter, *x);
     472  }
     473  catch (LinearDependenceException &excp) {
     474    Log() << Verbose(1) << excp;
     475    DoeLog(1) && (eLog() << Verbose(1) << "Alas! Intersection with plane failed - at least numerically - the intersection is not on the plane!" << endl);
     476    return false;
     477  }
     478
     479  DoLog(1) && (Log() << Verbose(1) << "INFO: Triangle is " << *this << "." << endl);
     480  DoLog(1) && (Log() << Verbose(1) << "INFO: Line is from " << *MolCenter << " to " << *x << "." << endl);
     481  DoLog(1) && (Log() << Verbose(1) << "INFO: Intersection is " << *Intersection << "." << endl);
     482
     483  if (Intersection->DistanceSquared(*endpoints[0]->node->node) < MYEPSILON) {
     484    DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with first endpoint." << endl);
     485    return true;
     486  }   else if (Intersection->DistanceSquared(*endpoints[1]->node->node) < MYEPSILON) {
     487    DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with second endpoint." << endl);
     488    return true;
     489  }   else if (Intersection->DistanceSquared(*endpoints[2]->node->node) < MYEPSILON) {
     490    DoLog(1) && (Log() << Verbose(1) << "Intersection coindices with third endpoint." << endl);
     491    return true;
     492  }
     493  // Calculate cross point between one baseline and the line from the third endpoint to intersection
     494  int i = 0;
     495  do {
     496    try {
     497      CrossPoint = GetIntersectionOfTwoLinesOnPlane(*(endpoints[i%3]->node->node),
     498                                                    *(endpoints[(i+1)%3]->node->node),
     499                                                    *(endpoints[(i+2)%3]->node->node),
     500                                                    *Intersection);
    467501      helper = (*endpoints[(i+1)%3]->node->node) - (*endpoints[i%3]->node->node);
    468502      CrossPoint -= (*endpoints[i%3]->node->node);  // cross point was returned as absolute vector
     
    471505      if ((s < -MYEPSILON) || ((s-1.) > MYEPSILON)) {
    472506        DoLog(1) && (Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << "outside of triangle." << endl);
    473         return false;
     507        i=4;
     508        break;
    474509      }
    475510      i++;
    476     } while (i < 3);
     511    } catch (LinearDependenceException &excp){
     512      break;
     513    }
     514  } while (i < 3);
     515  if (i == 3) {
    477516    DoLog(1) && (Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " inside of triangle." << endl);
    478517    return true;
    479   }
    480   catch (MathException &excp) {
    481     Log() << Verbose(1) << excp;
    482     DoeLog(1) && (eLog() << Verbose(1) << "Alas! Intersection with plane failed - at least numerically - the intersection is not on the plane!" << endl);
     518  } else {
     519    DoLog(1) && (Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " outside of triangle." << endl);
    483520    return false;
    484521  }
     
    507544  GetCenter(&Direction);
    508545  try {
    509     Line l = makeLineThrough(*x, Direction);
    510     *ClosestPoint = Plane(NormalVector, *(endpoints[0]->node->node)).GetIntersection(l);
    511   }
    512   catch (MathException &excp) {
     546    *ClosestPoint = Plane(NormalVector, *(endpoints[0]->node->node)).GetIntersection(*x, Direction);
     547  }
     548  catch (LinearDependenceException &excp) {
    513549    (*ClosestPoint) = (*x);
    514550  }
     
    533569    Direction = (*endpoints[(i+1)%3]->node->node) - (*endpoints[i%3]->node->node);
    534570    // calculate intersection, line can never be parallel to Direction (is the same vector as PlaneNormal);
    535     Line l = makeLineThrough(*(endpoints[i%3]->node->node), *(endpoints[(i+1)%3]->node->node));
    536     CrossPoint[i] = Plane(Direction, InPlane).GetIntersection(l);
     571    CrossPoint[i] = Plane(Direction, InPlane).GetIntersection(*(endpoints[i%3]->node->node), *(endpoints[(i+1)%3]->node->node));
    537572    CrossDirection[i] = CrossPoint[i] - InPlane;
    538573    CrossPoint[i] -= (*endpoints[i%3]->node->node);  // cross point was returned as absolute vector
     
    662697;
    663698
     699/** Returns the baseline which does not contain the given boundary point \a *point.
     700 * \param *point endpoint which is neither endpoint of the desired line
     701 * \return pointer to desired third baseline
     702 */
     703class BoundaryLineSet *BoundaryTriangleSet::GetThirdLine(const BoundaryPointSet * const point) const
     704{
     705  Info FunctionInfo(__func__);
     706  // sanity check
     707  if (!ContainsBoundaryPoint(point))
     708    return NULL;
     709  for (int i = 0; i < 3; i++)
     710    if (!lines[i]->ContainsBoundaryPoint(point))
     711      return lines[i];
     712  // actually, that' impossible :)
     713  return NULL;
     714}
     715;
     716
    664717/** Calculates the center point of the triangle.
    665718 * Is third of the sum of all endpoints.
     
    687740}
    688741
    689 Vector BoundaryTriangleSet::getEndpoint(int i) const{
    690   ASSERT(i>=0 && i<3,"Index of Endpoint out of Range");
    691 
    692   return *endpoints[i]->node->node;
    693 }
    694 
    695 string BoundaryTriangleSet::getEndpointName(int i) const{
    696   ASSERT(i>=0 && i<3,"Index of Endpoint out of Range");
    697 
    698   return endpoints[i]->node->getName();
    699 }
    700 
    701742/** output operator for BoundaryTriangleSet.
    702743 * \param &ost output stream
     
    705746ostream &operator <<(ostream &ost, const BoundaryTriangleSet &a)
    706747{
    707   ost << "[" << a.Nr << "|" << a.getEndpointName(0) << "," << a.getEndpointName(1) << "," << a.getEndpointName(2) << "]";
     748  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->getName() << "," << a.endpoints[1]->node->getName() << "," << a.endpoints[2]->node->getName() << "]";
    708749  //  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << ","
    709750  //      << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "," << a.endpoints[2]->node->Name << " at " << *a.endpoints[2]->node->node << "]";
     
    11111152    TesselPointList *ListofPoints = LC->GetPointsInsideSphere(RADIUS, (*VRunner));
    11121153
    1113     DoLog(1) && (Log() << Verbose(1) << "The following atoms are inside sphere at " << OtherOptCenter << ":" << endl);
     1154    DoLog(1) && (Log() << Verbose(1) << "The following atoms are inside sphere at " << (*VRunner) << ":" << endl);
    11141155    for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
    1115       DoLog(1) && (Log() << Verbose(1) << "  " << *(*Runner) << " with distance " << (*Runner)->node->distance(OtherOptCenter) << "." << endl);
     1156      DoLog(1) && (Log() << Verbose(1) << "  " << *(*Runner) << " with distance " << (*Runner)->node->distance(*(*VRunner)) << "." << endl);
    11161157
    11171158    // remove baseline's endpoints and candidates
     
    11291170      DoeLog(1) && (eLog() << Verbose(1) << "External atoms inside of sphere at " << *(*VRunner) << ":" << endl);
    11301171      for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
    1131         DoeLog(1) && (eLog() << Verbose(1) << "  " << *(*Runner) << endl);
     1172        DoeLog(1) && (eLog() << Verbose(1) << "  " << *(*Runner) << " at distance " << setprecision(13) << (*Runner)->node->distance(*(*VRunner)) << setprecision(6) << "." << endl);
     1173
     1174      // check with animate_sphere.tcl VMD script
     1175      if (ThirdPoint != NULL) {
     1176        DoeLog(1) && (eLog() << Verbose(1) << "Check by: animate_sphere 0 " << BaseLine->endpoints[0]->Nr + 1 << " " << BaseLine->endpoints[1]->Nr + 1 << " " << ThirdPoint->Nr + 1 << " " << RADIUS << " " << OldCenter[0] << " " << OldCenter[1] << " " << OldCenter[2] << " " << (*VRunner)->at(0) << " " << (*VRunner)->at(1) << " " << (*VRunner)->at(2) << endl);
     1177      } else {
     1178        DoeLog(1) && (eLog() << Verbose(1) << "Check by: ... missing third point ..." << endl);
     1179        DoeLog(1) && (eLog() << Verbose(1) << "Check by: animate_sphere 0 " << BaseLine->endpoints[0]->Nr + 1 << " " << BaseLine->endpoints[1]->Nr + 1 << " ??? " << RADIUS << " " << OldCenter[0] << " " << OldCenter[1] << " " << OldCenter[2] << " " << (*VRunner)->at(0) << " " << (*VRunner)->at(1) << " " << (*VRunner)->at(2) << endl);
     1180      }
    11321181    }
    11331182    delete (ListofPoints);
    11341183
    1135     // check with animate_sphere.tcl VMD script
    1136     if (ThirdPoint != NULL) {
    1137       DoLog(1) && (Log() << Verbose(1) << "Check by: animate_sphere 0 " << BaseLine->endpoints[0]->Nr + 1 << " " << BaseLine->endpoints[1]->Nr + 1 << " " << ThirdPoint->Nr + 1 << " " << RADIUS << " " << OldCenter[0] << " " << OldCenter[1] << " " << OldCenter[2] << " " << (*VRunner)->at(0) << " " << (*VRunner)->at(1) << " " << (*VRunner)->at(2) << endl);
    1138     } else {
    1139       DoLog(1) && (Log() << Verbose(1) << "Check by: ... missing third point ..." << endl);
    1140       DoLog(1) && (Log() << Verbose(1) << "Check by: animate_sphere 0 " << BaseLine->endpoints[0]->Nr + 1 << " " << BaseLine->endpoints[1]->Nr + 1 << " ??? " << RADIUS << " " << OldCenter[0] << " " << OldCenter[1] << " " << OldCenter[2] << " " << (*VRunner)->at(0) << " " << (*VRunner)->at(1) << " " << (*VRunner)->at(2) << endl);
    1141     }
    11421184  }
    11431185  return flag;
     
    14721514        CenterVector.Zero();
    14731515        for (int i = 0; i < 3; i++)
    1474           CenterVector += BTS->getEndpoint(i);
     1516          CenterVector += (*BTS->endpoints[i]->node->node);
    14751517        CenterVector.Scale(1. / 3.);
    14761518        DoLog(2) && (Log() << Verbose(2) << "CenterVector of base triangle is " << CenterVector << endl);
     
    33183360                        }
    33193361                      } else {
    3320                         DoLog(1) && (Log() << Verbose(1) << "REJECT: Distance to center of circumcircle is not the same from each corner of the triangle: " << fabs(radius - otherradius) << endl);
     3362                        DoeLog(0) && (eLog() << Verbose(1) << "REJECT: Distance to center of circumcircle is not the same from each corner of the triangle: " << fabs(radius - otherradius) << endl);
    33213363                      }
    33223364                    } else {
     
    46184660
    46194661  DoLog(0) && (Log() << Verbose(0) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl);
    4620   IndexToIndex::iterator it;
    4621   for (it = DegeneratedTriangles->begin(); it != DegeneratedTriangles->end(); it++)
     4662  for (IndexToIndex::iterator it = DegeneratedTriangles->begin(); it != DegeneratedTriangles->end(); it++)
    46224663    DoLog(0) && (Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl);
    46234664
     
    46374678  int count = 0;
    46384679
    4639   for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); TriangleKeyRunner != DegeneratedTriangles->end(); ++TriangleKeyRunner) {
     4680  // iterate over all degenerated triangles
     4681  for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); !DegeneratedTriangles->empty(); TriangleKeyRunner = DegeneratedTriangles->begin()) {
     4682    DoLog(0) && (Log() << Verbose(0) << "Checking presence of triangles " << TriangleKeyRunner->first << " and " << TriangleKeyRunner->second << "." << endl);
     4683    // both ways are stored in the map, only use one
     4684    if (TriangleKeyRunner->first > TriangleKeyRunner->second)
     4685      continue;
     4686
     4687    // determine from the keys in the map the two _present_ triangles
    46404688    finder = TrianglesOnBoundary.find(TriangleKeyRunner->first);
    46414689    if (finder != TrianglesOnBoundary.end())
    46424690      triangle = finder->second;
    46434691    else
    4644       break;
     4692      continue;
    46454693    finder = TrianglesOnBoundary.find(TriangleKeyRunner->second);
    46464694    if (finder != TrianglesOnBoundary.end())
    46474695      partnerTriangle = finder->second;
    46484696    else
    4649       break;
    4650 
     4697      continue;
     4698
     4699    // determine which lines are shared by the two triangles
    46514700    bool trianglesShareLine = false;
    46524701    for (int i = 0; i < 3; ++i)
     
    48194868  if (LastTriangle != NULL) {
    48204869    stringstream sstr;
    4821     sstr << "-"<< TrianglesOnBoundary.size() << "-" << LastTriangle->getEndpointName(0) << "_" << LastTriangle->getEndpointName(1) << "_" << LastTriangle->getEndpointName(2);
     4870    sstr << "-"<< TrianglesOnBoundary.size() << "-" << LastTriangle->endpoints[0]->node->getName() << "_" << LastTriangle->endpoints[1]->node->getName() << "_" << LastTriangle->endpoints[2]->node->getName();
    48224871    NumberName = sstr.str();
    48234872    if (DoTecplotOutput) {
Note: See TracChangeset for help on using the changeset viewer.