Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/tesselation.cpp

    rf66195 r29812d  
    66 */
    77
    8 #include <fstream>
    9 
    10 #include "linkedcell.hpp"
    118#include "tesselation.hpp"
    12 #include "tesselationhelpers.hpp"
    13 #include "vector.hpp"
    14 #include "verbose.hpp"
    15 
    16 class molecule;
     9#include "memoryallocator.hpp"
    1710
    1811// ======================================== Points on Boundary =================================
     
    4437BoundaryPointSet::~BoundaryPointSet()
    4538{
    46   //cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
     39  cout << Verbose(5) << "Erasing point nr. " << Nr << "." << endl;
    4740  if (!lines.empty())
    4841    cerr << "WARNING: Memory Leak! I " << *this << " am still connected to some lines." << endl;
     
    7467ostream & operator <<(ostream &ost, BoundaryPointSet &a)
    7568{
    76   ost << "[" << a.Nr << "|" << a.node->Name << " at " << *a.node->node << "]";
     69  ost << "[" << a.Nr << "|" << a.node->Name << "]";
    7770  return ost;
    7871}
     
    132125        for (LineMap::iterator Runner = erasor.first; Runner != erasor.second; Runner++)
    133126          if ((*Runner).second == this) {
    134             //cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
     127            cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
    135128            endpoints[i]->lines.erase(Runner);
    136129            break;
    137130          }
    138131      } else { // there's just a single line left
    139         if (endpoints[i]->lines.erase(Nr)) {
    140           //cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
    141         }
     132        if (endpoints[i]->lines.erase(Nr))
     133          cout << Verbose(5) << "Removing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
    142134      }
    143135      if (endpoints[i]->lines.empty()) {
    144         //cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;
     136        cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;
    145137        if (endpoints[i] != NULL) {
    146138          delete(endpoints[i]);
     
    176168
    177169/** Checks whether the adjacent triangles of a baseline are convex or not.
    178  * We sum the two angles of each height vector with respect to the center of the baseline.
     170 * We sum the two angles of each normal vector with a ficticious normnal vector from this baselinbe pointing outwards.
    179171 * If greater/equal M_PI than we are convex.
    180172 * \param *out output stream for debugging
     
    186178  // get the two triangles
    187179  if (triangles.size() != 2) {
    188     *out << Verbose(1) << "ERROR: Baseline " << *this << " is connected to less than two triangles, Tesselation incomplete!" << endl;
     180    *out << Verbose(1) << "ERROR: Baseline " << *this << " is connect to less than two triangles, Tesselation incomplete!" << endl;
    189181    return true;
    190182  }
     
    209201    NormalCheck.Scale(sign);
    210202    sign = -sign;
    211     if (runner->second->NormalVector.NormSquared() > MYEPSILON)
    212       BaseLineNormal.CopyVector(&runner->second->NormalVector);   // yes, copy second on top of first
    213     else {
    214       *out << Verbose(1) << "CRITICAL: Triangle " << *runner->second << " has zero normal vector!" << endl;
    215       exit(255);
    216     }
     203    BaseLineNormal.SubtractVector(&runner->second->NormalVector);   // we subtract as BaseLineNormal has to point inward in direction of [pi,2pi]
    217204    node = runner->second->GetThirdEndpoint(this);
    218205    if (node != NULL) {
     
    224211      i++;
    225212    } else {
    226       //*out << Verbose(2) << "ERROR: I cannot find third node in triangle, something's wrong." << endl;
     213      //*out << Verbose(2) << "WARNING: I cannot find third node in triangle, something's wrong." << endl;
    227214      return true;
    228215    }
     
    230217  //*out << Verbose(3) << "INFO: BaselineNormal is " << BaseLineNormal << "." << endl;
    231218  if (NormalCheck.NormSquared() < MYEPSILON) {
    232     *out << Verbose(3) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl;
     219    *out << Verbose(2) << "ACCEPT: Normalvectors of both triangles are the same: convex." << endl;
    233220    return true;
    234221  }
    235   BaseLineNormal.Scale(-1.);
    236222  double angle = GetAngle(helper[0], helper[1], BaseLineNormal);
    237223  if ((angle - M_PI) > -MYEPSILON) {
    238     *out << Verbose(3) << "ACCEPT: Angle is greater than pi: convex." << endl;
     224    *out << Verbose(2) << "ACCEPT: Angle is greater than pi: convex." << endl;
    239225    return true;
    240226  } else {
    241     *out << Verbose(3) << "REJECT: Angle is less than pi: concave." << endl;
     227    *out << Verbose(2) << "REJECT: Angle is less than pi: concave." << endl;
    242228    return false;
    243229  }
     
    276262ostream & operator <<(ostream &ost, BoundaryLineSet &a)
    277263{
    278   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << "," << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "]";
     264  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "]";
    279265  return ost;
    280266};
     
    346332  for (int i = 0; i < 3; i++) {
    347333    if (lines[i] != NULL) {
    348       if (lines[i]->triangles.erase(Nr)) {
    349         //cout << Verbose(5) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl;
    350       }
     334      if (lines[i]->triangles.erase(Nr))
     335        cout << Verbose(5) << "Triangle Nr." << Nr << " erased in line " << *lines[i] << "." << endl;
    351336      if (lines[i]->triangles.empty()) {
    352           //cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;
     337          cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;
    353338          delete (lines[i]);
    354339          lines[i] = NULL;
     
    356341    }
    357342  }
    358   //cout << Verbose(5) << "Erasing triangle Nr." << Nr << " itself." << endl;
     343  cout << Verbose(5) << "Erasing triangle Nr." << Nr << " itself." << endl;
    359344};
    360345
     
    376361 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane
    377362 * This we test if it's really on the plane and whether it's inside the triangle on the plane or not.
    378  * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line
    379  * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between
    380  * the first two basepoints) or not.
     363 * The latter is done as follows: if it's really outside, then for any endpoint of the triangle and it's opposite
     364 * base line, the intersection between the line from endpoint to intersection and the base line will have a Vector::NormSquared()
     365 * smaller than the first line.
    381366 * \param *out output stream for debugging
    382367 * \param *MolCenter offset vector of line
     
    410395    exit(255);
    411396  }
    412   CrossPoint.SubtractVector(endpoints[i%3]->node->node);  // cross point was returned as absolute vector
     397  CrossPoint.SubtractVector(endpoints[i%3]->node->node);
    413398
    414399  // check whether intersection is inside or not by comparing length of intersection and length of cross point
    415   if ((CrossPoint.NormSquared() - helper.NormSquared()) < MYEPSILON) { // inside
     400  if ((CrossPoint.NormSquared() - helper.NormSquared()) > -MYEPSILON) { // inside
    416401    return true;
    417402  } else { // outside!
     
    441426  for(int i=0;i<3;i++)
    442427    if (point == endpoints[i])
    443       return true;
    444   return false;
    445 };
    446 
    447 /** Checks whether point is any of the three endpoints this triangle contains.
    448  * \param *point TesselPoint to test
    449  * \return true - point is of the triangle, false - is not
    450  */
    451 bool BoundaryTriangleSet::ContainsBoundaryPoint(class TesselPoint *point)
    452 {
    453   for(int i=0;i<3;i++)
    454     if (point == endpoints[i]->node)
    455428      return true;
    456429  return false;
     
    478451};
    479452
    480 /** Checks whether three given \a *Points coincide with triangle's endpoints.
    481  * \param *Points[3] pointer to BoundaryPointSet
    482  * \return true - is the very triangle, false - is not
    483  */
    484 bool BoundaryTriangleSet::IsPresentTupel(class BoundaryTriangleSet *T)
    485 {
    486   return (((endpoints[0] == T->endpoints[0])
    487             || (endpoints[0] == T->endpoints[1])
    488             || (endpoints[0] == T->endpoints[2])
    489           ) && (
    490             (endpoints[1] == T->endpoints[0])
    491             || (endpoints[1] == T->endpoints[1])
    492             || (endpoints[1] == T->endpoints[2])
    493           ) && (
    494             (endpoints[2] == T->endpoints[0])
    495             || (endpoints[2] == T->endpoints[1])
    496             || (endpoints[2] == T->endpoints[2])
    497 
    498           ));
    499 };
    500 
    501453/** Returns the endpoint which is not contained in the given \a *line.
    502454 * \param *line baseline defining two endpoints
     
    533485ostream &operator <<(ostream &ost, BoundaryTriangleSet &a)
    534486{
    535   ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << " at " << *a.endpoints[0]->node->node << ","
    536       << a.endpoints[1]->node->Name << " at " << *a.endpoints[1]->node->node << "," << a.endpoints[2]->node->Name << " at " << *a.endpoints[2]->node->node << "]";
     487  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << ","
     488      << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name << "]";
    537489  return ost;
    538490};
     
    553505TesselPoint::~TesselPoint()
    554506{
     507  Free(&Name);
    555508};
    556509
     
    559512ostream & operator << (ostream &ost, const TesselPoint &a)
    560513{
    561   ost << "[" << (a.Name) << "|" << a.Name << " at " << *a.node << "]";
     514  ost << "[" << (a.Name) << "|" << &a << "]";
    562515  return ost;
    563516};
     
    616569  TrianglesOnBoundaryCount = 0;
    617570  InternalPointer = PointsOnBoundary.begin();
    618   LastTriangle = NULL;
    619   TriangleFilesWritten = 0;
    620571}
    621572;
     
    634585      cerr << "ERROR: The triangle " << runner->first << " has already been free'd." << endl;
    635586  }
    636   cout << "This envelope was written to file " << TriangleFilesWritten << " times(s)." << endl;
    637587}
    638588;
     
    11021052  Vector *Center = cloud->GetCenter(out);
    11031053  list<BoundaryTriangleSet*> *triangles = NULL;
    1104   bool AddFlag = false;
    1105   LinkedCell *BoundaryPoints = NULL;
    11061054
    11071055  *out << Verbose(1) << "Begin of InsertStraddlingPoints" << endl;
    11081056
    11091057  cloud->GoToFirst();
    1110   BoundaryPoints = new LinkedCell(this, 5.);
    11111058  while (!cloud->IsEnd()) {  // we only have to go once through all points, as boundary can become only bigger
    1112     if (AddFlag) {
    1113       delete(BoundaryPoints);
    1114       BoundaryPoints = new LinkedCell(this, 5.);
    1115       AddFlag = false;
    1116     }
     1059    LinkedCell BoundaryPoints(this, 5.);
    11171060    Walker = cloud->GetPoint();
    11181061    *out << Verbose(2) << "Current point is " << *Walker << "." << endl;
    11191062    // get the next triangle
    1120     triangles = FindClosestTrianglesToPoint(out, Walker->node, BoundaryPoints);
    1121     BTS = triangles->front();
    1122     if ((triangles == NULL) || (BTS->ContainsBoundaryPoint(Walker))) {
    1123       *out << Verbose(2) << "No triangles found, probably a tesselation point itself." << endl;
     1063    triangles = FindClosestTrianglesToPoint(out, Walker->node, &BoundaryPoints);
     1064    if (triangles == NULL) {
     1065      *out << Verbose(1) << "No triangles found, probably a tesselation point itself." << endl;
    11241066      cloud->GoToNext();
    11251067      continue;
    11261068    } else {
     1069      BTS = triangles->front();
    11271070    }
    11281071    *out << Verbose(2) << "Closest triangle is " << *BTS << "." << endl;
     
    11471090        // add Walker to boundary points
    11481091        *out << Verbose(2) << "Adding " << *Walker << " to BoundaryPoints." << endl;
    1149         AddFlag = true;
    11501092        if (AddBoundaryPoint(Walker,0))
    11511093          NewPoint = BPS[0];
     
    12381180  } else {
    12391181    delete TPS[n];
    1240     cout << Verbose(4) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl;
     1182    cout << Verbose(3) << "Node " << *((InsertUnique.first)->second->node) << " is already present in PointsOnBoundary." << endl;
    12411183    TPS[n] = (InsertUnique.first)->second;
    12421184  }
     
    12551197
    12561198  if (a->lines.find(b->node->nr) != a->lines.end()) {
    1257     LineMap::iterator FindLine = a->lines.find(b->node->nr);
     1199    LineMap::iterator FindLine;
    12581200    pair<LineMap::iterator,LineMap::iterator> FindPair;
    12591201    FindPair = a->lines.equal_range(b->node->nr);
    1260     cout << Verbose(5) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl;
    1261 
    1262     for (FindLine = FindPair.first; FindLine != FindPair.second; FindLine++) {
     1202
     1203    for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) {
    12631204      // If there is a line with less than two attached triangles, we don't need a new line.
    12641205      if (FindLine->second->triangles.size() < 2) {
    12651206        insertNewLine = false;
    1266         cout << Verbose(4) << "Using existing line " << *FindLine->second << endl;
     1207        cout << Verbose(3) << "Using existing line " << *FindLine->second << endl;
    12671208
    12681209        BPS[0] = FindLine->second->endpoints[0];
     
    12911232void Tesselation::AlwaysAddTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, int n)
    12921233{
    1293   cout << Verbose(4) << "Adding line [" << LinesOnBoundaryCount << "|" << *(a->node) << " and " << *(b->node) << "." << endl;
     1234  cout << Verbose(3) << "Adding line between " << *(a->node) << " and " << *(b->node) << "." << endl;
    12941235  BPS[0] = a;
    12951236  BPS[1] = b;
     
    13011242};
    13021243
    1303 /** Function adds triangle to global list.
    1304  * Furthermore, the triangle receives the next free id and id counter \a TrianglesOnBoundaryCount is increased.
     1244/** Function tries to add Triangle just created to Triangle and remarks if already existent (Failure of algorithm).
     1245 * Furthermore it adds the triangle to all of its lines, in order to recognize those which are saturated later.
    13051246 */
    13061247void Tesselation::AddTesselationTriangle()
     
    13111252  TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS));
    13121253  TrianglesOnBoundaryCount++;
    1313 
    1314   // set as last new triangle
    1315   LastTriangle = BTS;
    1316 
    1317   // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet
    1318 };
    1319 
    1320 /** Function adds triangle to global list.
    1321  * Furthermore, the triangle number is set to \a nr.
    1322  * \param nr triangle number
    1323  */
    1324 void Tesselation::AddTesselationTriangle(int nr)
    1325 {
    1326   cout << Verbose(1) << "Adding triangle to global TrianglesOnBoundary map." << endl;
    1327 
    1328   // add triangle to global map
    1329   TrianglesOnBoundary.insert(TrianglePair(nr, BTS));
    1330 
    1331   // set as last new triangle
    1332   LastTriangle = BTS;
    13331254
    13341255  // NOTE: add triangle to local maps is done in constructor of BoundaryTriangleSet
     
    13511272          cout << Verbose(5) << *triangle->lines[i] << " is no more attached to any triangle, erasing." << endl;
    13521273          RemoveTesselationLine(triangle->lines[i]);
    1353       } else {
    1354         cout << Verbose(5) << *triangle->lines[i] << " is still attached to another triangle: ";
    1355         for(TriangleMap::iterator TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); TriangleRunner++)
    1356           cout << "[" << (TriangleRunner->second)->Nr << "|" << *((TriangleRunner->second)->endpoints[0]) << ", " << *((TriangleRunner->second)->endpoints[1]) << ", " << *((TriangleRunner->second)->endpoints[2]) << "] \t";
    1357         cout << endl;
    1358 //        for (int j=0;j<2;j++) {
    1359 //          cout << Verbose(5) << "Lines of endpoint " << *(triangle->lines[i]->endpoints[j]) << ": ";
    1360 //          for(LineMap::iterator LineRunner = triangle->lines[i]->endpoints[j]->lines.begin(); LineRunner != triangle->lines[i]->endpoints[j]->lines.end(); LineRunner++)
    1361 //            cout << "[" << *(LineRunner->second) << "] \t";
    1362 //          cout << endl;
    1363 //        }
    1364       }
    1365       triangle->lines[i] = NULL;  // free'd or not: disconnect
     1274          triangle->lines[i] = NULL;
     1275      } else
     1276        cout << Verbose(5) << *triangle->lines[i] << " is still attached to another triangle." << endl;
    13661277    } else
    13671278      cerr << "ERROR: This line " << i << " has already been free'd." << endl;
     
    13831294  if (line == NULL)
    13841295    return;
    1385   // get other endpoint number for finding copies of same line
     1296  // get other endpoint number of finding copies of same line
    13861297  if (line->endpoints[1] != NULL)
    13871298    Numbers[0] = line->endpoints[1]->Nr;
     
    14101321        cout << Verbose(5) << *line->endpoints[i] << " has no more lines it's attached to, erasing." << endl;
    14111322        RemoveTesselationPoint(line->endpoints[i]);
    1412       } else {
    1413         cout << Verbose(5) << *line->endpoints[i] << " has still lines it's attached to: ";
    1414         for(LineMap::iterator LineRunner = line->endpoints[i]->lines.begin(); LineRunner != line->endpoints[i]->lines.end(); LineRunner++)
    1415           cout << "[" << *(LineRunner->second) << "] \t";
    1416         cout << endl;
    1417       }
    1418       line->endpoints[i] = NULL;  // free'd or not: disconnect
     1323        line->endpoints[i] = NULL;
     1324      } else
     1325        cout << Verbose(5) << *line->endpoints[i] << " has still lines it's attached to." << endl;
    14191326    } else
    14201327      cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl;
     
    14831390          }
    14841391          // Only one of the triangle lines must be considered for the triangle count.
    1485           //*out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;
    1486           //return adjacentTriangleCount;
     1392          *out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;
     1393          return adjacentTriangleCount;
    14871394        }
    14881395      }
     
    14931400  *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;
    14941401  return adjacentTriangleCount;
    1495 };
    1496 
    1497 /** Checks whether the triangle consisting of the three points is already present.
    1498  * Searches for the points in Tesselation::PointsOnBoundary and checks their
    1499  * lines. If any of the three edges already has two triangles attached, false is
    1500  * returned.
    1501  * \param *out output stream for debugging
    1502  * \param *Candidates endpoints of the triangle candidate
    1503  * \return NULL - none found or pointer to triangle
    1504  */
    1505 class BoundaryTriangleSet * Tesselation::GetPresentTriangle(ofstream *out, TesselPoint *Candidates[3])
    1506 {
    1507   class BoundaryTriangleSet *triangle = NULL;
    1508   class BoundaryPointSet *Points[3];
    1509 
    1510   // builds a triangle point set (Points) of the end points
    1511   for (int i = 0; i < 3; i++) {
    1512     PointMap::iterator FindPoint = PointsOnBoundary.find(Candidates[i]->nr);
    1513     if (FindPoint != PointsOnBoundary.end()) {
    1514       Points[i] = FindPoint->second;
    1515     } else {
    1516       Points[i] = NULL;
    1517     }
    1518   }
    1519 
    1520   // checks lines between the points in the Points for their adjacent triangles
    1521   for (int i = 0; i < 3; i++) {
    1522     if (Points[i] != NULL) {
    1523       for (int j = i; j < 3; j++) {
    1524         if (Points[j] != NULL) {
    1525           LineMap::iterator FindLine = Points[i]->lines.find(Points[j]->node->nr);
    1526           for (; (FindLine != Points[i]->lines.end()) && (FindLine->first == Points[j]->node->nr); FindLine++) {
    1527             TriangleMap *triangles = &FindLine->second->triangles;
    1528             for (TriangleMap::iterator FindTriangle = triangles->begin(); FindTriangle != triangles->end(); FindTriangle++) {
    1529               if (FindTriangle->second->IsPresentTupel(Points)) {
    1530                 if ((triangle == NULL) || (triangle->Nr > FindTriangle->second->Nr))
    1531                   triangle = FindTriangle->second;
    1532               }
    1533             }
    1534           }
    1535           // Only one of the triangle lines must be considered for the triangle count.
    1536           //*out << Verbose(2) << "Found " << adjacentTriangleCount << " adjacent triangles for the point set." << endl;
    1537           //return adjacentTriangleCount;
    1538         }
    1539       }
    1540     }
    1541   }
    1542 
    1543   return triangle;
    15441402};
    15451403
     
    16031461  CandidateList *OptCandidates = new CandidateList();
    16041462  for (int k=0;k<NDIM;k++) {
    1605     Oben.Zero();
    16061463    Oben.x[k] = 1.;
    16071464    FirstPoint = MaxPoint[k];
     
    16121469    ShortestAngle = 999999.; // This will contain the angle, which will be always positive (when looking for second point), when looking for third point this will be the quadrant.
    16131470
    1614     FindSecondPointForTesselation(FirstPoint, Oben, OptCandidate, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...
     1471    FindSecondPointForTesselation(FirstPoint, NULL, Oben, OptCandidate, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...
    16151472    SecondPoint = OptCandidate;
    16161473    if (SecondPoint == NULL)  // have we found a second point?
    16171474      continue;
     1475    else
     1476      cout << Verbose(1) << "Found second point is at " << *SecondPoint->node << ".\n";
    16181477
    16191478    helper.CopyVector(FirstPoint->node);
     
    16371496
    16381497    // adding point 1 and point 2 and add the line between them
    1639     cout << Verbose(1) << "Coordinates of start node at " << *FirstPoint->node << "." << endl;
    16401498    AddTesselationPoint(FirstPoint, 0);
    1641     cout << Verbose(1) << "Found second point is at " << *SecondPoint->node << ".\n";
    16421499    AddTesselationPoint(SecondPoint, 1);
    16431500    AddTesselationLine(TPS[0], TPS[1], 0);
     
    17121569 * @param *LC LinkedCell structure with neighbouring points
    17131570 */
    1714 bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, LinkedCell *LC)
     1571bool Tesselation::FindNextSuitableTriangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N, LinkedCell *LC)
    17151572{
    17161573  cout << Verbose(0) << "Begin of FindNextSuitableTriangle\n";
     
    17471604    CircleRadius = RADIUS*RADIUS - radius/4.;
    17481605    CirclePlaneNormal.Normalize();
    1749     //cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;
     1606    cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;
    17501607
    17511608    // construct old center
     
    18341691        result = false;
    18351692      }
    1836     } else if ((existentTrianglesCount >= 1) && (existentTrianglesCount <= 3)) { // If there is a planar region within the structure, we need this triangle a second time.
     1693    } else if (existentTrianglesCount == 1) { // If there is a planar region within the structure, we need this triangle a second time.
    18371694        AddTesselationPoint((*it)->point, 0);
    18381695        AddTesselationPoint(BaseRay->endpoints[0]->node, 1);
     
    18751732    // set baseline to new ray from ref point (here endpoints[0]->node) to current candidate (here (*it)->point))
    18761733    BaseRay = BLS[0];
    1877     if ((BTS != NULL) && (BTS->NormalVector.NormSquared() < MYEPSILON)) {
    1878       *out << Verbose(1) << "CRITICAL: Triangle " << *BTS << " has zero normal vector!" << endl;
    1879       exit(255);
    1880     }
    1881 
    18821734  }
    18831735
     
    18981750 * \param *out output stream for debugging
    18991751 * \param *Base line to be flipped
    1900  * \return NULL - convex, otherwise endpoint that makes it concave
     1752 * \return NULL - concave, otherwise endpoint that makes it concave
    19011753 */
    19021754class BoundaryPointSet *Tesselation::IsConvexRectangle(ofstream *out, class BoundaryLineSet *Base)
     
    19751827 * \param *out output stream for debugging
    19761828 * \param *Base line to be flipped
    1977  * \return volume change due to flipping (0 - then no flipped occured)
    1978  */
    1979 double Tesselation::PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base)
     1829 * \return true - line was changed, false - same line as before
     1830 */
     1831bool Tesselation::PickFarthestofTwoBaselines(ofstream *out, class BoundaryLineSet *Base)
    19801832{
    19811833  class BoundaryLineSet *OtherBase;
    19821834  Vector *ClosestPoint[2];
    1983   double volume;
    19841835
    19851836  int m=0;
     
    20011852  Distance.CopyVector(ClosestPoint[1]);
    20021853  Distance.SubtractVector(ClosestPoint[0]);
    2003 
    2004   // calculate volume
    2005   volume = CalculateVolumeofGeneralTetraeder(Base->endpoints[1]->node->node, OtherBase->endpoints[0]->node->node, OtherBase->endpoints[1]->node->node, Base->endpoints[0]->node->node);
    20061854
    20071855  // delete the temporary other base line and the closest points
     
    20181866    if (Base->triangles.size() < 2) {
    20191867      *out << Verbose(2) << "ERROR: Less than two triangles are attached to this baseline!" << endl;
    2020       return 0.;
     1868      return false;
    20211869    }
    20221870    for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
     
    20281876    if (Distance.ScalarProduct(&BaseLineNormal) > MYEPSILON) { // Distance points outwards, hence OtherBase higher than Base -> flip
    20291877      *out << Verbose(2) << "ACCEPT: Other base line would be higher: Flipping baseline." << endl;
    2030       // calculate volume summand as a general tetraeder
    2031       return volume;
     1878      FlipBaseline(out, Base);
     1879      return true;
    20321880    } else {  // Base higher than OtherBase -> do nothing
    20331881      *out << Verbose(2) << "REJECT: Base line is higher: Nothing to do." << endl;
    2034       return 0.;
    2035     }
    2036   }
     1882      return false;
     1883    }
     1884  }
     1885};
     1886
     1887/** Returns the closest point on \a *Base with respect to \a *OtherBase.
     1888 * \param *out output stream for debugging
     1889 * \param *Base reference line
     1890 * \param *OtherBase other base line
     1891 * \return Vector on reference line that has closest distance
     1892 */
     1893Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase)
     1894{
     1895  // construct the plane of the two baselines (i.e. take both their directional vectors)
     1896  Vector Normal;
     1897  Vector Baseline, OtherBaseline;
     1898  Baseline.CopyVector(Base->endpoints[1]->node->node);
     1899  Baseline.SubtractVector(Base->endpoints[0]->node->node);
     1900  OtherBaseline.CopyVector(OtherBase->endpoints[1]->node->node);
     1901  OtherBaseline.SubtractVector(OtherBase->endpoints[0]->node->node);
     1902  Normal.CopyVector(&Baseline);
     1903  Normal.VectorProduct(&OtherBaseline);
     1904  Normal.Normalize();
     1905  *out << Verbose(4) << "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << "." << endl;
     1906
     1907  // project one offset point of OtherBase onto this plane (and add plane offset vector)
     1908  Vector NewOffset;
     1909  NewOffset.CopyVector(OtherBase->endpoints[0]->node->node);
     1910  NewOffset.SubtractVector(Base->endpoints[0]->node->node);
     1911  NewOffset.ProjectOntoPlane(&Normal);
     1912  NewOffset.AddVector(Base->endpoints[0]->node->node);
     1913  Vector NewDirection;
     1914  NewDirection.CopyVector(&NewOffset);
     1915  NewDirection.AddVector(&OtherBaseline);
     1916
     1917  // calculate the intersection between this projected baseline and Base
     1918  Vector *Intersection = new Vector;
     1919  Intersection->GetIntersectionOfTwoLinesOnPlane(out, Base->endpoints[0]->node->node, Base->endpoints[1]->node->node, &NewOffset, &NewDirection, &Normal);
     1920  Normal.CopyVector(Intersection);
     1921  Normal.SubtractVector(Base->endpoints[0]->node->node);
     1922  *out << Verbose(3) << "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(&Baseline)/Baseline.NormSquared()) << "." << endl;
     1923
     1924  return Intersection;
    20371925};
    20381926
     
    20421930 * \param *out output stream for debugging
    20431931 * \param *Base line to be flipped
    2044  * \return pointer to allocated new baseline - flipping successful, NULL - something went awry
    2045  */
    2046 class BoundaryLineSet * Tesselation::FlipBaseline(ofstream *out, class BoundaryLineSet *Base)
     1932 * \return true - flipping successful, false - something went awry
     1933 */
     1934bool Tesselation::FlipBaseline(ofstream *out, class BoundaryLineSet *Base)
    20471935{
    20481936  class BoundaryLineSet *OldLines[4], *NewLine;
     
    20581946  if (Base->triangles.size() < 2) {
    20591947    *out << Verbose(2) << "ERROR: Less than two triangles are attached to this baseline!" << endl;
    2060     return NULL;
     1948    return false;
    20611949  }
    20621950  for (TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) {
     
    20941982  if (i<4) {
    20951983    *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl;
    2096     return NULL;
     1984    return false;
    20971985  }
    20981986  for (int j=0;j<4;j++)
    20991987    if (OldLines[j] == NULL) {
    21001988      *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl;
    2101       return NULL;
     1989      return false;
    21021990    }
    21031991  for (int j=0;j<2;j++)
    21041992    if (OldPoints[j] == NULL) {
    21051993      *out << Verbose(1) << "ERROR: We have not gathered enough endpoints!" << endl;
    2106       return NULL;
     1994      return false;
    21071995    }
    21081996
     
    21362024    BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[0]);
    21372025    BTS->GetNormalVector(BaseLineNormal);
    2138     AddTesselationTriangle(OldTriangleNrs[0]);
     2026    TrianglesOnBoundary.insert(TrianglePair(OldTriangleNrs[0], BTS));
    21392027    *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl;
    21402028
     
    21442032    BTS = new class BoundaryTriangleSet(BLS, OldTriangleNrs[1]);
    21452033    BTS->GetNormalVector(BaseLineNormal);
    2146     AddTesselationTriangle(OldTriangleNrs[1]);
     2034    TrianglesOnBoundary.insert(TrianglePair(OldTriangleNrs[1], BTS));
    21472035    *out << Verbose(3) << "INFO: Created new triangle " << *BTS << "." << endl;
    21482036  } else {
    21492037    *out << Verbose(1) << "The four old lines do not connect, something's utterly wrong here!" << endl;
    2150     return NULL;
     2038    return false;
    21512039  }
    21522040
    21532041  *out << Verbose(1) << "End of FlipBaseline" << endl;
    2154   return NewLine;
     2042  return true;
    21552043};
    21562044
     
    21582046/** Finds the second point of starting triangle.
    21592047 * \param *a first node
     2048 * \param *Candidate pointer to candidate node on return
    21602049 * \param Oben vector indicating the outside
    21612050 * \param OptCandidate reference to recommended candidate on return
     
    21642053 * \param *LC LinkedCell structure with neighbouring points
    21652054 */
    2166 void Tesselation::FindSecondPointForTesselation(TesselPoint* a, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, LinkedCell *LC)
     2055void Tesselation::FindSecondPointForTesselation(TesselPoint* a, TesselPoint* Candidate, Vector Oben, TesselPoint*& OptCandidate, double Storage[3], double RADIUS, LinkedCell *LC)
    21672056{
    21682057  cout << Verbose(2) << "Begin of FindSecondPointForTesselation" << endl;
    21692058  Vector AngleCheck;
    2170   class TesselPoint* Candidate = NULL;
    21712059  double norm = -1., angle;
    21722060  LinkedNodes *List = NULL;
     
    23032191  cout << Verbose(1) << "Begin of FindThirdPointForTesselation" << endl;
    23042192
    2305   cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl;
     2193  //cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << NormalVector << "." << endl;
    23062194
    23072195  // construct center of circle
     
    23282216    radius = OldSphereCenter.ScalarProduct(&OldSphereCenter);
    23292217    if (fabs(radius - CircleRadius) < HULLEPSILON) {
    2330       //cout << Verbose(2) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl;
    23312218
    23322219      // check SearchDirection
     
    25052392  TesselPoint *trianglePoints[3];
    25062393  TesselPoint *SecondPoint = NULL;
    2507   list<BoundaryTriangleSet*> *triangles = NULL;
    25082394
    25092395  if (LinesOnBoundary.empty()) {
     
    25162402  // check whether closest point is "too close" :), then it's inside
    25172403  if (trianglePoints[0] == NULL) {
    2518     *out << Verbose(2) << "Is the only point, no one else is closeby." << endl;
     2404    *out << Verbose(1) << "Is the only point, no one else is closeby." << endl;
    25192405    return NULL;
    25202406  }
    25212407  if (trianglePoints[0]->node->DistanceSquared(x) < MYEPSILON) {
    2522     *out << Verbose(3) << "Point is right on a tesselation point, no nearest triangle." << endl;
    2523     PointMap::iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr);
    2524     triangles = new list<BoundaryTriangleSet*>;
    2525     if (PointRunner != PointsOnBoundary.end()) {
    2526       for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++)
    2527         for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++)
    2528           triangles->push_back(TriangleRunner->second);
    2529       triangles->sort();
    2530       triangles->unique();
    2531     } else {
    2532       PointRunner = PointsOnBoundary.find(SecondPoint->nr);
    2533       trianglePoints[0] = SecondPoint;
    2534       if (PointRunner != PointsOnBoundary.end()) {
    2535         for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++)
    2536           for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++)
    2537             triangles->push_back(TriangleRunner->second);
    2538         triangles->sort();
    2539         triangles->unique();
    2540       } else {
    2541         *out << Verbose(1) << "ERROR: I cannot find a boundary point to the tessel point " << *trianglePoints[0] << "." << endl;
    2542         return NULL;
    2543       }
    2544     }
    2545   } else {
    2546     list<TesselPoint*> *connectedClosestPoints = GetCircleOfConnectedPoints(out, trianglePoints[0], x);
    2547     trianglePoints[1] = connectedClosestPoints->front();
    2548     trianglePoints[2] = connectedClosestPoints->back();
    2549     for (int i=0;i<3;i++) {
    2550       if (trianglePoints[i] == NULL) {
    2551         *out << Verbose(1) << "ERROR: IsInnerPoint encounters serious error, point " << i << " not found." << endl;
    2552       }
    2553       //*out << Verbose(2) << "List of triangle points:" << endl;
    2554       //*out << Verbose(3) << *trianglePoints[i] << endl;
    2555     }
    2556 
    2557     triangles = FindTriangles(trianglePoints);
    2558     *out << Verbose(2) << "List of possible triangles:" << endl;
    2559     for(list<BoundaryTriangleSet*>::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++)
    2560       *out << Verbose(3) << **Runner << endl;
    2561 
    2562     delete(connectedClosestPoints);
    2563   }
     2408    *out << Verbose(1) << "Point is right on a tesselation point, no nearest triangle." << endl;
     2409    return NULL;
     2410  }
     2411  list<TesselPoint*> *connectedPoints = GetCircleOfConnectedPoints(out, trianglePoints[0]);
     2412  list<TesselPoint*> *connectedClosestPoints = GetNeighboursOnCircleOfConnectedPoints(out, connectedPoints, trianglePoints[0], x);
     2413  delete(connectedPoints);
     2414  trianglePoints[1] = connectedClosestPoints->front();
     2415  trianglePoints[2] = connectedClosestPoints->back();
     2416  for (int i=0;i<3;i++) {
     2417    if (trianglePoints[i] == NULL) {
     2418      *out << Verbose(1) << "IsInnerPoint encounters serious error, point " << i << " not found." << endl;
     2419    }
     2420    //*out << Verbose(1) << "List of possible points:" << endl;
     2421    //*out << Verbose(2) << *trianglePoints[i] << endl;
     2422  }
     2423
     2424  list<BoundaryTriangleSet*> *triangles = FindTriangles(trianglePoints);
     2425
     2426  delete(connectedClosestPoints);
    25642427 
    25652428  if (triangles->empty()) {
    2566     *out << Verbose(0) << "ERROR: There is no nearest triangle. Please check the tesselation structure.";
    2567     delete(triangles);
     2429    *out << Verbose(0) << "Error: There is no nearest triangle. Please check the tesselation structure.";
    25682430    return NULL;
    25692431  } else
     
    25812443  class BoundaryTriangleSet *result = NULL;
    25822444  list<BoundaryTriangleSet*> *triangles = FindClosestTrianglesToPoint(out, x, LC);
    2583   Vector Center;
    25842445
    25852446  if (triangles == NULL)
    25862447    return NULL;
    25872448
    2588   if (triangles->size() == 1) { // there is no degenerate case
     2449  if (x->ScalarProduct(&triangles->front()->NormalVector) < 0)
     2450    result = triangles->back();
     2451  else
    25892452    result = triangles->front();
    2590     *out << Verbose(2) << "Normal Vector of this triangle is " << result->NormalVector << "." << endl;
    2591   } else {
    2592     result = triangles->front();
    2593     result->GetCenter(&Center);
    2594     Center.SubtractVector(x);
    2595     *out << Verbose(2) << "Normal Vector of this front side is " << result->NormalVector << "." << endl;
    2596     if (Center.ScalarProduct(&result->NormalVector) < 0) {
    2597       result = triangles->back();
    2598       *out << Verbose(2) << "Normal Vector of this back side is " << result->NormalVector << "." << endl;
    2599       if (Center.ScalarProduct(&result->NormalVector) < 0) {
    2600         *out << Verbose(1) << "ERROR: Front and back side yield NormalVector in wrong direction!" << endl;
    2601       }
    2602     }
    2603   }
     2453
    26042454  delete(triangles);
    26052455  return result;
     
    26162466{
    26172467  class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, &Point, LC);
    2618   Vector Center;
    2619 
    2620   if (result == NULL) {// is boundary point or only point in point cloud?
    2621     *out << Verbose(1) << Point << " is the only point in vicinity." << endl;
     2468  if (result == NULL)
     2469    return true;
     2470  if (Point.ScalarProduct(&result->NormalVector) < 0)
     2471    return true;
     2472  else
    26222473    return false;
    2623   }
    2624 
    2625   result->GetCenter(&Center);
    2626   *out << Verbose(3) << "INFO: Central point of the triangle is " << Center << "." << endl;
    2627   Center.SubtractVector(&Point);
    2628   *out << Verbose(3) << "INFO: Vector from center to point to test is " << Center << "." << endl;
    2629   if (Center.ScalarProduct(&result->NormalVector) > -MYEPSILON) {
    2630     *out << Verbose(1) << Point << " is an inner point." << endl;
    2631     return true;
    2632   } else {
    2633     *out << Verbose(1) << Point << " is NOT an inner point." << endl;
    2634     return false;
    2635   }
    26362474}
    26372475
     
    26452483bool Tesselation::IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC)
    26462484{
    2647   return IsInnerPoint(out, *(Point->node), LC);
     2485  class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, Point->node, LC);
     2486  if (result == NULL)
     2487    return true;
     2488  if (Point->node->ScalarProduct(&result->NormalVector) < 0)
     2489    return true;
     2490  else
     2491    return false;
    26482492}
    26492493
     
    26522496 * @param *Point of which get all connected points
    26532497 *
    2654  * @return set of the all points linked to the provided one
    2655  */
    2656 set<TesselPoint*> * Tesselation::GetAllConnectedPoints(ofstream *out, TesselPoint* Point)
    2657 {
    2658   set<TesselPoint*> *connectedPoints = new set<TesselPoint*>;
     2498 * @return list of the all points linked to the provided one
     2499 */
     2500list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point)
     2501{
     2502  list<TesselPoint*> *connectedPoints = new list<TesselPoint*>;
    26592503  class BoundaryPointSet *ReferencePoint = NULL;
    26602504  TesselPoint* current;
     
    26662510    ReferencePoint = PointRunner->second;
    26672511  } else {
    2668     *out << Verbose(2) << "GetAllConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;
     2512    *out << Verbose(2) << "getCircleOfConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;
    26692513    ReferencePoint = NULL;
    26702514  }
    26712515
    2672   // little trick so that we look just through lines connect to the BoundaryPoint
     2516  // little trick so that we look just through lines connect to the BoundaryPoint 
    26732517  // OR fall-back to look through all lines if there is no such BoundaryPoint
    26742518  LineMap *Lines = &LinesOnBoundary;
     
    26772521  LineMap::iterator findLines = Lines->begin();
    26782522  while (findLines != Lines->end()) {
    2679    takePoint = false;
    2680 
    2681    if (findLines->second->endpoints[0]->Nr == Point->nr) {
    2682      takePoint = true;
    2683      current = findLines->second->endpoints[1]->node;
    2684    } else if (findLines->second->endpoints[1]->Nr == Point->nr) {
    2685      takePoint = true;
    2686      current = findLines->second->endpoints[0]->node;
    2687    }
    2688 
    2689    if (takePoint) {
    2690      *out << Verbose(5) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is enlisted." << endl;
    2691      connectedPoints->insert(current);
    2692    }
    2693 
    2694    findLines++;
     2523    takePoint = false;
     2524
     2525    if (findLines->second->endpoints[0]->Nr == Point->nr) {
     2526      takePoint = true;
     2527      current = findLines->second->endpoints[1]->node;
     2528    } else if (findLines->second->endpoints[1]->Nr == Point->nr) {
     2529      takePoint = true;
     2530      current = findLines->second->endpoints[0]->node;
     2531    }
     2532   
     2533    if (takePoint) {
     2534      *out << Verbose(3) << "INFO: Endpoint " << *current << " of line " << *(findLines->second) << " is taken into the circle." << endl;
     2535      connectedPoints->push_back(current);
     2536    }
     2537
     2538    findLines++;
    26952539  }
    26962540
     
    26992543    return NULL;
    27002544  }
    2701 
    27022545  return connectedPoints;
    2703 };
    2704 
    2705 
    2706 /** Gets all points connected to the provided point by triangulation lines, ordered such that we have the circle round the point.
     2546}
     2547
     2548/** Gets the two neighbouring points with respect to a reference line to the provided point.
    27072549 * Maps them down onto the plane designated by the axis \a *Point and \a *Reference. The center of all points
    27082550 * connected in the tesselation to \a *Point is mapped to spherical coordinates with the zero angle being given
     
    27112553 *
    27122554 * @param *out output stream for debugging
     2555 * @param *connectedPoints list of connected points to the central \a *Point
    27132556 * @param *Point of which get all connected points
    2714  * @param *Reference Reference vector for zero angle or NULL for no preference
    2715  * @return list of the all points linked to the provided one
    2716  */
    2717 list<TesselPoint*> * Tesselation::GetCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector *Reference)
     2557 * @param *Reference Vector to be checked whether it is an inner point
     2558 *
     2559 * @return list of the two points linked to the provided one and closest to the point to be checked,
     2560 */
     2561list<TesselPoint*> * Tesselation::GetNeighboursOnCircleOfConnectedPoints(ofstream *out, list<TesselPoint*> *connectedPoints, TesselPoint* Point, Vector* Reference)
    27182562{
    27192563  map<double, TesselPoint*> anglesOfPoints;
    2720   set<TesselPoint*> *connectedPoints = GetAllConnectedPoints(out, Point);
    2721   list<TesselPoint*> *connectedCircle = new list<TesselPoint*>;
    2722   Vector center;
    2723   Vector PlaneNormal;
    2724   Vector AngleZero;
    2725   Vector OrthogonalVector;
    2726   Vector helper;
     2564  map<double, TesselPoint*>::iterator runner;
     2565  ;
     2566  Vector center, PlaneNormal, OrthogonalVector, helper, AngleZero;
     2567
     2568  if (connectedPoints->size() == 0) { // if have not found any points
     2569    *out << Verbose(1) << "ERROR: We have not found any connected points to " << *Point<< "." << endl;
     2570    return NULL;
     2571  }
    27272572
    27282573  // calculate central point
    2729   for (set<TesselPoint*>::iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++)
     2574  for (list<TesselPoint*>::iterator TesselRunner = connectedPoints->begin(); TesselRunner != connectedPoints->end(); TesselRunner++)
    27302575    center.AddVector((*TesselRunner)->node);
    27312576  //*out << "Summed vectors " << center << "; number of points " << connectedPoints.size()
     
    27412586
    27422587  // construct one orthogonal vector
    2743   if (Reference != NULL)
    2744     AngleZero.CopyVector(Reference);
    2745   else
    2746     AngleZero.CopyVector((*connectedPoints->begin())->node);
     2588  AngleZero.CopyVector(Reference);
    27472589  AngleZero.SubtractVector(Point->node);
    27482590  AngleZero.ProjectOntoPlane(&PlaneNormal);
     
    27522594
    27532595  // go through all connected points and calculate angle
    2754   for (set<TesselPoint*>::iterator listRunner = connectedPoints->begin(); listRunner != connectedPoints->end(); listRunner++) {
     2596  for (list<TesselPoint*>::iterator listRunner = connectedPoints->begin(); listRunner != connectedPoints->end(); listRunner++) {
    27552597    helper.CopyVector((*listRunner)->node);
    27562598    helper.SubtractVector(Point->node);
    27572599    helper.ProjectOntoPlane(&PlaneNormal);
    27582600    double angle = GetAngle(helper, AngleZero, OrthogonalVector);
    2759     *out << Verbose(3) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl;
     2601    *out << Verbose(2) << "INFO: Calculated angle is " << angle << " for point " << **listRunner << "." << endl;
    27602602    anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner)));
    27612603  }
    27622604
    2763   for(map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) {
    2764     connectedCircle->push_back(AngleRunner->second);
    2765   }
    2766 
    2767   delete(connectedPoints);
    2768   return connectedCircle;
     2605  list<TesselPoint*> *result = new list<TesselPoint*>;
     2606  runner = anglesOfPoints.begin();
     2607  result->push_back(runner->second);
     2608  runner = anglesOfPoints.end();
     2609  runner--;
     2610  result->push_back(runner->second);
     2611
     2612  *out << Verbose(2) << "List of closest points has " << result->size() << " elements, which are "
     2613    << *(result->front()) << " and " << *(result->back()) << endl;
     2614
     2615  return result;
    27692616}
    27702617
    2771 /** Gets all points connected to the provided point by triangulation lines, ordered such that we walk along a closed path.
    2772  *
    2773  * @param *out output stream for debugging
    2774  * @param *Point of which get all connected points
    2775  * @return list of the all points linked to the provided one
    2776  */
    2777 list<list<TesselPoint*> *> * Tesselation::GetPathsOfConnectedPoints(ofstream *out, TesselPoint* Point)
    2778 {
    2779   map<double, TesselPoint*> anglesOfPoints;
    2780   list<list<TesselPoint*> *> *ListOfPaths = new list<list<TesselPoint*> *>;
    2781   list<TesselPoint*> *connectedPath = NULL;
    2782   Vector center;
    2783   Vector PlaneNormal;
    2784   Vector AngleZero;
    2785   Vector OrthogonalVector;
    2786   Vector helper;
    2787   class BoundaryPointSet *ReferencePoint = NULL;
    2788   class BoundaryPointSet *CurrentPoint = NULL;
    2789   class BoundaryTriangleSet *triangle = NULL;
    2790   class BoundaryLineSet *CurrentLine = NULL;
    2791   class BoundaryLineSet *StartLine = NULL;
    2792 
    2793   // find the respective boundary point
    2794   PointMap::iterator PointRunner = PointsOnBoundary.find(Point->nr);
    2795   if (PointRunner != PointsOnBoundary.end()) {
    2796     ReferencePoint = PointRunner->second;
    2797   } else {
    2798     *out << Verbose(2) << "ERROR: GetPathOfConnectedPoints() could not find the BoundaryPoint belonging to " << *Point << "." << endl;
    2799     return NULL;
    2800   }
    2801 
    2802   map <class BoundaryLineSet *, bool> TouchedLine;
    2803   map <class BoundaryTriangleSet *, bool> TouchedTriangle;
    2804   map <class BoundaryLineSet *, bool>::iterator LineRunner;
    2805   map <class BoundaryTriangleSet *, bool>::iterator TriangleRunner;
    2806   for (LineMap::iterator Runner = ReferencePoint->lines.begin(); Runner != ReferencePoint->lines.end(); Runner++) {
    2807     TouchedLine.insert( pair <class BoundaryLineSet *, bool>(Runner->second, false) );
    2808     for (TriangleMap::iterator Sprinter = Runner->second->triangles.begin(); Sprinter != Runner->second->triangles.end(); Sprinter++)
    2809       TouchedTriangle.insert( pair <class BoundaryTriangleSet *, bool>(Sprinter->second, false) );
    2810   }
    2811   if (!ReferencePoint->lines.empty()) {
    2812     for (LineMap::iterator runner = ReferencePoint->lines.begin(); runner != ReferencePoint->lines.end(); runner++) {
    2813       LineRunner = TouchedLine.find(runner->second);
    2814       if (LineRunner == TouchedLine.end()) {
    2815         *out << Verbose(2) << "ERROR: I could not find " << *runner->second << " in the touched list." << endl;
    2816       } else if (!LineRunner->second) {
    2817         LineRunner->second = true;
    2818         connectedPath = new list<TesselPoint*>;
    2819         triangle = NULL;
    2820         CurrentLine = runner->second;
    2821         StartLine = CurrentLine;
    2822         CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
    2823         *out << Verbose(3)<< "INFO: Beginning path retrieval at " << *CurrentPoint << " of line " << *CurrentLine << "." << endl;
    2824         do {
    2825           // push current one
    2826           *out << Verbose(3) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl;
    2827           connectedPath->push_back(CurrentPoint->node);
    2828 
    2829           // find next triangle
    2830           for (TriangleMap::iterator Runner = CurrentLine->triangles.begin(); Runner != CurrentLine->triangles.end(); Runner++) {
    2831             *out << Verbose(3) << "INFO: Inspecting triangle " << *Runner->second << "." << endl;
    2832             if ((Runner->second != triangle)) { // look for first triangle not equal to old one
    2833               triangle = Runner->second;
    2834               TriangleRunner = TouchedTriangle.find(triangle);
    2835               if (TriangleRunner != TouchedTriangle.end()) {
    2836                 if (!TriangleRunner->second) {
    2837                   TriangleRunner->second = true;
    2838                   *out << Verbose(3) << "INFO: Connecting triangle is " << *triangle << "." << endl;
    2839                   break;
    2840                 } else {
    2841                   *out << Verbose(3) << "INFO: Skipping " << *triangle << ", as we have already visited it." << endl;
    2842                   triangle = NULL;
    2843                 }
    2844               } else {
    2845                 *out << Verbose(2) << "ERROR: I could not find " << *triangle << " in the touched list." << endl;
    2846                 triangle = NULL;
    2847               }
    2848             }
    2849           }
    2850           if (triangle == NULL)
    2851             break;
    2852           // find next line
    2853           for (int i=0;i<3;i++) {
    2854             if ((triangle->lines[i] != CurrentLine) && (triangle->lines[i]->ContainsBoundaryPoint(ReferencePoint))) { // not the current line and still containing Point
    2855               CurrentLine = triangle->lines[i];
    2856               *out << Verbose(3) << "INFO: Connecting line is " << *CurrentLine << "." << endl;
    2857               break;
    2858             }
    2859           }
    2860           LineRunner = TouchedLine.find(CurrentLine);
    2861           if (LineRunner == TouchedLine.end())
    2862             *out << Verbose(2) << "ERROR: I could not find " << *CurrentLine << " in the touched list." << endl;
    2863           else
    2864             LineRunner->second = true;
    2865           // find next point
    2866           CurrentPoint = CurrentLine->GetOtherEndpoint(ReferencePoint);
    2867 
    2868         } while (CurrentLine != StartLine);
    2869         // last point is missing, as it's on start line
    2870         *out << Verbose(3) << "INFO: Putting " << *CurrentPoint << " at end of path." << endl;
    2871         if (StartLine->GetOtherEndpoint(ReferencePoint)->node != connectedPath->back())
    2872           connectedPath->push_back(StartLine->GetOtherEndpoint(ReferencePoint)->node);
    2873 
    2874         ListOfPaths->push_back(connectedPath);
    2875       } else {
    2876         *out << Verbose(3) << "INFO: Skipping " << *runner->second << ", as we have already visited it." << endl;
    2877       }
    2878     }
    2879   } else {
    2880     *out << Verbose(1) << "ERROR: There are no lines attached to " << *ReferencePoint << "." << endl;
    2881   }
    2882 
    2883   return ListOfPaths;
    2884 }
    2885 
    2886 /** Gets all closed paths on the circle of points connected to the provided point by triangulation lines, if this very point is removed.
    2887  * From GetPathsOfConnectedPoints() extracts all single loops of intracrossing paths in the list of closed paths.
    2888  * @param *out output stream for debugging
    2889  * @param *Point of which get all connected points
    2890  * @return list of the closed paths
    2891  */
    2892 list<list<TesselPoint*> *> * Tesselation::GetClosedPathsOfConnectedPoints(ofstream *out, TesselPoint* Point)
    2893 {
    2894   list<list<TesselPoint*> *> *ListofPaths = GetPathsOfConnectedPoints(out, Point);
    2895   list<list<TesselPoint*> *> *ListofClosedPaths = new list<list<TesselPoint*> *>;
    2896   list<TesselPoint*> *connectedPath = NULL;
    2897   list<TesselPoint*> *newPath = NULL;
    2898   int count = 0;
    2899 
    2900 
    2901   list<TesselPoint*>::iterator CircleRunner;
    2902   list<TesselPoint*>::iterator CircleStart;
    2903 
    2904   for(list<list<TesselPoint*> *>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) {
    2905     connectedPath = *ListRunner;
    2906 
    2907     *out << Verbose(2) << "INFO: Current path is " << connectedPath << "." << endl;
    2908 
    2909     // go through list, look for reappearance of starting Point and count
    2910     CircleStart = connectedPath->begin();
    2911 
    2912     // go through list, look for reappearance of starting Point and create list
    2913     list<TesselPoint*>::iterator Marker = CircleStart;
    2914     for (CircleRunner = CircleStart; CircleRunner != connectedPath->end(); CircleRunner++) {
    2915       if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point
    2916         // we have a closed circle from Marker to new Marker
    2917         *out << Verbose(3) << count+1 << ". closed path consists of: ";
    2918         newPath = new list<TesselPoint*>;
    2919         list<TesselPoint*>::iterator CircleSprinter = Marker;
    2920         for (; CircleSprinter != CircleRunner; CircleSprinter++) {
    2921           newPath->push_back(*CircleSprinter);
    2922           *out << (**CircleSprinter) << " <-> ";
    2923         }
    2924         *out << ".." << endl;
    2925         count++;
    2926         Marker = CircleRunner;
    2927 
    2928         // add to list
    2929         ListofClosedPaths->push_back(newPath);
    2930       }
    2931     }
    2932   }
    2933   *out << Verbose(3) << "INFO: " << count << " closed additional path(s) have been created." << endl;
    2934 
    2935   // delete list of paths
    2936   while (!ListofPaths->empty()) {
    2937     connectedPath = *(ListofPaths->begin());
    2938     ListofPaths->remove(connectedPath);
    2939     delete(connectedPath);
    2940   }
    2941   delete(ListofPaths);
    2942 
    2943   // exit
    2944   return ListofClosedPaths;
    2945 };
    2946 
    2947 
    2948 /** Gets all belonging triangles for a given BoundaryPointSet.
    2949  * \param *out output stream for debugging
    2950  * \param *Point BoundaryPoint
    2951  * \return pointer to allocated list of triangles
    2952  */
    2953 set<BoundaryTriangleSet*> *Tesselation::GetAllTriangles(ofstream *out, class BoundaryPointSet *Point)
    2954 {
    2955   set<BoundaryTriangleSet*> *connectedTriangles = new set<BoundaryTriangleSet*>;
    2956 
    2957   if (Point == NULL) {
    2958     *out << Verbose(1) << "ERROR: Point given is NULL." << endl;
    2959   } else {
    2960     // go through its lines and insert all triangles
    2961     for (LineMap::iterator LineRunner = Point->lines.begin(); LineRunner != Point->lines.end(); LineRunner++)
    2962       for (TriangleMap::iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) {
    2963       connectedTriangles->insert(TriangleRunner->second);
    2964     }
    2965   }
    2966 
    2967   return connectedTriangles;
    2968 };
    2969 
    2970 
    29712618/** Removes a boundary point from the envelope while keeping it closed.
    2972  * We remove the old triangles connected to the point and re-create new triangles to close the surface following this ansatz:
    2973  *  -# a closed path(s) of boundary points surrounding the point to be removed is constructed
    2974  *  -# on each closed path, we pick three adjacent points, create a triangle with them and subtract the middle point from the path
    2975  *  -# we advance two points (i.e. the next triangle will start at the ending point of the last triangle) and continue as before
    2976  *  -# the surface is closed, when the path is empty
    2977  * Thereby, we (hopefully) make sure that the removed points remains beneath the surface (this is checked via IsInnerPoint eventually).
     2619 * We create new triangles and remove the old ones connected to the point.
    29782620 * \param *out output stream for debugging
    29792621 * \param *point point to be removed
     
    29832625  class BoundaryLineSet *line = NULL;
    29842626  class BoundaryTriangleSet *triangle = NULL;
    2985   Vector OldPoint, NormalVector;
     2627  Vector OldPoint, TetraederVector[3];
    29862628  double volume = 0;
     2629  int *numbers = NULL;
    29872630  int count = 0;
     2631  int i;
    29882632
    29892633  if (point == NULL) {
     
    30012645    return 0.;
    30022646  }
    3003 
    3004   list<list<TesselPoint*> *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(out, point->node);
    3005   list<TesselPoint*> *connectedPath = NULL;
    3006 
    3007   // gather all triangles
     2647  list<TesselPoint*> *CircleofPoints = GetCircleOfConnectedPoints(out, point->node);
     2648
     2649  // remove all triangles
    30082650  for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++)
    30092651    count+=LineRunner->second->triangles.size();
    3010   map<class BoundaryTriangleSet *, int> Candidates;
    3011   for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) {
     2652  numbers = new int[count];
     2653  class BoundaryTriangleSet **Candidates = new BoundaryTriangleSet*[count];
     2654  i=0;
     2655  for (LineMap::iterator LineRunner = point->lines.begin(); (point != NULL) && (LineRunner != point->lines.end()); LineRunner++) {
    30122656    line = LineRunner->second;
    30132657    for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) {
    30142658      triangle = TriangleRunner->second;
    3015       Candidates.insert( pair<class BoundaryTriangleSet *, int> (triangle, triangle->Nr) );
    3016     }
    3017   }
    3018 
    3019   // remove all triangles
    3020   count=0;
    3021   NormalVector.Zero();
    3022   for (map<class BoundaryTriangleSet *, int>::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) {
    3023     *out << Verbose(3) << "INFO: Removing triangle " << *(Runner->first) << "." << endl;
    3024     NormalVector.SubtractVector(&Runner->first->NormalVector); // has to point inward
    3025     RemoveTesselationTriangle(Runner->first);
    3026     count++;
    3027   }
    3028   *out << Verbose(1) << count << " triangles were removed." << endl;
    3029 
    3030   list<list<TesselPoint*> *>::iterator ListAdvance = ListOfClosedPaths->begin();
    3031   list<list<TesselPoint*> *>::iterator ListRunner = ListAdvance;
    3032   map<class BoundaryTriangleSet *, int>::iterator NumberRunner = Candidates.begin();
    3033   list<TesselPoint*>::iterator StartNode, MiddleNode, EndNode;
    3034   double angle;
    3035   double smallestangle;
    3036   Vector Point, Reference, OrthogonalVector;
    3037   if (count > 2) {  // less than three triangles, then nothing will be created
    3038     class TesselPoint *TriangleCandidates[3];
    3039     count = 0;
    3040     for ( ; ListRunner != ListOfClosedPaths->end(); ListRunner = ListAdvance) {  // go through all closed paths
    3041       if (ListAdvance != ListOfClosedPaths->end())
    3042         ListAdvance++;
    3043 
    3044       connectedPath = *ListRunner;
    3045 
    3046       // re-create all triangles by going through connected points list
    3047       list<class BoundaryLineSet *> NewLines;
    3048       for (;!connectedPath->empty();) {
    3049         // search middle node with widest angle to next neighbours
    3050         EndNode = connectedPath->end();
    3051         smallestangle = 0.;
    3052         for (MiddleNode = connectedPath->begin(); MiddleNode != connectedPath->end(); MiddleNode++) {
    3053           cout << Verbose(3) << "INFO: MiddleNode is " << **MiddleNode << "." << endl;
    3054           // construct vectors to next and previous neighbour
    3055           StartNode = MiddleNode;
    3056           if (StartNode == connectedPath->begin())
    3057             StartNode = connectedPath->end();
    3058           StartNode--;
    3059           //cout << Verbose(3) << "INFO: StartNode is " << **StartNode << "." << endl;
    3060           Point.CopyVector((*StartNode)->node);
    3061           Point.SubtractVector((*MiddleNode)->node);
    3062           StartNode = MiddleNode;
    3063           StartNode++;
    3064           if (StartNode == connectedPath->end())
    3065             StartNode = connectedPath->begin();
    3066           //cout << Verbose(3) << "INFO: EndNode is " << **StartNode << "." << endl;
    3067           Reference.CopyVector((*StartNode)->node);
    3068           Reference.SubtractVector((*MiddleNode)->node);
    3069           OrthogonalVector.CopyVector((*MiddleNode)->node);
    3070           OrthogonalVector.SubtractVector(&OldPoint);
    3071           OrthogonalVector.MakeNormalVector(&Reference);
    3072           angle = GetAngle(Point, Reference, OrthogonalVector);
    3073           //if (angle < M_PI)  // no wrong-sided triangles, please?
    3074             if(fabs(angle - M_PI) < fabs(smallestangle - M_PI)) {  // get straightest angle (i.e. construct those triangles with smallest area first)
    3075               smallestangle = angle;
    3076               EndNode = MiddleNode;
     2659      Candidates[i] = triangle;
     2660      numbers[i++] = triangle->Nr;
     2661    }
     2662  }
     2663  for (int j=0;j<i;j++) {
     2664    RemoveTesselationTriangle(Candidates[j]);
     2665  }
     2666  delete[](Candidates);
     2667  *out << Verbose(1) << i << " triangles were removed." << endl;
     2668
     2669  // re-create all triangles by going through connected points list
     2670  list<TesselPoint*>::iterator CircleRunner = CircleofPoints->begin();
     2671  list<TesselPoint*>::iterator OtherCircleRunner = CircleofPoints->begin();
     2672  class TesselPoint *CentralNode = *CircleRunner;
     2673  // advance two with CircleRunner and one with OtherCircleRunner
     2674  CircleRunner++;
     2675  CircleRunner++;
     2676  OtherCircleRunner++;
     2677  i=0;
     2678  cout << Verbose(2) << "INFO: CentralNode is " << *CentralNode << "." << endl;
     2679  for (; (OtherCircleRunner != CircleofPoints->end()) && (CircleRunner != CircleofPoints->end()); (CircleRunner++), (OtherCircleRunner++)) {
     2680    cout << Verbose(3) << "INFO: CircleRunner's node is " << **CircleRunner << "." << endl;
     2681    cout << Verbose(3) << "INFO: OtherCircleRunner's node is " << **OtherCircleRunner << "." << endl;
     2682    *out << Verbose(4) << "Adding new triangle points."<< endl;
     2683    AddTesselationPoint(CentralNode, 0);
     2684    AddTesselationPoint(*OtherCircleRunner, 1);
     2685    AddTesselationPoint(*CircleRunner, 2);
     2686    *out << Verbose(4) << "Adding new triangle lines."<< endl;
     2687    AddTesselationLine(TPS[0], TPS[1], 0);
     2688    AddTesselationLine(TPS[0], TPS[2], 1);
     2689    AddTesselationLine(TPS[1], TPS[2], 2);
     2690    BTS = new class BoundaryTriangleSet(BLS, numbers[i]);
     2691    TrianglesOnBoundary.insert(TrianglePair(numbers[i], BTS));
     2692    *out << Verbose(4) << "Created triangle " << *BTS << "." << endl;
     2693    // calculate volume summand as a general tetraeder
     2694    for (int j=0;j<3;j++) {
     2695      TetraederVector[j].CopyVector(TPS[j]->node->node);
     2696      TetraederVector[j].SubtractVector(&OldPoint);
     2697    }
     2698    OldPoint.CopyVector(&TetraederVector[0]);
     2699    OldPoint.VectorProduct(&TetraederVector[1]);
     2700    volume += 1./6. * fabs(OldPoint.ScalarProduct(&TetraederVector[2]));
     2701    // advance number
     2702    i++;
     2703    if (i >= count)
     2704      *out << Verbose(2) << "WARNING: Maximum of numbers reached!" << endl;
     2705  }
     2706  *out << Verbose(1) << i << " triangles were created." << endl;
     2707
     2708  delete[](numbers);
     2709
     2710  return volume;
     2711};
     2712
     2713/** Checks for a new special triangle whether one of its edges is already present with one one triangle connected.
     2714 * This enforces that special triangles (i.e. degenerated ones) should at last close the open-edge frontier and not
     2715 * make it bigger (i.e. closing one (the baseline) and opening two new ones).
     2716 * \param TPS[3] nodes of the triangle
     2717 * \return true - there is such a line (i.e. creation of degenerated triangle is valid), false - no such line (don't create)
     2718 */
     2719bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3])
     2720{
     2721  bool result = false;
     2722  int counter = 0;
     2723
     2724  // check all three points
     2725  for (int i=0;i<3;i++)
     2726    for (int j=i+1; j<3; j++) {
     2727      if (nodes[i]->lines.find(nodes[j]->node->nr) != nodes[i]->lines.end()) {  // there already is a line
     2728        LineMap::iterator FindLine;
     2729        pair<LineMap::iterator,LineMap::iterator> FindPair;
     2730        FindPair = nodes[i]->lines.equal_range(nodes[j]->node->nr);
     2731        for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) {
     2732          // If there is a line with less than two attached triangles, we don't need a new line.
     2733          if (FindLine->second->triangles.size() < 2) {
     2734            counter++;
     2735            break;  // increase counter only once per edge
     2736          }
     2737        }
     2738      } else { // no line
     2739        cout << Verbose(1) << "The line between " << nodes[i] << " and " << nodes[j] << " is not yet present, hence no need for a degenerate triangle." << endl;
     2740        result = true;
     2741      }
     2742    }
     2743  if (counter > 1) {
     2744    cout << Verbose(2) << "INFO: Degenerate triangle is ok, at least two, here " << counter << ", existing lines are used." << endl;
     2745    result = true;
     2746  }
     2747  return result;
     2748};
     2749
     2750
     2751/** Sort function for the candidate list.
     2752 */
     2753bool SortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2)
     2754{
     2755  Vector BaseLineVector, OrthogonalVector, helper;
     2756  if (candidate1->BaseLine != candidate2->BaseLine) {  // sanity check
     2757    cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl;
     2758    //return false;
     2759    exit(1);
     2760  }
     2761  // create baseline vector
     2762  BaseLineVector.CopyVector(candidate1->BaseLine->endpoints[1]->node->node);
     2763  BaseLineVector.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);
     2764  BaseLineVector.Normalize();
     2765
     2766  // create normal in-plane vector to cope with acos() non-uniqueness on [0,2pi] (note that is pointing in the "right" direction already, hence ">0" test!)
     2767  helper.CopyVector(candidate1->BaseLine->endpoints[0]->node->node);
     2768  helper.SubtractVector(candidate1->point->node);
     2769  OrthogonalVector.CopyVector(&helper);
     2770  helper.VectorProduct(&BaseLineVector);
     2771  OrthogonalVector.SubtractVector(&helper);
     2772  OrthogonalVector.Normalize();
     2773
     2774  // calculate both angles and correct with in-plane vector
     2775  helper.CopyVector(candidate1->point->node);
     2776  helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);
     2777  double phi = BaseLineVector.Angle(&helper);
     2778  if (OrthogonalVector.ScalarProduct(&helper) > 0) {
     2779    phi = 2.*M_PI - phi;
     2780  }
     2781  helper.CopyVector(candidate2->point->node);
     2782  helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);
     2783  double psi = BaseLineVector.Angle(&helper);
     2784  if (OrthogonalVector.ScalarProduct(&helper) > 0) {
     2785    psi = 2.*M_PI - psi;
     2786  }
     2787
     2788  cout << Verbose(2) << *candidate1->point << " has angle " << phi << endl;
     2789  cout << Verbose(2) << *candidate2->point << " has angle " << psi << endl;
     2790
     2791  // return comparison
     2792  return phi < psi;
     2793};
     2794
     2795/**
     2796 * Finds the point which is second closest to the provided one.
     2797 *
     2798 * @param Point to which to find the second closest other point
     2799 * @param linked cell structure
     2800 *
     2801 * @return point which is second closest to the provided one
     2802 */
     2803TesselPoint* FindSecondClosestPoint(const Vector* Point, LinkedCell* LC)
     2804{
     2805  LinkedNodes *List = NULL;
     2806  TesselPoint* closestPoint = NULL;
     2807  TesselPoint* secondClosestPoint = NULL;
     2808  double distance = 1e16;
     2809  double secondDistance = 1e16;
     2810  Vector helper;
     2811  int N[NDIM], Nlower[NDIM], Nupper[NDIM];
     2812
     2813  LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly
     2814  for(int i=0;i<NDIM;i++) // store indices of this cell
     2815    N[i] = LC->n[i];
     2816  cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;
     2817
     2818  LC->GetNeighbourBounds(Nlower, Nupper);
     2819  //cout << endl;
     2820  for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
     2821    for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
     2822      for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
     2823        List = LC->GetCurrentCell();
     2824        cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;
     2825        if (List != NULL) {
     2826          for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     2827            helper.CopyVector(Point);
     2828            helper.SubtractVector((*Runner)->node);
     2829            double currentNorm = helper. Norm();
     2830            if (currentNorm < distance) {
     2831              // remember second point
     2832              secondDistance = distance;
     2833              secondClosestPoint = closestPoint;
     2834              // mark down new closest point
     2835              distance = currentNorm;
     2836              closestPoint = (*Runner);
     2837              cout << Verbose(2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl;
    30772838            }
    3078         }
    3079         MiddleNode = EndNode;
    3080         if (MiddleNode == connectedPath->end()) {
    3081           cout << Verbose(1) << "CRITICAL: Could not find a smallest angle!" << endl;
    3082           exit(255);
    3083         }
    3084         StartNode = MiddleNode;
    3085         if (StartNode == connectedPath->begin())
    3086           StartNode = connectedPath->end();
    3087         StartNode--;
    3088         EndNode++;
    3089         if (EndNode == connectedPath->end())
    3090           EndNode = connectedPath->begin();
    3091         cout << Verbose(4) << "INFO: StartNode is " << **StartNode << "." << endl;
    3092         cout << Verbose(4) << "INFO: MiddleNode is " << **MiddleNode << "." << endl;
    3093         cout << Verbose(4) << "INFO: EndNode is " << **EndNode << "." << endl;
    3094         *out << Verbose(3) << "INFO: Attempting to create triangle " << (*StartNode)->Name << ", " << (*MiddleNode)->Name << " and " << (*EndNode)->Name << "." << endl;
    3095         TriangleCandidates[0] = *StartNode;
    3096         TriangleCandidates[1] = *MiddleNode;
    3097         TriangleCandidates[2] = *EndNode;
    3098         triangle = GetPresentTriangle(out, TriangleCandidates);
    3099         if (triangle != NULL) {
    3100           cout << Verbose(1) << "WARNING: New triangle already present, skipping!" << endl;
    3101           StartNode++;
    3102           MiddleNode++;
    3103           EndNode++;
    3104           if (StartNode == connectedPath->end())
    3105             StartNode = connectedPath->begin();
    3106           if (MiddleNode == connectedPath->end())
    3107             MiddleNode = connectedPath->begin();
    3108           if (EndNode == connectedPath->end())
    3109             EndNode = connectedPath->begin();
    3110           continue;
    3111         }
    3112         *out << Verbose(5) << "Adding new triangle points."<< endl;
    3113         AddTesselationPoint(*StartNode, 0);
    3114         AddTesselationPoint(*MiddleNode, 1);
    3115         AddTesselationPoint(*EndNode, 2);
    3116         *out << Verbose(5) << "Adding new triangle lines."<< endl;
    3117         AddTesselationLine(TPS[0], TPS[1], 0);
    3118         AddTesselationLine(TPS[0], TPS[2], 1);
    3119         NewLines.push_back(BLS[1]);
    3120         AddTesselationLine(TPS[1], TPS[2], 2);
    3121         BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    3122         BTS->GetNormalVector(NormalVector);
    3123         AddTesselationTriangle();
    3124         // calculate volume summand as a general tetraeder
    3125         volume += CalculateVolumeofGeneralTetraeder(TPS[0]->node->node, TPS[1]->node->node, TPS[2]->node->node, &OldPoint);
    3126         // advance number
    3127         count++;
    3128 
    3129         // prepare nodes for next triangle
    3130         StartNode = EndNode;
    3131         cout << Verbose(4) << "Removing " << **MiddleNode << " from closed path, remaining points: " << connectedPath->size() << "." << endl;
    3132         connectedPath->remove(*MiddleNode); // remove the middle node (it is surrounded by triangles)
    3133         if (connectedPath->size() == 2) { // we are done
    3134           connectedPath->remove(*StartNode); // remove the start node
    3135           connectedPath->remove(*EndNode); // remove the end node
    3136           break;
    3137         } else if (connectedPath->size() < 2) { // something's gone wrong!
    3138           cout << Verbose(1) << "CRITICAL: There are only two endpoints left!" << endl;
    3139           exit(255);
     2839          }
    31402840        } else {
    3141           MiddleNode = StartNode;
    3142           MiddleNode++;
    3143           if (MiddleNode == connectedPath->end())
    3144             MiddleNode = connectedPath->begin();
    3145           EndNode = MiddleNode;
    3146           EndNode++;
    3147           if (EndNode == connectedPath->end())
    3148             EndNode = connectedPath->begin();
     2841          cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << ","
     2842            << LC->n[2] << " is invalid!" << endl;
    31492843        }
    31502844      }
    3151       // maximize the inner lines (we preferentially created lines with a huge angle, which is for the tesselation not wanted though useful for the closing)
    3152       if (NewLines.size() > 1) {
    3153         list<class BoundaryLineSet *>::iterator Candidate;
    3154         class BoundaryLineSet *OtherBase = NULL;
    3155         double tmp, maxgain;
    3156         do {
    3157           maxgain = 0;
    3158           for(list<class BoundaryLineSet *>::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) {
    3159             tmp = PickFarthestofTwoBaselines(out, *Runner);
    3160             if (maxgain < tmp) {
    3161               maxgain = tmp;
    3162               Candidate = Runner;
     2845
     2846  return secondClosestPoint;
     2847};
     2848
     2849/**
     2850 * Finds the point which is closest to the provided one.
     2851 *
     2852 * @param Point to which to find the closest other point
     2853 * @param SecondPoint the second closest other point on return, NULL if none found
     2854 * @param linked cell structure
     2855 *
     2856 * @return point which is closest to the provided one, NULL if none found
     2857 */
     2858TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC)
     2859{
     2860  LinkedNodes *List = NULL;
     2861  TesselPoint* closestPoint = NULL;
     2862  SecondPoint = NULL;
     2863  double distance = 1e16;
     2864  double secondDistance = 1e16;
     2865  Vector helper;
     2866  int N[NDIM], Nlower[NDIM], Nupper[NDIM];
     2867
     2868  LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly
     2869  for(int i=0;i<NDIM;i++) // store indices of this cell
     2870    N[i] = LC->n[i];
     2871  cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;
     2872
     2873  LC->GetNeighbourBounds(Nlower, Nupper);
     2874  //cout << endl;
     2875  for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)
     2876    for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)
     2877      for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {
     2878        List = LC->GetCurrentCell();
     2879        cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;
     2880        if (List != NULL) {
     2881          for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {
     2882            helper.CopyVector(Point);
     2883            helper.SubtractVector((*Runner)->node);
     2884            double currentNorm = helper. Norm();
     2885            if (currentNorm < distance) {
     2886              secondDistance = distance;
     2887              SecondPoint = closestPoint;
     2888              distance = currentNorm;
     2889              closestPoint = (*Runner);
     2890              cout << Verbose(2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl;
     2891            } else if (currentNorm < secondDistance) {
     2892              secondDistance = currentNorm;
     2893              SecondPoint = (*Runner);
     2894              cout << Verbose(2) << "INFO: New Second Nearest Neighbour is " << *SecondPoint << "." << endl;
    31632895            }
    31642896          }
    3165           if (maxgain != 0) {
    3166             volume += maxgain;
    3167             cout << Verbose(3) << "Flipping baseline with highest volume" << **Candidate << "." << endl;
    3168             OtherBase = FlipBaseline(out, *Candidate);
    3169             NewLines.erase(Candidate);
    3170             NewLines.push_back(OtherBase);
    3171           }
    3172         } while (maxgain != 0.);
     2897        } else {
     2898          cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << ","
     2899            << LC->n[2] << " is invalid!" << endl;
     2900        }
    31732901      }
    31742902
    3175       ListOfClosedPaths->remove(connectedPath);
    3176       delete(connectedPath);
    3177     }
    3178     *out << Verbose(1) << count << " triangles were created." << endl;
    3179   } else {
    3180     while (!ListOfClosedPaths->empty()) {
    3181       ListRunner = ListOfClosedPaths->begin();
    3182       connectedPath = *ListRunner;
    3183       ListOfClosedPaths->remove(connectedPath);
    3184       delete(connectedPath);
    3185     }
    3186     *out << Verbose(1) << "No need to create any triangles." << endl;
    3187   }
    3188   delete(ListOfClosedPaths);
    3189 
    3190   *out << Verbose(1) << "Removed volume is " << volume << "." << endl;
    3191 
    3192   return volume;
    3193 };
    3194 
    3195 
     2903  return closestPoint;
     2904};
    31962905
    31972906/**
     
    32302939              FindTriangle = FindLine->second->triangles.begin();
    32312940              for (; FindTriangle != FindLine->second->triangles.end(); FindTriangle++) {
    3232                 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) {
     2941                if ((
     2942                  (FindTriangle->second->endpoints[0] == TrianglePoints[0])
     2943                    || (FindTriangle->second->endpoints[0] == TrianglePoints[1])
     2944                    || (FindTriangle->second->endpoints[0] == TrianglePoints[2])
     2945                  ) && (
     2946                    (FindTriangle->second->endpoints[1] == TrianglePoints[0])
     2947                    || (FindTriangle->second->endpoints[1] == TrianglePoints[1])
     2948                    || (FindTriangle->second->endpoints[1] == TrianglePoints[2])
     2949                  ) && (
     2950                    (FindTriangle->second->endpoints[2] == TrianglePoints[0])
     2951                    || (FindTriangle->second->endpoints[2] == TrianglePoints[1])
     2952                    || (FindTriangle->second->endpoints[2] == TrianglePoints[2])
     2953                  )
     2954                ) {
    32332955                  result->push_back(FindTriangle->second);
    32342956                }
     
    32482970
    32492971/**
    3250  * Finds all degenerated lines within the tesselation structure.
    3251  *
    3252  * @return map of keys of degenerated line pairs, each line occurs twice
    3253  *         in the list, once as key and once as value
    3254  */
    3255 map<int, int> * Tesselation::FindAllDegeneratedLines()
    3256 {
    3257   map<int, class BoundaryLineSet *> AllLines;
    3258   map<int, int> * DegeneratedLines = new map<int, int>;
    3259 
    3260   // sanity check
    3261   if (LinesOnBoundary.empty()) {
    3262     cout << Verbose(1) << "Warning: FindAllDegeneratedTriangles() was called without any tesselation structure.";
    3263     return DegeneratedLines;
    3264   }
    3265 
    3266   LineMap::iterator LineRunner1;
    3267   pair<LineMap::iterator, bool> tester;
    3268   for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) {
    3269     tester = AllLines.insert( pair<int,BoundaryLineSet *> (LineRunner1->second->endpoints[0]->Nr, LineRunner1->second) );
    3270     if ((!tester.second) && (tester.first->second->endpoints[1]->Nr == LineRunner1->second->endpoints[1]->Nr)) { // found degenerated line
    3271       DegeneratedLines->insert ( pair<int, int> (LineRunner1->second->Nr, tester.first->second->Nr) );
    3272       DegeneratedLines->insert ( pair<int, int> (tester.first->second->Nr, LineRunner1->second->Nr) );
    3273     }
    3274   }
    3275 
    3276   AllLines.clear();
    3277 
    3278   cout << Verbose(1) << "FindAllDegeneratedLines() found " << DegeneratedLines->size() << " lines." << endl;
    3279   map<int,int>::iterator it;
    3280   for (it = DegeneratedLines->begin(); it != DegeneratedLines->end(); it++)
    3281       cout << Verbose(2) << (*it).first << " => " << (*it).second << endl;
    3282 
    3283   return DegeneratedLines;
    3284 }
    3285 
    3286 /**
    32872972 * Finds all degenerated triangles within the tesselation structure.
    32882973 *
     
    32902975 *         in the list, once as key and once as value
    32912976 */
    3292 map<int, int> * Tesselation::FindAllDegeneratedTriangles()
    3293 {
    3294   map<int, int> * DegeneratedLines = FindAllDegeneratedLines();
    3295   map<int, int> * DegeneratedTriangles = new map<int, int>;
    3296 
    3297   TriangleMap::iterator TriangleRunner1, TriangleRunner2;
    3298   LineMap::iterator Liner;
    3299   class BoundaryLineSet *line1 = NULL, *line2 = NULL;
    3300 
    3301   for (map<int, int>::iterator LineRunner = DegeneratedLines->begin(); LineRunner != DegeneratedLines->end(); ++LineRunner) {
    3302     // run over both lines' triangles
    3303     Liner = LinesOnBoundary.find(LineRunner->first);
    3304     if (Liner != LinesOnBoundary.end())
    3305       line1 = Liner->second;
    3306     Liner = LinesOnBoundary.find(LineRunner->second);
    3307     if (Liner != LinesOnBoundary.end())
    3308       line2 = Liner->second;
    3309     for (TriangleRunner1 = line1->triangles.begin(); TriangleRunner1 != line1->triangles.end(); ++TriangleRunner1) {
    3310       for (TriangleRunner2 = line2->triangles.begin(); TriangleRunner2 != line2->triangles.end(); ++TriangleRunner2) {
    3311         if ((TriangleRunner1->second != TriangleRunner2->second)
    3312           && (TriangleRunner1->second->IsPresentTupel(TriangleRunner2->second))) {
    3313           DegeneratedTriangles->insert( pair<int, int> (TriangleRunner1->second->Nr, TriangleRunner2->second->Nr) );
    3314           DegeneratedTriangles->insert( pair<int, int> (TriangleRunner2->second->Nr, TriangleRunner1->second->Nr) );
     2977map<int, int> Tesselation::FindAllDegeneratedTriangles()
     2978{
     2979  map<int, int> DegeneratedTriangles;
     2980
     2981  // sanity check
     2982  if (LinesOnBoundary.empty()) {
     2983    cout << Verbose(1) << "Warning: FindAllDegeneratedTriangles() was called without any tesselation structure.";
     2984    return DegeneratedTriangles;
     2985  }
     2986
     2987  LineMap::iterator LineRunner1, LineRunner2;
     2988
     2989  for (LineRunner1 = LinesOnBoundary.begin(); LineRunner1 != LinesOnBoundary.end(); ++LineRunner1) {
     2990    for (LineRunner2 = LinesOnBoundary.begin(); LineRunner2 != LinesOnBoundary.end(); ++LineRunner2) {
     2991      if ((LineRunner1->second != LineRunner2->second)
     2992        && (LineRunner1->second->endpoints[0] == LineRunner2->second->endpoints[0])
     2993        && (LineRunner1->second->endpoints[1] == LineRunner2->second->endpoints[1])
     2994      ) {
     2995        TriangleMap::iterator TriangleRunner1 = LineRunner1->second->triangles.begin(),
     2996          TriangleRunner2 = LineRunner2->second->triangles.begin();
     2997
     2998        for (; TriangleRunner1 != LineRunner1->second->triangles.end(); ++TriangleRunner1) {
     2999          for (; TriangleRunner2 != LineRunner2->second->triangles.end(); ++TriangleRunner2) {
     3000            if ((TriangleRunner1->second != TriangleRunner2->second)
     3001              && (TriangleRunner1->second->endpoints[0] == TriangleRunner2->second->endpoints[0])
     3002              && (TriangleRunner1->second->endpoints[1] == TriangleRunner2->second->endpoints[1])
     3003              && (TriangleRunner1->second->endpoints[2] == TriangleRunner2->second->endpoints[2])
     3004            ) {
     3005              DegeneratedTriangles[TriangleRunner1->second->Nr] = TriangleRunner2->second->Nr;
     3006              DegeneratedTriangles[TriangleRunner2->second->Nr] = TriangleRunner1->second->Nr;
     3007            }
     3008          }
    33153009        }
    33163010      }
    33173011    }
    33183012  }
    3319   delete(DegeneratedLines);
    3320 
    3321   cout << Verbose(1) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl;
     3013
     3014  cout << Verbose(1) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles.size() << " triangles." << endl;
    33223015  map<int,int>::iterator it;
    3323   for (it = DegeneratedTriangles->begin(); it != DegeneratedTriangles->end(); it++)
     3016  for (it = DegeneratedTriangles.begin(); it != DegeneratedTriangles.end(); it++)
    33243017      cout << Verbose(2) << (*it).first << " => " << (*it).second << endl;
    33253018
     
    33333026void Tesselation::RemoveDegeneratedTriangles()
    33343027{
    3335   map<int, int> * DegeneratedTriangles = FindAllDegeneratedTriangles();
    3336   TriangleMap::iterator finder;
    3337   BoundaryTriangleSet *triangle = NULL, *partnerTriangle = NULL;
    3338   int count  = 0;
    3339 
    3340   cout << Verbose(1) << "Begin of RemoveDegeneratedTriangles" << endl;
    3341 
    3342   for (map<int, int>::iterator TriangleKeyRunner = DegeneratedTriangles->begin();
    3343     TriangleKeyRunner != DegeneratedTriangles->end(); ++TriangleKeyRunner
     3028  map<int, int> DegeneratedTriangles = FindAllDegeneratedTriangles();
     3029
     3030  for (map<int, int>::iterator TriangleKeyRunner = DegeneratedTriangles.begin();
     3031    TriangleKeyRunner != DegeneratedTriangles.end(); ++TriangleKeyRunner
    33443032  ) {
    3345     finder = TrianglesOnBoundary.find(TriangleKeyRunner->first);
    3346     if (finder != TrianglesOnBoundary.end())
    3347       triangle = finder->second;
    3348     else
    3349       break;
    3350     finder = TrianglesOnBoundary.find(TriangleKeyRunner->second);
    3351     if (finder != TrianglesOnBoundary.end())
    3352       partnerTriangle = finder->second;
    3353     else
    3354       break;
     3033    BoundaryTriangleSet *triangle = TrianglesOnBoundary.find(TriangleKeyRunner->first)->second,
     3034      *partnerTriangle = TrianglesOnBoundary.find(TriangleKeyRunner->second)->second;
    33553035
    33563036    bool trianglesShareLine = false;
     
    33643044      && (triangle->endpoints[0]->LinesCount > 2)
    33653045    ) {
    3366       // check whether we have to fix lines
    3367       BoundaryTriangleSet *Othertriangle = NULL;
    3368       BoundaryTriangleSet *OtherpartnerTriangle = NULL;
    3369       TriangleMap::iterator TriangleRunner;
    3370       for (int i = 0; i < 3; ++i)
    3371         for (int j = 0; j < 3; ++j)
    3372           if (triangle->lines[i] != partnerTriangle->lines[j]) {
    3373             // get the other two triangles
    3374             for (TriangleRunner = triangle->lines[i]->triangles.begin(); TriangleRunner != triangle->lines[i]->triangles.end(); ++TriangleRunner)
    3375               if (TriangleRunner->second != triangle) {
    3376                 Othertriangle = TriangleRunner->second;
    3377               }
    3378             for (TriangleRunner = partnerTriangle->lines[i]->triangles.begin(); TriangleRunner != partnerTriangle->lines[i]->triangles.end(); ++TriangleRunner)
    3379               if (TriangleRunner->second != partnerTriangle) {
    3380                 OtherpartnerTriangle = TriangleRunner->second;
    3381               }
    3382             /// interchanges their lines so that triangle->lines[i] == partnerTriangle->lines[j]
    3383             // the line of triangle receives the degenerated ones
    3384             triangle->lines[i]->triangles.erase(Othertriangle->Nr);
    3385             triangle->lines[i]->triangles.insert( TrianglePair( partnerTriangle->Nr, partnerTriangle) );
    3386             for (int k=0;k<3;k++)
    3387               if (triangle->lines[i] == Othertriangle->lines[k]) {
    3388                 Othertriangle->lines[k] = partnerTriangle->lines[j];
    3389                 break;
    3390               }
    3391             // the line of partnerTriangle receives the non-degenerated ones
    3392             partnerTriangle->lines[j]->triangles.erase( partnerTriangle->Nr);
    3393             partnerTriangle->lines[j]->triangles.insert( TrianglePair( Othertriangle->Nr, Othertriangle) );
    3394             partnerTriangle->lines[j] = triangle->lines[i];
    3395           }
    3396 
    3397       // erase the pair
    3398       count += (int) DegeneratedTriangles->erase(triangle->Nr);
    33993046      cout << Verbose(1) << "RemoveDegeneratedTriangles() removes triangle " << *triangle << "." << endl;
    34003047      RemoveTesselationTriangle(triangle);
    3401       count += (int) DegeneratedTriangles->erase(partnerTriangle->Nr);
    34023048      cout << Verbose(1) << "RemoveDegeneratedTriangles() removes triangle " << *partnerTriangle << "." << endl;
    34033049      RemoveTesselationTriangle(partnerTriangle);
     3050      DegeneratedTriangles.erase(DegeneratedTriangles.find(partnerTriangle->Nr));
    34043051    } else {
    34053052      cout << Verbose(1) << "RemoveDegeneratedTriangles() does not remove triangle " << *triangle
     
    34083055    }
    34093056  }
    3410   delete(DegeneratedTriangles);
    3411 
    3412   cout << Verbose(1) << "RemoveDegeneratedTriangles() removed " << count << " triangles:" << endl;
    3413   cout << Verbose(1) << "End of RemoveDegeneratedTriangles" << endl;
    34143057}
    34153058
    3416 /** Adds an outside Tesselpoint to the envelope via (two) degenerated triangles.
    3417  * We look for the closest point on the boundary, we look through its connected boundary lines and
    3418  * seek the one with the minimum angle between its center point and the new point and this base line.
    3419  * We open up the line by adding a degenerated triangle, whose other side closes the base line again.
    3420  * \param *out output stream for debugging
    3421  * \param *point point to add
    3422  * \param *LC Linked Cell structure to find nearest point
    3423  */
    3424 void Tesselation::AddBoundaryPointByDegeneratedTriangle(ofstream *out, class TesselPoint *point, LinkedCell *LC)
    3425 {
    3426   *out << Verbose(2) << "Begin of AddBoundaryPointByDegeneratedTriangle" << endl;
    3427 
    3428   // find nearest boundary point
    3429   class TesselPoint *BackupPoint = NULL;
    3430   class TesselPoint *NearestPoint = FindClosestPoint(point->node, BackupPoint, LC);
    3431   class BoundaryPointSet *NearestBoundaryPoint = NULL;
    3432   PointMap::iterator PointRunner;
    3433 
    3434   if (NearestPoint == point)
    3435     NearestPoint = BackupPoint;
    3436   PointRunner = PointsOnBoundary.find(NearestPoint->nr);
    3437   if (PointRunner != PointsOnBoundary.end()) {
    3438     NearestBoundaryPoint = PointRunner->second;
    3439   } else {
    3440     *out << Verbose(1) << "ERROR: I cannot find the boundary point." << endl;
    3441     return;
    3442   }
    3443   *out << Verbose(2) << "Nearest point on boundary is " << NearestPoint->Name << "." << endl;
    3444 
    3445   // go through its lines and find the best one to split
    3446   Vector CenterToPoint;
    3447   Vector BaseLine;
    3448   double angle, BestAngle = 0.;
    3449   class BoundaryLineSet *BestLine = NULL;
    3450   for (LineMap::iterator Runner = NearestBoundaryPoint->lines.begin(); Runner != NearestBoundaryPoint->lines.end(); Runner++) {
    3451     BaseLine.CopyVector(Runner->second->endpoints[0]->node->node);
    3452     BaseLine.SubtractVector(Runner->second->endpoints[1]->node->node);
    3453     CenterToPoint.CopyVector(Runner->second->endpoints[0]->node->node);
    3454     CenterToPoint.AddVector(Runner->second->endpoints[1]->node->node);
    3455     CenterToPoint.Scale(0.5);
    3456     CenterToPoint.SubtractVector(point->node);
    3457     angle = CenterToPoint.Angle(&BaseLine);
    3458     if (fabs(angle - M_PI/2.) < fabs(BestAngle - M_PI/2.)) {
    3459       BestAngle = angle;
    3460       BestLine = Runner->second;
    3461     }
    3462   }
    3463 
    3464   // remove one triangle from the chosen line
    3465   class BoundaryTriangleSet *TempTriangle = (BestLine->triangles.begin())->second;
    3466   BestLine->triangles.erase(TempTriangle->Nr);
    3467   int nr = -1;
    3468   for (int i=0;i<3; i++) {
    3469     if (TempTriangle->lines[i] == BestLine) {
    3470       nr = i;
    3471       break;
    3472     }
    3473   }
    3474 
    3475   // create new triangle to connect point (connects automatically with the missing spot of the chosen line)
    3476   *out << Verbose(5) << "Adding new triangle points."<< endl;
    3477   AddTesselationPoint((BestLine->endpoints[0]->node), 0);
    3478   AddTesselationPoint((BestLine->endpoints[1]->node), 1);
    3479   AddTesselationPoint(point, 2);
    3480   *out << Verbose(5) << "Adding new triangle lines."<< endl;
    3481   AddTesselationLine(TPS[0], TPS[1], 0);
    3482   AddTesselationLine(TPS[0], TPS[2], 1);
    3483   AddTesselationLine(TPS[1], TPS[2], 2);
    3484   BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    3485   BTS->GetNormalVector(TempTriangle->NormalVector);
    3486   BTS->NormalVector.Scale(-1.);
    3487   *out << Verbose(3) << "INFO: NormalVector of new triangle is " << BTS->NormalVector << "." << endl;
    3488   AddTesselationTriangle();
    3489 
    3490   // create other side of this triangle and close both new sides of the first created triangle
    3491   *out << Verbose(5) << "Adding new triangle points."<< endl;
    3492   AddTesselationPoint((BestLine->endpoints[0]->node), 0);
    3493   AddTesselationPoint((BestLine->endpoints[1]->node), 1);
    3494   AddTesselationPoint(point, 2);
    3495   *out << Verbose(5) << "Adding new triangle lines."<< endl;
    3496   AddTesselationLine(TPS[0], TPS[1], 0);
    3497   AddTesselationLine(TPS[0], TPS[2], 1);
    3498   AddTesselationLine(TPS[1], TPS[2], 2);
    3499   BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    3500   BTS->GetNormalVector(TempTriangle->NormalVector);
    3501   *out << Verbose(3) << "INFO: NormalVector of other new triangle is " << BTS->NormalVector << "." << endl;
    3502   AddTesselationTriangle();
    3503 
    3504   // add removed triangle to the last open line of the second triangle
    3505   for (int i=0;i<3;i++) { // look for the same line as BestLine (only it's its degenerated companion)
    3506     if ((BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[0])) && (BTS->lines[i]->ContainsBoundaryPoint(BestLine->endpoints[1]))) {
    3507       if (BestLine == BTS->lines[i]){
    3508         *out << Verbose(1) << "CRITICAL: BestLine is same as found line, something's wrong here!" << endl;
    3509         exit(255);
    3510       }
    3511       BTS->lines[i]->triangles.insert( pair<int, class BoundaryTriangleSet *> (TempTriangle->Nr, TempTriangle) );
    3512       TempTriangle->lines[nr] = BTS->lines[i];
    3513       break;
    3514     }
    3515   }
    3516 
    3517   // exit
    3518   *out << Verbose(2) << "End of AddBoundaryPointByDegeneratedTriangle" << endl;
    3519 };
    3520 
    3521 /** Writes the envelope to file.
    3522  * \param *out otuput stream for debugging
    3523  * \param *filename basename of output file
    3524  * \param *cloud PointCloud structure with all nodes
    3525  */
    3526 void Tesselation::Output(ofstream *out, const char *filename, PointCloud *cloud)
    3527 {
    3528   ofstream *tempstream = NULL;
    3529   string NameofTempFile;
    3530   char NumberName[255];
    3531 
    3532   if (LastTriangle != NULL) {
    3533     sprintf(NumberName, "-%04d-%s_%s_%s", (int)TrianglesOnBoundary.size(), LastTriangle->endpoints[0]->node->Name, LastTriangle->endpoints[1]->node->Name, LastTriangle->endpoints[2]->node->Name);
    3534     if (DoTecplotOutput) {
    3535       string NameofTempFile(filename);
    3536       NameofTempFile.append(NumberName);
    3537       for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos))
    3538       NameofTempFile.erase(npos, 1);
    3539       NameofTempFile.append(TecplotSuffix);
    3540       *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
    3541       tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
    3542       WriteTecplotFile(out, tempstream, this, cloud, TriangleFilesWritten);
    3543       tempstream->close();
    3544       tempstream->flush();
    3545       delete(tempstream);
    3546     }
    3547 
    3548     if (DoRaster3DOutput) {
    3549       string NameofTempFile(filename);
    3550       NameofTempFile.append(NumberName);
    3551       for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos))
    3552       NameofTempFile.erase(npos, 1);
    3553       NameofTempFile.append(Raster3DSuffix);
    3554       *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";
    3555       tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);
    3556       WriteRaster3dFile(out, tempstream, this, cloud);
    3557       IncludeSphereinRaster3D(out, tempstream, this, cloud);
    3558       tempstream->close();
    3559       tempstream->flush();
    3560       delete(tempstream);
    3561     }
    3562   }
    3563   if (DoTecplotOutput || DoRaster3DOutput)
    3564     TriangleFilesWritten++;
    3565 };
     3059/** Gets the angle between a point and a reference relative to the provided center.
     3060 * We have two shanks point and reference between which the angle is calculated
     3061 * and by scalar product with OrthogonalVector we decide the interval.
     3062 * @param point to calculate the angle for
     3063 * @param reference to which to calculate the angle
     3064 * @param OrthogonalVector points in direction of [pi,2pi] interval
     3065 *
     3066 * @return angle between point and reference
     3067 */
     3068double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector)
     3069{
     3070  if (reference.IsZero())
     3071    return M_PI;
     3072
     3073  // calculate both angles and correct with in-plane vector
     3074  if (point.IsZero())
     3075    return M_PI;
     3076  double phi = point.Angle(&reference);
     3077  if (OrthogonalVector.ScalarProduct(&point) > 0) {
     3078    phi = 2.*M_PI - phi;
     3079  }
     3080
     3081  cout << Verbose(3) << "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << "." << endl;
     3082
     3083  return phi;
     3084}
     3085
Note: See TracChangeset for help on using the changeset viewer.