Changeset f07f86d


Ignore:
Timestamp:
Apr 20, 2010, 10:34:43 AM (15 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
b60a29
Parents:
061b06
git-author:
Frederik Heber <heber@…> (04/20/10 09:26:30)
git-committer:
Frederik Heber <heber@…> (04/20/10 10:34:43)
Message:

Rewrite of tesselation procedure: treatment of degenerated triangles.

The central idea is that when matching open lines are present, then we have to check whether candidate matches desired ThirdPoint and that the calculated OptCenter matches as well. The latter is essential for degenerated triangles, that can only be decerned by their (Other)OptCenter.

Asparagine is now tesselated correctly from radius 1.5 up to 25.

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/tesselation.cpp

    r061b06 rf07f86d  
    654654};
    655655
    656 /** Checks validity of a given sphere of a candidate line.
    657  * \sa CandidateForTesselation::CheckValidity(), which is more evolved.
    658  * \param *OtherOptCenter center of the other triangle
    659  * \param RADIUS radius of sphere
    660  * \param *LC LinkedCell structure with other atoms
    661  * \return true - candidate triangle is degenerated, false - candidate triangle is not degenerated
    662  */
    663 bool BoundaryTriangleSet::CheckDegeneracy(Vector *OtherOptCenter, const double RADIUS, const LinkedCell *LC) const
    664 {
    665   Info FunctionInfo(__func__);
    666 
    667   DoLog(1) && (Log() << Verbose(1) << "INFO: Checking whether sphere contains no others points ..." << endl);
    668   bool flag = true;
    669 
    670   // get all points inside the sphere
    671   TesselPointList *ListofPoints = LC->GetPointsInsideSphere(RADIUS, OtherOptCenter);
    672 
    673   // remove triangles's endpoints
    674   for (int i=0;i<3;i++)
    675     ListofPoints->remove(endpoints[i]->node);
    676 
    677   // check for other points
    678   if (!ListofPoints->empty()) {
    679     Log() << Verbose(1) << "CheckValidity: There are still " << ListofPoints->size() << " points inside the sphere." << endl;
    680     flag = false;
    681     Log() << Verbose(1) << "External atoms inside of sphere at " << *OtherOptCenter << ":" << endl;
    682     for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
    683       Log() << Verbose(1) << "  " << *(*Runner) << " with distance " << (*Runner)->node->Distance(OtherOptCenter) << "." << endl;
    684   }
    685   delete(ListofPoints);
    686 
    687   return flag;
    688 };
    689 
    690 
    691 
    692656/** Returns the endpoint which is not contained in the given \a *line.
    693657 * \param *line baseline defining two endpoints
     
    10781042  Info FunctionInfo(__func__);
    10791043
    1080   const double radiusSquared = RADIUS;
     1044  const double radiusSquared = RADIUS*RADIUS;
    10811045  list<const Vector *> VectorList;
    10821046  VectorList.push_back(&OptCenter);
     
    10891053  // check baseline for OptCenter and OtherOptCenter being on sphere's surface
    10901054  for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) {
    1091     for (int i=0;i<2;i++)
    1092       if (fabs((*VRunner)->DistanceSquared(BaseLine->endpoints[i]->node->node) - radiusSquared) < MYEPSILON) {
    1093         DoeLog(1) && (eLog() << Verbose(1) << "Endpoint " << BaseLine->endpoints[i] << " is out of sphere at " << *(*VRunner) << "." << endl);
     1055    for (int i=0;i<2;i++) {
     1056      const double distance = fabs((*VRunner)->DistanceSquared(BaseLine->endpoints[i]->node->node) - radiusSquared);
     1057      if (distance > HULLEPSILON) {
     1058        DoeLog(1) && (eLog() << Verbose(1) << "Endpoint " << *BaseLine->endpoints[i] << " is out of sphere at " << *(*VRunner) << " by " << setprecision(13) << distance << "." << endl);
    10941059        return false;
    10951060      }
     1061    }
    10961062  }
    10971063
     
    11001066    const TesselPoint *Walker = *Runner;
    11011067    for (list<const Vector *>::const_iterator VRunner = VectorList.begin(); VRunner != VectorList.end(); ++VRunner) {
    1102       if (fabs((*VRunner)->DistanceSquared(Walker->node) - radiusSquared) < MYEPSILON) {
    1103         DoeLog(1) && (eLog() << Verbose(1) << "Candidate " << Walker << " is out of sphere at " << *(*VRunner) << "." << endl);
     1068      const double distance = fabs((*VRunner)->DistanceSquared(Walker->node) - radiusSquared);
     1069      if (distance > HULLEPSILON) {
     1070        DoeLog(1) && (eLog() << Verbose(1) << "Candidate " << Walker << " is out of sphere at " << *(*VRunner) << " by " << setprecision(13) << distance << "." << endl);
    11041071        return false;
    11051072      }
     
    18271794 * If successful it raises the line count and inserts the new line into the BLS,
    18281795 * if unsuccessful, it writes the line which had been present into the BLS, deleting the new constructed one.
     1796 * @param *OptCenter desired OptCenter if there are more than one candidate line
    18291797 * @param *candidate third point of the triangle to be, for checking between multiple open line candidates
    18301798 * @param *a first endpoint
     
    18321800 * @param n index of Tesselation::BLS giving the line with both endpoints
    18331801 */
    1834 void Tesselation::AddTesselationLine(const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) {
     1802void Tesselation::AddTesselationLine(const Vector * const OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n) {
    18351803  bool insertNewLine = true;
    18361804
     
    18471815      // If there is a line with less than two attached triangles, we don't need a new line.
    18481816      if (FindLine->second->triangles.size() == 1) {
     1817        CandidateMap::iterator Finder = OpenLines.find(FindLine->second);
     1818        if (!Finder->second->pointlist.empty())
     1819          Log() << Verbose(1) << "INFO: line " << *(FindLine->second) << " is open with candidate " << **(Finder->second->pointlist.begin()) << "." << endl;
     1820        else
     1821          Log() << Verbose(1) << "INFO: line " << *(FindLine->second) << " is open with no candidate." << endl;
    18491822        // get open line
    1850         CandidateMap::iterator Finder = OpenLines.find(FindLine->second);
    1851         insertNewLine = false;
    1852         WinningLine = FindLine->second;
    1853         if ((!Finder->second->pointlist.empty()) && (*(Finder->second->pointlist.begin()) == candidate->node)) { // stop searching if candidate matches
     1823        if ((!Finder->second->pointlist.empty()) && (*(Finder->second->pointlist.begin()) == candidate->node)
     1824            && (OptCenter == NULL || *OptCenter == Finder->second->OptCenter)) { // stop searching if candidate matches
     1825          insertNewLine = false;
     1826          WinningLine = FindLine->second;
    18541827          break;
    18551828        }
     
    20632036};
    20642037
     2038
     2039/** Checks validity of a given sphere of a candidate line.
     2040 * \sa CandidateForTesselation::CheckValidity(), which is more evolved.
     2041 * Note that endpoints are stored in Tesselation::TPS.
     2042 * \param *OtherOptCenter center of the other triangle
     2043 * \param RADIUS radius of sphere
     2044 * \param *LC LinkedCell structure with other atoms
     2045 * \return true - candidate triangle is degenerated, false - candidate triangle is not degenerated
     2046 */
     2047bool Tesselation::CheckDegeneracy(Vector *OtherOptCenter, const double RADIUS, const LinkedCell *LC) const
     2048{
     2049  Info FunctionInfo(__func__);
     2050
     2051  DoLog(1) && (Log() << Verbose(1) << "INFO: Checking whether sphere contains no others points ..." << endl);
     2052  bool flag = true;
     2053
     2054  cout << Verbose(1) << "Check by: draw sphere {" << OtherOptCenter->x[0] << " " << OtherOptCenter->x[1] << " " << OtherOptCenter->x[2] << "} radius " << RADIUS << " resolution 30" << endl;
     2055
     2056  // get all points inside the sphere
     2057  TesselPointList *ListofPoints = LC->GetPointsInsideSphere(RADIUS, OtherOptCenter);
     2058
     2059  Log() << Verbose(1) << "The following atoms are inside sphere at " << *OtherOptCenter << ":" << endl;
     2060  for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
     2061    Log() << Verbose(1) << "  " << *(*Runner) << " with distance " << (*Runner)->node->Distance(OtherOptCenter) << "." << endl;
     2062
     2063  // remove triangles's endpoints
     2064  for (int i=0;i<3;i++)
     2065    ListofPoints->remove(TPS[i]->node);
     2066
     2067  // check for other points
     2068  if (!ListofPoints->empty()) {
     2069    Log() << Verbose(1) << "CheckDegeneracy: There are still " << ListofPoints->size() << " points inside the sphere." << endl;
     2070    flag = false;
     2071    Log() << Verbose(1) << "External atoms inside of sphere at " << *OtherOptCenter << ":" << endl;
     2072    for (TesselPointList::const_iterator Runner = ListofPoints->begin(); Runner != ListofPoints->end(); ++Runner)
     2073      Log() << Verbose(1) << "  " << *(*Runner) << " with distance " << (*Runner)->node->Distance(OtherOptCenter) << "." << endl;
     2074  }
     2075  delete(ListofPoints);
     2076
     2077  return flag;
     2078};
     2079
     2080
    20652081/** Checks whether the triangle consisting of the three points is already present.
    20662082 * Searches for the points in Tesselation::PointsOnBoundary and checks their
     
    21822198  TesselPoint* Temporary;
    21832199  double maxCoordinate[NDIM];
    2184   BoundaryLineSet BaseLine;
     2200  BoundaryLineSet *BaseLine = NULL;
    21852201  Vector helper;
    21862202  Vector Chord;
     
    22282244    NormalVector.Zero();
    22292245    NormalVector.x[k] = 1.;
    2230     BaseLine.endpoints[0] = new BoundaryPointSet(MaxPoint[k]);
    2231     Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine.endpoints[0]->node << "." << endl;
     2246    BaseLine = new BoundaryLineSet();
     2247    BaseLine->endpoints[0] = new BoundaryPointSet(MaxPoint[k]);
     2248    Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine->endpoints[0]->node << "." << endl;
    22322249
    22332250    double ShortestAngle;
    22342251    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.
    22352252
    2236     FindSecondPointForTesselation(BaseLine.endpoints[0]->node, NormalVector, Temporary, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...
     2253    FindSecondPointForTesselation(BaseLine->endpoints[0]->node, NormalVector, Temporary, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...
    22372254    if (Temporary == NULL)  // have we found a second point?
    22382255      continue;
    2239     BaseLine.endpoints[1] = new BoundaryPointSet(Temporary);
     2256    BaseLine->endpoints[1] = new BoundaryPointSet(Temporary);
    22402257
    22412258    // construct center of circle
    2242     CircleCenter.CopyVector(BaseLine.endpoints[0]->node->node);
    2243     CircleCenter.AddVector(BaseLine.endpoints[1]->node->node);
     2259    CircleCenter.CopyVector(BaseLine->endpoints[0]->node->node);
     2260    CircleCenter.AddVector(BaseLine->endpoints[1]->node->node);
    22442261    CircleCenter.Scale(0.5);
    22452262
    22462263    // construct normal vector of circle
    2247     CirclePlaneNormal.CopyVector(BaseLine.endpoints[0]->node->node);
    2248     CirclePlaneNormal.SubtractVector(BaseLine.endpoints[1]->node->node);
     2264    CirclePlaneNormal.CopyVector(BaseLine->endpoints[0]->node->node);
     2265    CirclePlaneNormal.SubtractVector(BaseLine->endpoints[1]->node->node);
    22492266
    22502267    double radius = CirclePlaneNormal.NormSquared();
     
    22642281
    22652282    // adding point 1 and point 2 and add the line between them
    2266     Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine.endpoints[0]->node << "." << endl;
    2267     Log() << Verbose(0) << "Found second point is at " << *BaseLine.endpoints[1]->node << ".\n";
     2283    Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine->endpoints[0]->node << "." << endl;
     2284    Log() << Verbose(0) << "Found second point is at " << *BaseLine->endpoints[1]->node << ".\n";
    22682285
    22692286    //Log() << Verbose(1) << "INFO: OldSphereCenter is at " << helper << ".\n";
    2270     CandidateForTesselation OptCandidates(&BaseLine);
     2287    CandidateForTesselation OptCandidates(BaseLine);
    22712288    FindThirdPointForTesselation(NormalVector, SearchDirection, SphereCenter, OptCandidates, NULL, RADIUS, LC);
    22722289    Log() << Verbose(0) << "List of third Points is:" << endl;
     
    22742291        Log() << Verbose(0) << " " << *(*it) << endl;
    22752292    }
    2276 
    2277     BTS = NULL;
    2278     AddCandidatePolygon(OptCandidates, RADIUS, LC);
    2279 //    delete(BaseLine.endpoints[0]);
    2280 //    delete(BaseLine.endpoints[1]);
     2293    if (!OptCandidates.pointlist.empty()) {
     2294      BTS = NULL;
     2295      AddCandidatePolygon(OptCandidates, RADIUS, LC);
     2296    } else {
     2297      delete BaseLine;
     2298      continue;
     2299    }
    22812300
    22822301    if (BTS != NULL) // we have created one starting triangle
     
    22862305      OptCandidates.pointlist.clear();
    22872306    }
     2307    delete BaseLine;
    22882308  }
    22892309};
     
    24362456 * @param *LC LinkedCell structure with neighbouring points
    24372457 */
    2438 bool Tesselation::FindNextSuitableTriangle(CandidateForTesselation &CandidateLine, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC)
     2458bool Tesselation::FindNextSuitableTriangle(CandidateForTesselation &CandidateLine, const BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC)
    24392459{
    24402460        Info FunctionInfo(__func__);
     
    26272647  Sprinter++;
    26282648  while(Sprinter != connectedClosestPoints->end()) {
    2629     // add this triangle
    2630     AddCandidateTriangle(TurningPoint, *Runner, *Sprinter);
    2631 
    2632     // store values from tesselation procedure therein
    2633     BTS->SetTopNode(CandidateLine.T);
    2634     if (CandidateLine.T != NULL)  // start triangle has angle from top of -1
    2635       BTS->AngleFromTop = CandidateLine.ShortestAngle;
    2636     else
    2637       BTS->AngleFromTop = -1.;
    2638 
    2639     // create normal vector
    2640     BTS->GetCenter(&Center);
    2641     Center.SubtractVector(&CandidateLine.OptCenter);
    2642     BTS->SphereCenter.CopyVector(&CandidateLine.OptCenter);
    2643     BTS->GetNormalVector(Center);
    2644 
    2645     // give some verbose output about the whole procedure
    2646     if (CandidateLine.T != NULL)
    2647       Log() << Verbose(0) << "--> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << "." << endl;
    2648     else
    2649       Log() << Verbose(0) << "--> New starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle." << endl;
    2650 
    2651     // check whether its degenerate and if so, add the other side triangle as well
    2652     if (BTS->CheckDegeneracy(&CandidateLine.OtherOptCenter, RADIUS, LC)) {
    2653       Log() << Verbose(1) << "Triangle " << *BTS << " is degenerated, adding other side." << endl;
    2654       BoundaryTriangleSet * const triangle = BTS;
    2655       AddDegeneratedTriangle(BTS, &CandidateLine.OtherOptCenter, RADIUS, LC);
    2656       // check whether other side triangle has been created
    2657       if (BTS != NULL) {
    2658         BTS->SetTopNode(CandidateLine.T);
    2659         if (CandidateLine.T != NULL)  // start triangle has angle from top of -1
    2660           BTS->AngleFromTop = CandidateLine.ShortestAngle;
    2661         else
    2662           BTS->AngleFromTop = -1.;
    2663         BTS->SphereCenter.CopyVector(&CandidateLine.OtherOptCenter);
    2664         // normal vector points other way round
    2665         BTS->NormalVector.CopyVector(&triangle->NormalVector);
    2666         BTS->NormalVector.Scale(-1.);
    2667 
    2668         // give some verbose output about the whole procedure
    2669         if (CandidateLine.T != NULL)
    2670           Log() << Verbose(0) << "--> New degenerate triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << "." << endl;
    2671         else
    2672           Log() << Verbose(0) << "--> New degenerate starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle." << endl;
    2673       }
     2649    AddTesselationPoint(TurningPoint, 0);
     2650    AddTesselationPoint(*Runner, 1);
     2651    AddTesselationPoint(*Sprinter, 2);
     2652
     2653    // check whether we add a degenerate or a normal triangle
     2654    if (CheckDegeneracy(&CandidateLine.OtherOptCenter, RADIUS, LC)) {
     2655      // add normal and degenerate triangles
     2656      Log() << Verbose(1) << "Triangle of endpoints " << *TPS[0] << "," << *TPS[1] << " and " << *TPS[2] << " is degenerated, adding both sides." << endl;
     2657      BoundaryTriangleSet * const triangle = AddDegeneratedTriangle(CandidateLine, RADIUS, LC);
     2658    } else {
     2659      // add this triangle
     2660      AddCandidateTriangle(CandidateLine);
    26742661    }
    26752662
     
    26832670};
    26842671
    2685 /** If a given \a *triangle is degenerated, this adds the "other side".
     2672/** If a given \a *triangle is degenerated, this adds both sides.
    26862673 * i.e. the triangle with same BoundaryPointSet's but NormalVector in opposite direction.
    2687  * \param *triangle degenerated triangle
    2688  * \param *OtherOptCenter center of the sphere for the other triangle
     2674 * Note that endpoints are stored in Tesselation::TPS
     2675 * \param CandidateLine CanddiateForTesselation structure for the desired BoundaryLine
    26892676 * \param RADIUS radius of sphere
    26902677 * \param *LC pointer to LinkedCell structure
    26912678 * \return pointer to created other triangle
    26922679 */
    2693 void Tesselation::AddDegeneratedTriangle(BoundaryTriangleSet *&triangle, Vector *OtherOptCenter, const double RADIUS, const LinkedCell *LC)
     2680BoundaryTriangleSet * const  Tesselation::AddDegeneratedTriangle(CandidateForTesselation &CandidateLine, const double RADIUS, const LinkedCell *LC)
    26942681{
    26952682  Info FunctionInfo(__func__);
    2696   TesselPoint *ThirdNode = NULL;
    2697   BoundaryTriangleSet *otherTriangle = NULL;
    2698   /// 1. For each of the open sides of \a *triangle find best candidate
     2683  BoundaryTriangleSet *triangle = NULL;
     2684  pair<LineMap::iterator,LineMap::iterator> FindPair[3];
     2685  int LineCase[3];
     2686  int count[3];
     2687  Vector Center;
     2688  CandidateMap::const_iterator CandidateCheck = OpenLines.end();
     2689
     2690  /// 1. For each new pair of endpoints, find and count the number of present lines
     2691  Log() << Verbose(0) << "INFO: Counting present open lines ..." << endl;
    26992692  for (int i=0;i<3;i++) {
    27002693    BLS[i] = NULL;
    2701     // go through all possible lines (also degenerate ones) and find ones to be used
    2702     pair<LineMap::iterator,LineMap::iterator> FindPair = triangle->lines[i]->endpoints[0]->lines.equal_range(triangle->lines[i]->endpoints[1]->Nr);
    2703     for (LineMap::iterator FindLine = FindPair.first; FindLine != FindPair.second; FindLine++) {
    2704       if ((*FindLine).second->triangles.size() == 1) {
    2705         Log() << Verbose(1) << "Found line " << *(*FindLine).second << " from triangle " << *((*FindLine).second->triangles.begin()->second) << "." << endl;
    2706         // check whether best Candidate for this line from the degenerate triangle is the third endpoint
    2707         CandidateForTesselation CandidateLine((*FindLine).second);
    2708         otherTriangle = ((*FindLine).second->triangles.begin())->second;  // this is unique and present, above we check that there is exactly one
    2709         ThirdNode = otherTriangle->GetThirdEndpoint((*FindLine).second)->node;
    2710         FindNextSuitableTriangle(CandidateLine, *triangle, RADIUS, LC);
    2711 
    2712         /// 2. If best candidate is third endpoint,
    2713         for (TesselPointList::const_iterator Runner = CandidateLine.pointlist.begin(); Runner != CandidateLine.pointlist.end(); ++Runner) {
    2714           Log() << Verbose(1) << "Found candidate " << *(*Runner) << endl;
    2715           if ((*Runner) == ThirdNode) { // seems like we found a line to connect to
    2716             /// sets Tesselation::BLS[i] accordingly and removes the line from Tesselation::OpenLines
    2717             AddExistingTesselationTriangleLine((*FindLine).second,i);
    2718             break;
    2719           }
    2720         }
     2694    LineCase[i] = -1;
     2695    // find already present lines
     2696    FindPair[i] = TPS[(i+0)%3]->lines.equal_range(TPS[(i+1)%3]->Nr);
     2697    // count their number
     2698    count[i] = 0;
     2699    Log() << Verbose(1) << "For line between " << *TPS[(i+0)%3] << " and " << *TPS[(i+1)%3] << ":" << endl;
     2700    for (LineMap::iterator FindLine = FindPair[i].first; FindLine != FindPair[i].second; FindLine++)
     2701      if (FindLine->second->triangles.size() == 1) {
     2702        Log() << Verbose(1) << "  open line " << *FindLine->second << "." << endl;
     2703        count[i]++;
    27212704      }
    2722     }
    2723     /// otherwise we create a new BoundaryLineSet for this Tesselation::BLS[i] and add it to OpenLines
    2724   }
    2725   if ((BLS[0] == NULL) && (BLS[1] == NULL) && (BLS[2] == NULL)) {
    2726     Log() << Verbose(0) << "This degenerate triangle would not share any line with its other side, rejecting." << endl;
    2727     BTS = NULL;
    2728   } else {
    2729     // created new lines for the other egdes of the other side triangle
    2730     for (int i=0;i<3;i++) {
    2731       if (BLS[i] == NULL) {
    2732         AddNewTesselationTriangleLine(triangle->lines[i]->endpoints[0],triangle->lines[i]->endpoints[1],i);
    2733       }
    2734     }
    2735     /// 3. Create the triangle
    2736     BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    2737     AddTesselationTriangle();
    2738 
    2739     // add triangle to the CandidateForTesselation of its open lines
    2740     CandidateMap::iterator Finder = OpenLines.end();
    2741     for (int i=0;i<3;i++) {
    2742       Finder = OpenLines.find(BTS->lines[i]);
    2743       if (Finder != OpenLines.end()) {
    2744         Log() << Verbose(1) << "INFO: Found open line of this triangle " << *(Finder->first) << endl;
    2745         if (Finder->second->T == NULL) {
    2746           Finder->second->T = BTS;
    2747           Log() << Verbose(1) << "ACCEPT: Setting source triangle of open line " << *(Finder->first) << " to the newly created one." << endl;
    2748         }
    2749       } else
    2750         Log() << Verbose(1) << "REJECT: line " << *BTS->lines[i] << " of this triangle is not found to be open." << endl;
    2751     }
    2752   }
     2705    Log() << Verbose(1) << "  SUM: there are " << count[i] << " line(s) present."  << endl;
     2706  }
     2707
     2708  /// 2. Create or pick the lines for the first triangle
     2709  // for each count we have a different case:
     2710  // case 0: no triangles at this line and not closed
     2711  // case 1: no triangles at new line is closed
     2712  // case 2: one line with one triangle attached, one will used this line
     2713  // case 3: one line with two triangles attached, new line will be used by both degenerate triangles
     2714  // case 4: two lines with one triangle each, each new triangle will pick one
     2715  Log() << Verbose(0) << "INFO: Creating/Picking lines for first triangle ..." << endl;
     2716  for (int i=0;i<3;i++) {
     2717    Log() << Verbose(0) << "Current line is between " << *TPS[(i+0)%3] << " and " << *TPS[(i+1)%3] << ":" << endl;
     2718    switch (count[i]) {
     2719      case 0:
     2720        AddNewTesselationTriangleLine(TPS[(i+0)%3], TPS[(i+1)%3], i);
     2721        break;
     2722      case 1:
     2723//        // check whether present line has right candidate
     2724//        CandidateCheck = OpenLines.find(FindPair[i].first->second);
     2725//        if (CandidateCheck != OpenLines.end()) {
     2726//          if (!CandidateCheck->second->pointlist.empty()) {
     2727//            for (TesselPointList::const_iterator Runner = CandidateCheck->second->pointlist.begin(); Runner != CandidateCheck->second->pointlist.end(); ++Runner) {
     2728//              Log() << Verbose(1) << "Found candidate " << *(*Runner) << " with Candidate center is " << CandidateCheck->second->OptCenter << ", desired opt center is " << CandidateLine.OptCenter << "." << endl;
     2729//              if (((*Runner) == TPS[(i+2)%3]->node) && (CandidateLine.OptCenter == CandidateCheck->second->OptCenter)) { // seems like we found a line to connect to
     2730//                AddExistingTesselationTriangleLine(CandidateCheck->first, i);
     2731//                break;  // have to break as a AddExistingTesselationTriangleLine changes OpenLines
     2732//              }
     2733//            }
     2734//          } else {
     2735//            Log() << Verbose(1) << "Open line between " << *TPS[(i+0)%3] << " and " << *TPS[(i+1)%3] << " has no candidate." << endl;
     2736//          }
     2737//        } else {
     2738//          Log() << Verbose(1) << "No open lines present for line between " << *TPS[(i+0)%3] << " and " << *TPS[(i+1)%3] << "." << endl;
     2739//        }
     2740//        if (BLS[i] == NULL) {
     2741//          AddNewTesselationTriangleLine(TPS[(i+0)%3], TPS[(i+1)%3], i);
     2742//        }
     2743        AddTesselationLine(&CandidateLine.OptCenter, TPS[(i+2)%3], TPS[(i+0)%3], TPS[(i+1)%3], i);
     2744        break;
     2745      default:
     2746      case 2:
     2747        AddTesselationLine(&CandidateLine.OptCenter, TPS[(i+2)%3], TPS[(i+0)%3], TPS[(i+1)%3], i);
     2748        break;
     2749//        DoeLog(0) && (eLog() << Verbose(0) << "There are more than two BoundaryPointSets between " << *TPS[(i+0)%3] << " and " << *TPS[(i+1)%3] << "." << endl);
     2750//        performCriticalExit();
     2751//        break;
     2752    }
     2753  }
     2754
     2755  /// 3. create the first triangle and NormalVector and so on
     2756  Log() << Verbose(0) << "INFO: Adding first triangle with center at " << CandidateLine.OptCenter << " ..." << endl;
     2757  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2758  AddTesselationTriangle();
     2759  // check whether triangle has been created
     2760  BTS->SetTopNode(CandidateLine.T);
     2761  if (CandidateLine.T != NULL)  // start triangle has angle from top of -1
     2762    BTS->AngleFromTop = CandidateLine.ShortestAngle;
     2763  else
     2764    BTS->AngleFromTop = -1.;
     2765  // create normal vector
     2766  BTS->GetCenter(&Center);
     2767  Center.SubtractVector(&CandidateLine.OptCenter);
     2768  BTS->SphereCenter.CopyVector(&CandidateLine.OptCenter);
     2769  BTS->GetNormalVector(Center);
     2770  // give some verbose output about the whole procedure
     2771  if (CandidateLine.T != NULL)
     2772    Log() << Verbose(0) << "--> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << "." << endl;
     2773  else
     2774    Log() << Verbose(0) << "--> New starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle." << endl;
     2775  triangle = BTS;
     2776
     2777  /// 4. Gather candidates for each new line
     2778  Log() << Verbose(0) << "INFO: Adding candidates to new lines ..." << endl;
     2779  for (int i=0;i<3;i++) {
     2780    Log() << Verbose(0) << "Current line is between " << *TPS[(i+0)%3] << " and " << *TPS[(i+1)%3] << ":" << endl;
     2781    CandidateCheck = OpenLines.find(BLS[i]);
     2782    if ((CandidateCheck != OpenLines.end()) && (CandidateCheck->second->pointlist.empty())) {
     2783      if (CandidateCheck->second->T == NULL)
     2784        CandidateCheck->second->T = triangle;
     2785      FindNextSuitableTriangle(*(CandidateCheck->second), *CandidateCheck->second->T, RADIUS, LC);
     2786    }
     2787  }
     2788
     2789  /// 5. Create or pick the lines for the second triangle
     2790  Log() << Verbose(0) << "INFO: Creating/Picking lines for second triangle ..." << endl;
     2791  for (int i=0;i<3;i++) {
     2792    Log() << Verbose(0) << "Current line is between " << *TPS[(i+0)%3] << " and " << *TPS[(i+1)%3] << ":" << endl;
     2793    switch (count[i]) {
     2794      case 0:
     2795        AddTesselationLine(&CandidateLine.OtherOptCenter, TPS[(i+2)%3], TPS[(i+0)%3], TPS[(i+1)%3], i);
     2796        break;
     2797      case 1:
     2798//        // check whether present line has right candidate
     2799//        CandidateCheck = OpenLines.find(BLS[i]);
     2800//        BLS[i] = NULL;
     2801//        if (CandidateCheck == OpenLines.end()) {  // first triangle has closed present line
     2802//          AddNewTesselationTriangleLine(TPS[(i+0)%3], TPS[(i+1)%3], i);
     2803//        } else {
     2804//          for (TesselPointList::const_iterator Runner = CandidateCheck->second->pointlist.begin(); Runner != CandidateCheck->second->pointlist.end(); ++Runner) {
     2805//            Log() << Verbose(1) << "Found candidate " << *(*Runner) << " with Candidate center is " << CandidateCheck->second->OptCenter << ", desired other opt center is " << CandidateLine.OtherOptCenter << "." << endl;
     2806//            if (((*Runner) == TPS[(i+2)%3]->node) && (CandidateLine.OtherOptCenter == CandidateCheck->second->OptCenter)) { // seems like we found a line to connect to
     2807//              AddExistingTesselationTriangleLine(CandidateCheck->first, i);
     2808//              break;  // have to break as a AddExistingTesselationTriangleLine changes OpenLines
     2809//            }
     2810//          }
     2811//        }
     2812//        if (BLS[i] == NULL) {
     2813//          DoeLog(0) && (eLog() << Verbose(0) << "BoundaryLine between " << TPS[(i+0)%3] << " and " << TPS[(i+1)%3] << " has not the correct candidate, i.e. the third endpoint: " << *TPS[(i+2)%3] << endl);
     2814//          performCriticalExit();
     2815//        }
     2816        AddTesselationLine(&CandidateLine.OtherOptCenter, TPS[(i+2)%3], TPS[(i+0)%3], TPS[(i+1)%3], i);
     2817        break;
     2818      case 2:
     2819      default:
     2820        AddTesselationLine(&CandidateLine.OtherOptCenter, TPS[(i+2)%3], TPS[(i+0)%3], TPS[(i+1)%3], i);
     2821        break;
     2822//        DoeLog(0) && (eLog() << Verbose(0) << "There are more than two BoundaryPointSets between " << *TPS[(i+0)%3] << " and " << *TPS[(i+1)%3] << "." << endl);
     2823//        performCriticalExit();
     2824//        break;
     2825    }
     2826  }
     2827
     2828  /// 6. create the second triangle and NormalVector and so on
     2829  Log() << Verbose(0) << "INFO: Adding second triangle with center at " << CandidateLine.OtherOptCenter << " ..." << endl;
     2830  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     2831  AddTesselationTriangle();
     2832  // check whether triangle has been created
     2833  BTS->SetTopNode(CandidateLine.T);
     2834  if (CandidateLine.T != NULL)  // start triangle has angle from top of -1
     2835    BTS->AngleFromTop = CandidateLine.ShortestAngle;
     2836  else
     2837    BTS->AngleFromTop = -1.;
     2838  BTS->SphereCenter.CopyVector(&CandidateLine.OtherOptCenter);
     2839  // create normal vector in other direction
     2840  BTS->GetNormalVector(&triangle->NormalVector);
     2841  BTS->NormalVector.Scale(-1.);
     2842  // give some verbose output about the whole procedure
     2843  if (CandidateLine.T != NULL)
     2844    Log() << Verbose(0) << "--> New degenerate triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << "." << endl;
     2845  else
     2846    Log() << Verbose(0) << "--> New degenerate starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle." << endl;
     2847
     2848  return triangle;
    27532849};
    27542850
    27552851/** Adds a triangle to the Tesselation structure from three given TesselPoint's.
    2756  * \param *first first TesselPoint
    2757  * \param *second second TesselPoint
    2758  * \param *third third TesselPoint
    2759  */
    2760 void Tesselation::AddCandidateTriangle(TesselPoint *first, TesselPoint *second, TesselPoint *third)
     2852 * Note that endpoints are in Tesselation::TPS.
     2853 * \param CandidateLine CandidateForTesselation structure contains other information
     2854 */
     2855void Tesselation::AddCandidateTriangle(CandidateForTesselation &CandidateLine)
    27612856{
    27622857  Info FunctionInfo(__func__);
    2763   // add the points
    2764   AddTesselationPoint(first, 0);
    2765   AddTesselationPoint(second, 1);
    2766   AddTesselationPoint(third, 2);
     2858  Vector Center;
    27672859
    27682860  // add the lines
    2769   AddTesselationLine(TPS[2], TPS[0], TPS[1], 0);
    2770   AddTesselationLine(TPS[1], TPS[0], TPS[2], 1);
    2771   AddTesselationLine(TPS[0], TPS[1], TPS[2], 2);
     2861  AddTesselationLine(&CandidateLine.OptCenter, TPS[2], TPS[0], TPS[1], 0);
     2862  AddTesselationLine(&CandidateLine.OptCenter, TPS[1], TPS[0], TPS[2], 1);
     2863  AddTesselationLine(&CandidateLine.OptCenter, TPS[0], TPS[1], TPS[2], 2);
    27722864
    27732865  // add the triangles
    27742866  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    27752867  AddTesselationTriangle();
     2868  // store values from tesselation procedure therein
     2869  BTS->SetTopNode(CandidateLine.T);
     2870  if (CandidateLine.T != NULL)  // start triangle has angle from top of -1
     2871    BTS->AngleFromTop = CandidateLine.ShortestAngle;
     2872  else
     2873    BTS->AngleFromTop = -1.;
     2874
     2875  // create normal vector
     2876  BTS->GetCenter(&Center);
     2877  Center.SubtractVector(&CandidateLine.OptCenter);
     2878  BTS->SphereCenter.CopyVector(&CandidateLine.OptCenter);
     2879  BTS->GetNormalVector(Center);
     2880
     2881  // give some verbose output about the whole procedure
     2882  if (CandidateLine.T != NULL)
     2883    Log() << Verbose(0) << "--> New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << ", from " << *CandidateLine.T << " and angle " << CandidateLine.ShortestAngle << "." << endl;
     2884  else
     2885    Log() << Verbose(0) << "--> New starting triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " and no top triangle." << endl;
    27762886};
    27772887
     
    31633273 * @param *LC LinkedCell structure with neighbouring points
    31643274 */
    3165 void Tesselation::FindThirdPointForTesselation(Vector &NormalVector, Vector &SearchDirection, Vector &OldSphereCenter, CandidateForTesselation &CandidateLine, const class BoundaryPointSet  * const ThirdPoint, const double RADIUS, const LinkedCell *LC) const
     3275void Tesselation::FindThirdPointForTesselation(const Vector &NormalVector, const Vector &SearchDirection, const Vector &OldSphereCenter, CandidateForTesselation &CandidateLine, const class BoundaryPointSet  * const ThirdPoint, const double RADIUS, const LinkedCell *LC) const
    31663276{
    31673277        Info FunctionInfo(__func__);
     
    33443454  }
    33453455
    3346   if (!CandidateLine.CheckValidity(RADIUS, LC)) {
     3456  if ((!CandidateLine.pointlist.empty()) && (!CandidateLine.CheckValidity(RADIUS, LC))) {
    33473457    DoeLog(0) && (eLog() << Verbose(0) << "There were other points contained in the rolling sphere as well!" << endl);
    33483458    performCriticalExit();
     
    43494459        AddTesselationPoint(*EndNode, 2);
    43504460        Log() << Verbose(3) << "Adding new triangle lines."<< endl;
    4351         AddTesselationLine(NULL, TPS[0], TPS[1], 0);
    4352         AddTesselationLine(NULL, TPS[0], TPS[2], 1);
     4461        AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0);
     4462        AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1);
    43534463        NewLines.push_back(BLS[1]);
    4354         AddTesselationLine(NULL, TPS[1], TPS[2], 2);
     4464        AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2);
    43554465        BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    43564466        BTS->GetNormalVector(NormalVector);
     
    48014911  AddTesselationPoint(point, 2);
    48024912  Log() << Verbose(2) << "Adding new triangle lines."<< endl;
    4803   AddTesselationLine(NULL, TPS[0], TPS[1], 0);
    4804   AddTesselationLine(NULL, TPS[0], TPS[2], 1);
    4805   AddTesselationLine(NULL, TPS[1], TPS[2], 2);
     4913  AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0);
     4914  AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1);
     4915  AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2);
    48064916  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    48074917  BTS->GetNormalVector(TempTriangle->NormalVector);
     
    48164926  AddTesselationPoint(point, 2);
    48174927  Log() << Verbose(2) << "Adding new triangle lines."<< endl;
    4818   AddTesselationLine(NULL, TPS[0], TPS[1], 0);
    4819   AddTesselationLine(NULL, TPS[0], TPS[2], 1);
    4820   AddTesselationLine(NULL, TPS[1], TPS[2], 2);
     4928  AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0);
     4929  AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1);
     4930  AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2);
    48214931  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
    48224932  BTS->GetNormalVector(TempTriangle->NormalVector);
     
    50515161      for (int i = 0; i < 3; i++)
    50525162        AddTesselationPoint((*TriangleWalker)->endpoints[i]->node, i);
    5053       AddTesselationLine(NULL, TPS[0], TPS[1], 0);
    5054       AddTesselationLine(NULL, TPS[0], TPS[2], 1);
    5055       AddTesselationLine(NULL, TPS[1], TPS[2], 2);
     5163      AddTesselationLine(NULL, NULL, TPS[0], TPS[1], 0);
     5164      AddTesselationLine(NULL, NULL, TPS[0], TPS[2], 1);
     5165      AddTesselationLine(NULL, NULL, TPS[1], TPS[2], 2);
    50565166      if (TriangleNrs.empty())
    50575167        DoeLog(0) && (eLog()<< Verbose(0) << "No more free triangle numbers!" << endl);
  • src/tesselation.hpp

    r061b06 rf07f86d  
    163163    bool IsPresentTupel(const BoundaryPointSet * const Points[3]) const;
    164164    bool IsPresentTupel(const BoundaryTriangleSet * const T) const;
    165     bool CheckDegeneracy(Vector *OtherOptCenter, const double RADIUS, const LinkedCell *LC) const;
    166165    void SetTopNode(const BoundaryTriangleSet * const topnode);
    167166
     
    283282    void AddTesselationPoint(TesselPoint* Candidate, const int n);
    284283    void SetTesselationPoint(TesselPoint* Candidate, const int n) const;
    285     void AddTesselationLine(const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n);
     284    void AddTesselationLine(const Vector * const OptCenter, const BoundaryPointSet * const candidate, class BoundaryPointSet *a, class BoundaryPointSet *b, const int n);
    286285    void AddNewTesselationTriangleLine(class BoundaryPointSet *a, class BoundaryPointSet *b, const int n);
    287286    void AddExistingTesselationTriangleLine(class BoundaryLineSet *FindLine, int n);
    288287    void AddTesselationTriangle();
    289288    void AddTesselationTriangle(const int nr);
    290     void AddCandidateTriangle(TesselPoint *first, TesselPoint *second, TesselPoint *third);
    291     void AddDegeneratedTriangle(BoundaryTriangleSet *&triangle, Vector *OtherOptCenter, const double RADIUS, const LinkedCell *LC);
     289    void AddCandidateTriangle(CandidateForTesselation &CandidateLine);
     290    BoundaryTriangleSet * const AddDegeneratedTriangle(CandidateForTesselation &CandidateLine, const double RADIUS, const LinkedCell *LC);
    292291    void AddCandidatePolygon(CandidateForTesselation CandidateLine, const double RADIUS, const LinkedCell *LC);
    293292    void RemoveTesselationTriangle(class BoundaryTriangleSet *triangle);
    294293    void RemoveTesselationLine(class BoundaryLineSet *line);
    295294    void RemoveTesselationPoint(class BoundaryPointSet *point);
     295    bool CheckDegeneracy(Vector *OtherOptCenter, const double RADIUS, const LinkedCell *LC) const;
    296296
    297297
     
    299299    void FindStartingTriangle(const double RADIUS, const LinkedCell *LC);
    300300    void FindSecondPointForTesselation(class TesselPoint* a, Vector Oben, class TesselPoint*& OptCandidate, double Storage[3], double RADIUS, const LinkedCell *LC);
    301     void FindThirdPointForTesselation(Vector &NormalVector, Vector &SearchDirection, Vector &OldSphereCenter, CandidateForTesselation &CandidateLine, const class BoundaryPointSet  * const ThirdNode, const double RADIUS, const LinkedCell *LC) const;
    302     bool FindNextSuitableTriangle(CandidateForTesselation &CandidateLine, BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC);
     301    void FindThirdPointForTesselation(const Vector &NormalVector, const Vector &SearchDirection, const Vector &OldSphereCenter, CandidateForTesselation &CandidateLine, const class BoundaryPointSet  * const ThirdNode, const double RADIUS, const LinkedCell *LC) const;
     302    bool FindNextSuitableTriangle(CandidateForTesselation &CandidateLine, const BoundaryTriangleSet &T, const double& RADIUS, const LinkedCell *LC);
    303303    int CheckPresenceOfTriangle(class TesselPoint *Candidates[3]) const;
    304304    class BoundaryTriangleSet * GetPresentTriangle(TesselPoint *Candidates[3]);
Note: See TracChangeset for help on using the changeset viewer.