Changeset 62bb91 for src/tesselation.cpp
- Timestamp:
- Aug 4, 2009, 1:48:57 PM (15 years ago)
- 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:
- ef0e6d
- Parents:
- 03e57a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/tesselation.cpp
r03e57a r62bb91 143 143 bool BoundaryLineSet::CheckConvexityCriterion(ofstream *out) 144 144 { 145 Vector BaseLineNormal; 146 double angle = 0; 145 Vector BaseLineCenter, BaseLineNormal, BaseLine, helper[2]; 147 146 // get the two triangles 148 147 if (TrianglesCount != 2) { … … 151 150 } 152 151 // have a normal vector on the base line pointing outwards 152 *out << Verbose(3) << "INFO: " << *this << " has vectors at " << *(endpoints[0]->node->node) << " and at " << *(endpoints[1]->node->node) << "." << endl; 153 BaseLineCenter.CopyVector(endpoints[0]->node->node); 154 BaseLineCenter.AddVector(endpoints[1]->node->node); 155 BaseLineCenter.Scale(1./2.); 156 BaseLine.CopyVector(endpoints[0]->node->node); 157 BaseLine.SubtractVector(endpoints[1]->node->node); 158 *out << Verbose(3) << "INFO: Baseline is " << BaseLine << " and its center is at " << BaseLineCenter << "." << endl; 159 153 160 BaseLineNormal.Zero(); 154 for(TriangleMap::iterator runner = triangles.begin(); runner != triangles.end(); runner++) 155 BaseLineNormal.AddVector(&runner->second->NormalVector); 156 BaseLineNormal.Normalize(); 157 // and calculate the sum of the angles with this normal vector and each of the triangle ones' 158 for(TriangleMap::iterator runner = triangles.begin(); runner != triangles.end(); runner++) 159 angle += BaseLineNormal.Angle(&runner->second->NormalVector); 160 161 int i=0; 162 class BoundaryPointSet *node = NULL; 163 for(TriangleMap::iterator runner = triangles.begin(); runner != triangles.end(); runner++) { 164 *out << Verbose(3) << "INFO: NormalVector of " << *(runner->second) << " is " << runner->second->NormalVector << "." << endl; 165 BaseLineNormal.SubtractVector(&runner->second->NormalVector); // we subtract as BaseLineNormal has to point inward in direction of [pi,2pi] 166 node = runner->second->GetThirdEndpoint(this); 167 if (node != NULL) { 168 *out << Verbose(3) << "INFO: Third node for triangle " << *(runner->second) << " is " << *node << " at " << *(node->node->node) << "." << endl; 169 helper[i].CopyVector(node->node->node); 170 helper[i].SubtractVector(&BaseLineCenter); 171 helper[i].MakeNormalVector(&BaseLine); // we want to compare the triangle's heights' angles! 172 *out << Verbose(4) << "INFO: Height vector with respect to baseline is " << helper[i] << "." << endl; 173 i++; 174 } else { 175 *out << Verbose(2) << "WARNING: I cannot find third node in triangle, something's wrong." << endl; 176 return true; 177 } 178 } 179 *out << Verbose(3) << "INFO: BaselineNormal is " << BaseLineNormal << "." << endl; 180 double angle = helper[0].Angle(&helper[1]); 181 if (BaseLineNormal.ScalarProduct(&helper[1]) > 0) { 182 angle = 2.*M_PI - angle; 183 } 184 *out << Verbose(3) << "The angle is " << angle << "." << endl; 161 185 if ((angle - M_PI) > -MYEPSILON) 162 186 return true; … … 176 200 return false; 177 201 }; 202 203 /** Returns other endpoint of the line. 204 * \param *point other endpoint 205 * \return NULL - if endpoint not contained in BoundaryLineSet, or pointer to BoundaryPointSet otherwise 206 */ 207 inline class BoundaryPointSet *BoundaryLineSet::GetOtherEndpoint(class BoundaryPointSet *point) 208 { 209 if (endpoints[0] == point) 210 return endpoints[1]; 211 else if (endpoints[1] == point) 212 return endpoints[0]; 213 else 214 return NULL; 215 }; 216 178 217 179 218 ostream & … … 360 399 || (endpoints[2] == Points[1]) 361 400 || (endpoints[2] == Points[2]) 401 362 402 )); 363 403 }; 404 405 /** Returns the endpoint which is not contained in the given \a *line. 406 * \param *line baseline defining two endpoints 407 * \return pointer third endpoint or NULL if line does not belong to triangle. 408 */ 409 class BoundaryPointSet *BoundaryTriangleSet::GetThirdEndpoint(class BoundaryLineSet *line) 410 { 411 // sanity check 412 if (!ContainsBoundaryLine(line)) 413 return NULL; 414 for(int i=0;i<3;i++) 415 if (!line->ContainsBoundaryPoint(endpoints[i])) 416 return endpoints[i]; 417 // actually, that' impossible :) 418 return NULL; 419 }; 420 421 /** Calculates the center point of the triangle. 422 * Is third of the sum of all endpoints. 423 * \param *center central point on return. 424 */ 425 void BoundaryTriangleSet::GetCenter(Vector *center) 426 { 427 center->Zero(); 428 for(int i=0;i<3;i++) 429 center->AddVector(endpoints[i]->node->node); 430 center->Scale(1./3.); 431 } 364 432 365 433 ostream & … … 809 877 BLS[2] = LineChecker[1]->second; 810 878 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 879 BTS->GetCenter(&helper); 880 helper.SubtractVector(Center); 881 helper.Scale(-1); 882 BTS->GetNormalVector(helper); 811 883 TrianglesOnBoundary.insert(TrianglePair(TrianglesOnBoundaryCount, BTS)); 812 884 TrianglesOnBoundaryCount++; … … 824 896 }; 825 897 826 /** Inserts all atoms outside of the tesselated surface into it by adding new triangles.898 /** Inserts all points outside of the tesselated surface into it by adding new triangles. 827 899 * \param *out output stream for debugging 828 900 * \param *cloud cluster of points 901 * \param *LC LinkedCell structure to find nearest point quickly 829 902 * \return true - all straddling points insert, false - something went wrong 830 903 */ 831 bool Tesselation::InsertStraddlingPoints(ofstream *out, PointCloud *cloud )904 bool Tesselation::InsertStraddlingPoints(ofstream *out, PointCloud *cloud, LinkedCell *LC) 832 905 { 833 906 Vector Intersection; 834 907 TesselPoint *Walker = NULL; 835 908 Vector *Center = cloud->GetCenter(out); 909 list<BoundaryTriangleSet*> *triangles = NULL; 910 911 *out << Verbose(1) << "Begin of InsertStraddlingPoints" << endl; 836 912 837 913 cloud->GoToFirst(); 838 914 while (!cloud->IsLast()) { // we only have to go once through all points, as boundary can become only bigger 839 915 Walker = cloud->GetPoint(); 916 *out << Verbose(2) << "Current point is " << *Walker << "." << endl; 840 917 // get the next triangle 841 BTS = FindClosestTriangleToPoint(out, Walker->node); 842 if (BTS == NULL) { 843 *out << Verbose(1) << "ERROR: No triangle closest to " << Walker << " was found." << endl; 844 return false; 845 } 918 triangles = FindClosestTrianglesToPoint(out, Walker->node, LC); 919 if (triangles == NULL) { 920 *out << Verbose(1) << "No triangles found, probably a tesselation point itself." << endl; 921 cloud->GoToNext(); 922 continue; 923 } else { 924 BTS = triangles->front(); 925 } 926 *out << Verbose(2) << "Closest triangle is " << BTS << "." << endl; 846 927 // get the intersection point 847 928 if (BTS->GetIntersectionInsideTriangle(out, Center, Walker->node, &Intersection)) { 929 *out << Verbose(2) << "We have an intersection at " << Intersection << "." << endl; 848 930 // we have the intersection, check whether in- or outside of boundary 849 931 if ((Center->DistanceSquared(Walker->node) - Center->DistanceSquared(&Intersection)) < -MYEPSILON) { … … 904 986 // exit 905 987 delete(Center); 988 *out << Verbose(1) << "End of InsertStraddlingPoints" << endl; 906 989 return true; 907 990 }; 908 991 909 /** Adds an atomto the tesselation::PointsOnBoundary list.910 * \param *Walker atomto add992 /** Adds an point to the tesselation::PointsOnBoundary list. 993 * \param *Walker point to add 911 994 */ 912 995 void … … 1020 1103 1021 1104 1022 /** Checks whether the triangle consisting of the three atoms is already present.1105 /** Checks whether the triangle consisting of the three points is already present. 1023 1106 * Searches for the points in Tesselation::PointsOnBoundary and checks their 1024 1107 * lines. If any of the three edges already has two triangles attached, false is … … 1075 1158 1076 1159 /** Finds the starting triangle for find_non_convex_border(). 1077 * Looks at the outermost atomper axis, then Find_second_point_for_Tesselation()1160 * Looks at the outermost point per axis, then Find_second_point_for_Tesselation() 1078 1161 * for the second and Find_next_suitable_point_via_Angle_of_Sphere() for the third 1079 1162 * point are called. … … 1089 1172 TesselPoint* FirstPoint = NULL; 1090 1173 TesselPoint* SecondPoint = NULL; 1091 TesselPoint* Max Atom[NDIM];1174 TesselPoint* MaxPoint[NDIM]; 1092 1175 double max_coordinate[NDIM]; 1093 1176 Vector Oben; … … 1099 1182 1100 1183 for (i = 0; i < 3; i++) { 1101 Max Atom[i] = NULL;1184 MaxPoint[i] = NULL; 1102 1185 max_coordinate[i] = -1; 1103 1186 } 1104 1187 1105 // 1. searching topmost atomwith respect to each axis1188 // 1. searching topmost point with respect to each axis 1106 1189 for (int i=0;i<NDIM;i++) { // each axis 1107 1190 LC->n[i] = LC->N[i]-1; // current axis is topmost cell … … 1115 1198 cout << Verbose(2) << "New maximal for axis " << i << " node is " << *(*Runner) << " at " << *(*Runner)->node << "." << endl; 1116 1199 max_coordinate[i] = (*Runner)->node->x[i]; 1117 Max Atom[i] = (*Runner);1200 MaxPoint[i] = (*Runner); 1118 1201 } 1119 1202 } … … 1126 1209 cout << Verbose(2) << "Found maximum coordinates: "; 1127 1210 for (int i=0;i<NDIM;i++) 1128 cout << i << ": " << *Max Atom[i] << "\t";1211 cout << i << ": " << *MaxPoint[i] << "\t"; 1129 1212 cout << endl; 1130 1213 … … 1133 1216 for (int k=0;k<NDIM;k++) { 1134 1217 Oben.x[k] = 1.; 1135 FirstPoint = Max Atom[k];1218 FirstPoint = MaxPoint[k]; 1136 1219 cout << Verbose(1) << "Coordinates of start node at " << *FirstPoint->node << "." << endl; 1137 1220 … … 1238 1321 * @param RADIUS radius of the rolling ball 1239 1322 * @param N number of found triangles 1240 * @param *LC LinkedCell structure with neighbouring atoms1323 * @param *LC LinkedCell structure with neighbouring points 1241 1324 */ 1242 1325 bool Tesselation::Find_next_suitable_triangle(ofstream *out, BoundaryLineSet &Line, BoundaryTriangleSet &T, const double& RADIUS, int N, LinkedCell *LC) … … 1327 1410 1328 1411 // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2) 1329 TesselPoint * AtomCandidates[3];1330 AtomCandidates[0] = (*it)->point;1331 AtomCandidates[1] = BaseRay->endpoints[0]->node;1332 AtomCandidates[2] = BaseRay->endpoints[1]->node;1333 int existentTrianglesCount = CheckPresenceOfTriangle(out, AtomCandidates);1412 TesselPoint *PointCandidates[3]; 1413 PointCandidates[0] = (*it)->point; 1414 PointCandidates[1] = BaseRay->endpoints[0]->node; 1415 PointCandidates[2] = BaseRay->endpoints[1]->node; 1416 int existentTrianglesCount = CheckPresenceOfTriangle(out, PointCandidates); 1334 1417 1335 1418 BTS = NULL; … … 1414 1497 bool Tesselation::CorrectConcaveBaselines(ofstream *out) 1415 1498 { 1416 class BoundaryTriangleSet *triangle[2];1417 1499 class BoundaryLineSet *OldLines[4], *NewLine; 1418 1500 class BoundaryPointSet *OldPoints[2]; … … 1420 1502 class BoundaryLineSet *Base = NULL; 1421 1503 int OldTriangles[2], OldBaseLine; 1422 int i; 1504 int i,m; 1505 1506 *out << Verbose(1) << "Begin of CorrectConcaveBaselines" << endl; 1507 1423 1508 for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline++) { 1424 1509 Base = baseline->second; 1425 1510 *out << Verbose(2) << "Current baseline is " << *Base << " ... " << endl; 1426 1511 // check convexity 1427 1512 if (Base->CheckConvexityCriterion(out)) { // triangles are convex 1428 *out << Verbose( 3) << Base << "has two convex triangles." << endl;1513 *out << Verbose(2) << "... has two convex triangles." << endl; 1429 1514 } else { // not convex! 1515 *out << Verbose(2) << "... has two concave triangles!" << endl; 1430 1516 // get the two triangles 1431 i=0;1432 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++)1433 triangle[i++] = runner->second;1434 1517 // gather four endpoints and four lines 1435 1518 for (int j=0;j<4;j++) … … 1438 1521 OldPoints[j] = NULL; 1439 1522 i=0; 1440 for (int m=0;m<2;m++) { // go over both triangles 1441 for (int j=0;j<3;j++) { // all of their endpoints and baselines 1442 if (triangle[m]->lines[j] != Base) // pick not the central baseline 1443 OldLines[i++] = triangle[m]->lines[j]; 1444 if (!Base->ContainsBoundaryPoint(triangle[m]->endpoints[j])) // and neither of its endpoints 1445 OldPoints[m] = triangle[m]->endpoints[j]; 1446 } 1447 } 1523 m=0; 1524 *out << Verbose(3) << "The four old lines are: "; 1525 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1526 for (int j=0;j<3;j++) // all of their endpoints and baselines 1527 if (runner->second->lines[j] != Base) { // pick not the central baseline 1528 OldLines[i++] = runner->second->lines[j]; 1529 *out << *runner->second->lines[j] << "\t"; 1530 } 1531 *out << endl; 1532 *out << Verbose(3) << "The two old points are: "; 1533 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) 1534 for (int j=0;j<3;j++) // all of their endpoints and baselines 1535 if (!Base->ContainsBoundaryPoint(runner->second->endpoints[j])) { // and neither of its endpoints 1536 OldPoints[m++] = runner->second->endpoints[j]; 1537 *out << *runner->second->endpoints[j] << "\t"; 1538 } 1539 *out << endl; 1448 1540 if (i<4) { 1449 1541 *out << Verbose(1) << "ERROR: We have not gathered enough baselines!" << endl; … … 1461 1553 } 1462 1554 1463 // remove triangles 1464 for (int j=0;j<2;j++) { 1465 OldTriangles[j] = triangle[j]->Nr; 1466 TrianglesOnBoundary.erase(OldTriangles[j]); 1467 triangle[j] = NULL; 1468 } 1469 1470 // remove baseline 1555 // remove triangles and baseline removes itself 1556 m=0; 1471 1557 OldBaseLine = Base->Nr; 1472 1558 LinesOnBoundary.erase(OldBaseLine); 1473 Base = NULL; 1559 for(TriangleMap::iterator runner = Base->triangles.begin(); runner != Base->triangles.end(); runner++) { 1560 TrianglesOnBoundary.erase(OldTriangles[m++] = runner->second->Nr); 1561 delete(runner->second); 1562 } 1474 1563 1475 1564 // construct new baseline (with same number as old one) … … 1481 1570 // construct new triangles with flipped baseline 1482 1571 i=-1; 1483 if ( BLS[0]->IsConnectedTo(OldLines[2]))1572 if (OldLines[0]->IsConnectedTo(OldLines[2])) 1484 1573 i=2; 1485 if ( BLS[0]->IsConnectedTo(OldLines[2]))1574 if (OldLines[0]->IsConnectedTo(OldLines[3])) 1486 1575 i=3; 1487 1576 if (i!=-1) { … … 1503 1592 } 1504 1593 } 1594 *out << Verbose(1) << "End of CorrectConcaveBaselines" << endl; 1505 1595 return true; 1506 1596 }; 1507 1508 1509 /** States whether point is in- or outside of a tesselated surface.1510 * \param *pointer point to be checked1511 * \return true - is inside, false - is outside1512 */1513 bool Tesselation::IsInside(Vector *pointer)1514 {1515 1516 // hier kommt dann Saskias Routine hin...1517 1518 return true;1519 };1520 1521 1522 /** Finds the closest triangle to a given point.1523 * \param *out output stream for debugging1524 * \param *x second endpoint of line1525 * \return pointer triangle that is closest, NULL if none was found1526 */1527 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToPoint(ofstream *out, Vector *x)1528 {1529 class BoundaryTriangleSet *triangle = NULL;1530 1531 // hier kommt dann Saskias Routine hin...1532 1533 return triangle;1534 };1535 1536 1597 1537 1598 /** Finds the second point of starting triangle. … … 1542 1603 * \param Storage[3] array storing angles and other candidate information 1543 1604 * \param RADIUS radius of virtual sphere 1544 * \param *LC LinkedCell structure with neighbouring atoms1605 * \param *LC LinkedCell structure with neighbouring points 1545 1606 */ 1546 1607 void Tesselation::Find_second_point_for_Tesselation(TesselPoint* a, TesselPoint* Candidate, Vector Oben, TesselPoint*& Opt_Candidate, double Storage[3], double RADIUS, LinkedCell *LC) … … 1552 1613 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 1553 1614 1554 if (LC->SetIndexToNode(a)) { // get cell for the starting atom1615 if (LC->SetIndexToNode(a)) { // get cell for the starting point 1555 1616 for(int i=0;i<NDIM;i++) // store indices of this cell 1556 1617 N[i] = LC->n[i]; 1557 1618 } else { 1558 cerr << "ERROR: Atom" << *a << " is not found in cell " << LC->index << "." << endl;1619 cerr << "ERROR: Point " << *a << " is not found in cell " << LC->index << "." << endl; 1559 1620 return; 1560 1621 } 1561 // then go through the current and all neighbouring cells and check the contained atoms for possible candidates1622 // then go through the current and all neighbouring cells and check the contained points for possible candidates 1562 1623 cout << Verbose(3) << "LC Intervals from ["; 1563 1624 for (int i=0;i<NDIM;i++) { … … 1657 1718 * @param OldSphereCenter center of sphere for base triangle, relative to center of BaseLine, giving null angle for the parameter circle 1658 1719 * @param BaseLine BoundaryLineSet with the current base line 1659 * @param ThirdNode third atomto avoid in search1720 * @param ThirdNode third point to avoid in search 1660 1721 * @param candidates list of equally good candidates to return 1661 1722 * @param ShortestAngle the current path length on this circle band for the current Opt_Candidate 1662 1723 * @param RADIUS radius of sphere 1663 * @param *LC LinkedCell structure with neighbouring atoms1724 * @param *LC LinkedCell structure with neighbouring points 1664 1725 */ 1665 1726 void Tesselation::Find_third_point_for_Tesselation(Vector NormalVector, Vector SearchDirection, Vector OldSphereCenter, class BoundaryLineSet *BaseLine, class TesselPoint *ThirdNode, CandidateList* &candidates, double *ShortestAngle, const double RADIUS, LinkedCell *LC) … … 1714 1775 } 1715 1776 1716 // get cell for the starting atom1777 // get cell for the starting point 1717 1778 if (LC->SetIndexToVector(&CircleCenter)) { 1718 1779 for(int i=0;i<NDIM;i++) // store indices of this cell … … 1723 1784 return; 1724 1785 } 1725 // then go through the current and all neighbouring cells and check the contained atoms for possible candidates1786 // then go through the current and all neighbouring cells and check the contained points for possible candidates 1726 1787 //cout << Verbose(2) << "LC Intervals:"; 1727 1788 for (int i=0;i<NDIM;i++) { … … 1874 1935 }; 1875 1936 1937 /** Finds the triangle that is closest to a given Vector \a *x. 1938 * \param *out output stream for debugging 1939 * \param *x Vector to look from 1940 * \return list of BoundaryTriangleSet of nearest triangles or NULL in degenerate case. 1941 */ 1942 list<BoundaryTriangleSet*> * Tesselation::FindClosestTrianglesToPoint(ofstream *out, Vector *x, LinkedCell* LC) 1943 { 1944 class TesselPoint *trianglePoints[3]; 1945 1946 if (LinesOnBoundary.empty()) { 1947 *out << Verbose(0) << "Error: There is no tesselation structure to compare the point with, " << "please create one first."; 1948 return NULL; 1949 } 1950 1951 trianglePoints[0] = findClosestPoint(x, LC); 1952 // check whether closest point is "too close" :), then it's inside 1953 if (trianglePoints[0]->node->DistanceSquared(x) < MYEPSILON) { 1954 *out << Verbose(1) << "Point is right on a tesselation point, no nearest triangle." << endl; 1955 return NULL; 1956 } 1957 list<TesselPoint*> *connectedClosestPoints = getCircleOfConnectedPoints(out, trianglePoints[0], x); 1958 trianglePoints[1] = connectedClosestPoints->front(); 1959 trianglePoints[2] = connectedClosestPoints->back(); 1960 for (int i=0;i<3;i++) { 1961 if (trianglePoints[i] == NULL) { 1962 *out << Verbose(1) << "IsInnerPoint encounters serious error, point " << i << " not found." << endl; 1963 } 1964 *out << Verbose(1) << "List of possible points:" << endl; 1965 *out << *trianglePoints[i] << endl; 1966 } 1967 delete(connectedClosestPoints); 1968 1969 list<BoundaryTriangleSet*> *triangles = FindTriangles(trianglePoints); 1970 1971 if (triangles->empty()) { 1972 *out << Verbose(0) << "Error: There is no nearest triangle. Please check the tesselation structure."; 1973 return NULL; 1974 } else 1975 return triangles; 1976 }; 1977 1978 /** Finds closest triangle to a point. 1979 * This basically just takes care of the degenerate case, which is not handled in FindClosestTrianglesToPoint(). 1980 * \param *out output stream for debugging 1981 * \param *x Vector to look from 1982 * \return list of BoundaryTriangleSet of nearest triangles or NULL. 1983 */ 1984 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToPoint(ofstream *out, Vector *x, LinkedCell* LC) 1985 { 1986 class BoundaryTriangleSet *result = NULL; 1987 list<BoundaryTriangleSet*> *triangles = FindClosestTrianglesToPoint(out, x, LC); 1988 1989 if (triangles == NULL) 1990 return NULL; 1991 1992 if (x->ScalarProduct(&triangles->front()->NormalVector) < 0) 1993 result = triangles->back(); 1994 else 1995 result = triangles->front(); 1996 1997 delete(triangles); 1998 return result; 1999 }; 2000 2001 /** Checks whether the provided Vector is within the tesselation structure. 2002 * 2003 * @param point of which to check the position 2004 * @param *LC LinkedCell structure 2005 * 2006 * @return true if the point is inside the tesselation structure, false otherwise 2007 */ 2008 bool Tesselation::IsInnerPoint(ofstream *out, Vector Point, LinkedCell* LC) 2009 { 2010 class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, &Point, LC); 2011 if (result == NULL) 2012 return true; 2013 if (Point.ScalarProduct(&result->NormalVector) < 0) 2014 return true; 2015 else 2016 return false; 2017 } 2018 2019 /** Checks whether the provided TesselPoint is within the tesselation structure. 2020 * 2021 * @param *Point of which to check the position 2022 * @param *LC Linked Cell structure 2023 * 2024 * @return true if the point is inside the tesselation structure, false otherwise 2025 */ 2026 bool Tesselation::IsInnerPoint(ofstream *out, TesselPoint *Point, LinkedCell* LC) 2027 { 2028 class BoundaryTriangleSet *result = FindClosestTriangleToPoint(out, Point->node, LC); 2029 if (result == NULL) 2030 return true; 2031 if (Point->node->ScalarProduct(&result->NormalVector) < 0) 2032 return true; 2033 else 2034 return false; 2035 } 2036 2037 /** Gets all points connected to the provided point by triangulation lines. 2038 * Maps them down onto the plane designated by the axis \a *Point and \a *Reference. The center of all points 2039 * connected in the tesselation to \a *Point is mapped to spherical coordinates with the zero angle being given 2040 * by the mapped down \a *Reference. Hence, the biggest and the smallest angles are those of the two shanks of the 2041 * triangle we are looking for. 2042 * 2043 * @param *Point of which get all connected points 2044 * @param *Reference Vector to be checked whether it is an inner point 2045 * 2046 * @return list of the two points linked to the provided one and closest to the point to be checked, 2047 */ 2048 list<TesselPoint*> * Tesselation::getCircleOfConnectedPoints(ofstream *out, TesselPoint* Point, Vector* Reference) 2049 { 2050 list<TesselPoint*> connectedPoints; 2051 map<double, TesselPoint*> anglesOfPoints; 2052 map<double, TesselPoint*>::iterator runner; 2053 list<TesselPoint*>::iterator listRunner; 2054 Vector center, planeNorm, currentPoint, OrthogonalVector, helper; 2055 TesselPoint* current; 2056 bool takePoint = false; 2057 2058 planeNorm.CopyVector(Point->node); 2059 planeNorm.SubtractVector(Reference); 2060 planeNorm.Normalize(); 2061 2062 LineMap::iterator findLines = LinesOnBoundary.begin(); 2063 while (findLines != LinesOnBoundary.end()) { 2064 takePoint = false; 2065 2066 if (findLines->second->endpoints[0]->Nr == Point->nr) { 2067 takePoint = true; 2068 current = findLines->second->endpoints[1]->node; 2069 } else if (findLines->second->endpoints[1]->Nr == Point->nr) { 2070 takePoint = true; 2071 current = findLines->second->endpoints[0]->node; 2072 } 2073 2074 if (takePoint) { 2075 connectedPoints.push_back(current); 2076 currentPoint.CopyVector(current->node); 2077 currentPoint.ProjectOntoPlane(&planeNorm); 2078 center.AddVector(¤tPoint); 2079 } 2080 2081 findLines++; 2082 } 2083 2084 *out << "Summed vectors " << center << "; number of points " << connectedPoints.size() 2085 << "; scale factor " << 1.0/connectedPoints.size(); 2086 2087 center.Scale(1.0/connectedPoints.size()); 2088 listRunner = connectedPoints.begin(); 2089 2090 *out << " calculated center " << center << endl; 2091 2092 // construct one orthogonal vector 2093 helper.CopyVector(Reference); 2094 helper.ProjectOntoPlane(&planeNorm); 2095 OrthogonalVector.MakeNormalVector(¢er, &helper, (*listRunner)->node); 2096 while (listRunner != connectedPoints.end()) { 2097 double angle = getAngle(*((*listRunner)->node), *(Reference), center, OrthogonalVector); 2098 *out << "Calculated angle " << angle << " for point " << **listRunner << endl; 2099 anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 2100 listRunner++; 2101 } 2102 2103 list<TesselPoint*> *result = new list<TesselPoint*>; 2104 runner = anglesOfPoints.begin(); 2105 *out << "First value is " << *runner->second << endl; 2106 result->push_back(runner->second); 2107 runner = anglesOfPoints.end(); 2108 runner--; 2109 *out << "Second value is " << *runner->second << endl; 2110 result->push_back(runner->second); 2111 2112 *out << "List of closest points has " << result->size() << " elements, which are " 2113 << *(result->front()) << " and " << *(result->back()) << endl; 2114 2115 return result; 2116 } 2117 1876 2118 /** Checks for a new special triangle whether one of its edges is already present with one one triangle connected. 1877 2119 * This enforces that special triangles (i.e. degenerated ones) should at last close the open-edge frontier and not … … 1957 2199 1958 2200 2201 1959 2202 /** 1960 * Checks whether the provided atom is within the tesselation structure.2203 * Finds the point which is closest to the provided one. 1961 2204 * 1962 * @param *Atom of which to check the position 1963 * @param tesselation structure 1964 * 1965 * @return true if the atom is inside the tesselation structure, false otherwise 1966 */ 1967 bool IsInnerPoint(TesselPoint *Atom, class Tesselation *Tess, LinkedCell* LC) 1968 { 1969 if (Tess->LinesOnBoundary.begin() == Tess->LinesOnBoundary.end()) { 1970 cout << Verbose(0) << "Error: There is no tesselation structure to compare the point with, " 1971 << "please create one first."; 1972 exit(1); 1973 } 1974 1975 class TesselPoint *trianglePoints[3]; 1976 trianglePoints[0] = findClosestAtom(Atom, LC); 1977 // check whether closest atom is "too close" :), then it's inside 1978 if (trianglePoints[0]->node->DistanceSquared(Atom->node) < MYEPSILON) 1979 return true; 1980 list<TesselPoint*> *connectedClosestPoints = Tess->getClosestConnectedAtoms(trianglePoints[0], Atom); 1981 trianglePoints[1] = connectedClosestPoints->front(); 1982 trianglePoints[2] = connectedClosestPoints->back(); 1983 for (int i=0;i<3;i++) { 1984 if (trianglePoints[i] == NULL) { 1985 cout << Verbose(1) << "IsInnerPoint encounters serious error, point " << i << " not found." << endl; 1986 } 1987 1988 cout << Verbose(1) << "List of possible atoms:" << endl; 1989 cout << *trianglePoints[i] << endl; 1990 1991 // for(list<TesselPoint*>::iterator runner = connectedClosestPoints->begin(); runner != connectedClosestPoints->end(); runner++) 1992 // cout << Verbose(2) << *(*runner) << endl; 1993 } 1994 delete(connectedClosestPoints); 1995 1996 list<BoundaryTriangleSet*> *triangles = Tess->FindTriangles(trianglePoints); 1997 1998 if (triangles->empty()) { 1999 cout << Verbose(0) << "Error: There is no nearest triangle. Please check the tesselation structure."; 2000 exit(1); 2001 } 2002 2003 Vector helper; 2004 helper.CopyVector(Atom->node); 2005 2006 // Only in case of degeneration, there will be two different scalar products. 2007 // If at least one scalar product is positive, the point is considered to be outside. 2008 bool status = (helper.ScalarProduct(&triangles->front()->NormalVector) < 0) 2009 && (helper.ScalarProduct(&triangles->back()->NormalVector) < 0); 2010 delete(triangles); 2011 return status; 2012 } 2013 2014 /** 2015 * Finds the atom which is closest to the provided one. 2016 * 2017 * @param atom to which to find the closest other atom 2205 * @param Point to which to find the closest other point 2018 2206 * @param linked cell structure 2019 2207 * 2020 * @return atomwhich is closest to the provided one2021 */ 2022 TesselPoint* findClosest Atom(const TesselPoint* Atom, LinkedCell* LC)2208 * @return point which is closest to the provided one 2209 */ 2210 TesselPoint* findClosestPoint(const Vector* Point, LinkedCell* LC) 2023 2211 { 2024 2212 LinkedNodes *List = NULL; 2025 TesselPoint* closest Atom= NULL;2213 TesselPoint* closestPoint = NULL; 2026 2214 double distance = 1e16; 2027 2215 Vector helper; 2028 2216 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 2029 2217 2030 LC->SetIndexToVector( Atom->node); // ignore status as we calculate bounds below sensibly2218 LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly 2031 2219 for(int i=0;i<NDIM;i++) // store indices of this cell 2032 2220 N[i] = LC->n[i]; … … 2042 2230 if (List != NULL) { 2043 2231 for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) { 2044 helper.CopyVector( Atom->node);2232 helper.CopyVector(Point); 2045 2233 helper.SubtractVector((*Runner)->node); 2046 2234 double currentNorm = helper. Norm(); 2047 2235 if (currentNorm < distance) { 2048 2236 distance = currentNorm; 2049 closest Atom= (*Runner);2237 closestPoint = (*Runner); 2050 2238 } 2051 2239 } … … 2056 2244 } 2057 2245 2058 return closestAtom; 2059 } 2246 return closestPoint; 2247 } 2248 2060 2249 2061 2250 /** 2062 * Gets all atoms connected to the provided atom by triangulation lines.2251 * Finds triangles belonging to the three provided points. 2063 2252 * 2064 * @param atom of which get all connected atoms 2065 * @param atom to be checked whether it is an inner atom 2253 * @param *Points[3] list, is expected to contain three points 2066 2254 * 2067 * @return list of the two atoms linked to the provided one and closest to the atom to be checked, 2068 */ 2069 list<TesselPoint*> * Tesselation::getClosestConnectedAtoms(TesselPoint* Atom, TesselPoint* AtomToCheck) 2070 { 2071 list<TesselPoint*> connectedAtoms; 2072 map<double, TesselPoint*> anglesOfAtoms; 2073 map<double, TesselPoint*>::iterator runner; 2074 LineMap::iterator findLines = LinesOnBoundary.begin(); 2075 list<TesselPoint*>::iterator listRunner; 2076 Vector center, planeNorm, currentPoint, OrthogonalVector, helper; 2077 TesselPoint* current; 2078 bool takeAtom = false; 2079 2080 planeNorm.CopyVector(Atom->node); 2081 planeNorm.SubtractVector(AtomToCheck->node); 2082 planeNorm.Normalize(); 2083 2084 while (findLines != LinesOnBoundary.end()) { 2085 takeAtom = false; 2086 2087 if (findLines->second->endpoints[0]->Nr == Atom->nr) { 2088 takeAtom = true; 2089 current = findLines->second->endpoints[1]->node; 2090 } else if (findLines->second->endpoints[1]->Nr == Atom->nr) { 2091 takeAtom = true; 2092 current = findLines->second->endpoints[0]->node; 2093 } 2094 2095 if (takeAtom) { 2096 connectedAtoms.push_back(current); 2097 currentPoint.CopyVector(current->node); 2098 currentPoint.ProjectOntoPlane(&planeNorm); 2099 center.AddVector(¤tPoint); 2100 } 2101 2102 findLines++; 2103 } 2104 2105 cout << "Summed vectors " << center << "; number of atoms " << connectedAtoms.size() 2106 << "; scale factor " << 1.0/connectedAtoms.size(); 2107 2108 center.Scale(1.0/connectedAtoms.size()); 2109 listRunner = connectedAtoms.begin(); 2110 2111 cout << " calculated center " << center << endl; 2112 2113 // construct one orthogonal vector 2114 helper.CopyVector(AtomToCheck->node); 2115 helper.ProjectOntoPlane(&planeNorm); 2116 OrthogonalVector.MakeNormalVector(¢er, &helper, (*listRunner)->node); 2117 while (listRunner != connectedAtoms.end()) { 2118 double angle = getAngle(*((*listRunner)->node), *(AtomToCheck->node), center, OrthogonalVector); 2119 cout << "Calculated angle " << angle << " for atom " << **listRunner << endl; 2120 anglesOfAtoms.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 2121 listRunner++; 2122 } 2123 2124 list<TesselPoint*> *result = new list<TesselPoint*>; 2125 runner = anglesOfAtoms.begin(); 2126 cout << "First value is " << *runner->second << endl; 2127 result->push_back(runner->second); 2128 runner = anglesOfAtoms.end(); 2129 runner--; 2130 cout << "Second value is " << *runner->second << endl; 2131 result->push_back(runner->second); 2132 2133 cout << "List of closest atoms has " << result->size() << " elements, which are " 2134 << *(result->front()) << " and " << *(result->back()) << endl; 2135 2136 return result; 2137 } 2138 2139 /** 2140 * Finds triangles belonging to the three provided atoms. 2141 * 2142 * @param atom list, is expected to contain three atoms 2143 * 2144 * @return triangles which belong to the provided atoms, will be empty if there are none, 2255 * @return triangles which belong to the provided points, will be empty if there are none, 2145 2256 * will usually be one, in case of degeneration, there will be two 2146 2257 */ … … 2202 2313 } 2203 2314 2204 /** 2205 * Gets the angle between a point and a reference relative to the provided center.2206 * 2315 /** Gets the angle between a point and a reference relative to the provided center. 2316 * We have two shanks (point, center) and (reference, center) between which the angle is calculated 2317 * and by scalar product with OrthogonalVector we decide the interval. 2207 2318 * @param point to calculate the angle for 2208 2319 * @param reference to which to calculate the angle 2209 2320 * @param center for which to calculate the angle between the vectors 2210 * @param OrthogonalVector helps discern between [0,pi] and [pi,2pi] in acos()2321 * @param OrthogonalVector points in direction of [pi,2pi] interval 2211 2322 * 2212 2323 * @return angle between point and reference 2213 2324 */ 2214 double getAngle( Vector point, Vector reference, Vector center, Vector OrthogonalVector)2325 double getAngle(const Vector &point, const Vector &reference, const Vector ¢er, Vector OrthogonalVector) 2215 2326 { 2216 2327 Vector ReferenceVector, helper; 2217 cout << Verbose(2) << reference << " is our reference " << endl; 2218 cout << Verbose(2) << center << " is our center " << endl; 2328 cout << Verbose(4) << center << " is our center " << endl; 2219 2329 // create baseline vector 2220 2330 ReferenceVector.CopyVector(&reference); 2221 2331 ReferenceVector.SubtractVector(¢er); 2332 OrthogonalVector.MakeNormalVector(&ReferenceVector); 2333 cout << Verbose(4) << ReferenceVector << " is our reference " << endl; 2222 2334 if (ReferenceVector.IsNull()) 2223 2335 return M_PI; … … 2233 2345 } 2234 2346 2235 cout << Verbose( 2) << point << " has angle " << phi<< endl;2347 cout << Verbose(3) << helper << " has angle " << phi << " with respect to reference." << endl; 2236 2348 2237 2349 return phi; 2238 2350 } 2239 2351 2240 /**2241 * Checks whether the provided point is within the tesselation structure.2242 *2243 * This is a wrapper function for IsInnerAtom, so it can be used with a simple2244 * vector, too.2245 *2246 * @param point of which to check the position2247 * @param tesselation structure2248 *2249 * @return true if the point is inside the tesselation structure, false otherwise2250 */2251 bool IsInnerPoint(Vector Point, class Tesselation *Tess, LinkedCell* LC)2252 {2253 TesselPoint *temp_atom = new TesselPoint;2254 bool status = false;2255 temp_atom->node->CopyVector(&Point);2256 2257 status = IsInnerPoint(temp_atom, Tess, LC);2258 delete(temp_atom);2259 2260 return status;2261 }2262
Note:
See TracChangeset
for help on using the changeset viewer.