Changes in src/tesselationhelpers.cpp [f66195:658efb]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/tesselationhelpers.cpp
rf66195 r658efb 6 6 */ 7 7 8 #include <fstream>9 10 #include "linkedcell.hpp"11 #include "tesselation.hpp"12 8 #include "tesselationhelpers.hpp" 13 #include "vector.hpp" 14 #include "verbose.hpp" 15 16 double DetGet(gsl_matrix *A, int inPlace) { 9 10 double det_get(gsl_matrix *A, int inPlace) { 17 11 /* 18 12 inPlace = 1 => A is replaced with the LU decomposed copy. … … 42 36 }; 43 37 44 void GetSphere(Vector *center, Vector &a, Vector &b, Vector &c, double RADIUS)38 void get_sphere(Vector *center, Vector &a, Vector &b, Vector &c, double RADIUS) 45 39 { 46 40 gsl_matrix *A = gsl_matrix_calloc(3,3); … … 52 46 gsl_matrix_set(A, i, 2, c.x[i]); 53 47 } 54 m11 = DetGet(A, 1);48 m11 = det_get(A, 1); 55 49 56 50 for(int i=0;i<3;i++) { … … 59 53 gsl_matrix_set(A, i, 2, c.x[i]); 60 54 } 61 m12 = DetGet(A, 1);55 m12 = det_get(A, 1); 62 56 63 57 for(int i=0;i<3;i++) { … … 66 60 gsl_matrix_set(A, i, 2, c.x[i]); 67 61 } 68 m13 = DetGet(A, 1);62 m13 = det_get(A, 1); 69 63 70 64 for(int i=0;i<3;i++) { … … 73 67 gsl_matrix_set(A, i, 2, b.x[i]); 74 68 } 75 m14 = DetGet(A, 1);69 m14 = det_get(A, 1); 76 70 77 71 if (fabs(m11) < MYEPSILON) … … 107 101 * @param Umkreisradius double radius of circumscribing circle 108 102 */ 109 void Get CenterOfSphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection,103 void Get_center_of_sphere(Vector* Center, Vector a, Vector b, Vector c, Vector *NewUmkreismittelpunkt, Vector* Direction, Vector* AlternativeDirection, 110 104 double HalfplaneIndicator, double AlternativeIndicator, double alpha, double beta, double gamma, double RADIUS, double Umkreisradius) 111 105 { … … 113 107 double Restradius; 114 108 Vector OtherCenter; 115 cout << Verbose(3) << "Begin of Get CenterOfSphere.\n";109 cout << Verbose(3) << "Begin of Get_center_of_sphere.\n"; 116 110 Center->Zero(); 117 111 helper.CopyVector(&a); … … 159 153 Center->AddVector(&TempNormal); 160 154 cout << Verbose(0) << "Center of sphere of circumference is " << *Center << ".\n"; 161 GetSphere(&OtherCenter, a, b, c, RADIUS);155 get_sphere(&OtherCenter, a, b, c, RADIUS); 162 156 cout << Verbose(0) << "OtherCenter of sphere of circumference is " << OtherCenter << ".\n"; 163 cout << Verbose(3) << "End of Get CenterOfSphere.\n";157 cout << Verbose(3) << "End of Get_center_of_sphere.\n"; 164 158 }; 165 159 … … 313 307 gsl_multimin_fminimizer *s = NULL; 314 308 gsl_vector *ss, *x; 315 gsl_multimin_function minex Function;309 gsl_multimin_function minex_func; 316 310 317 311 size_t iter = 0; … … 330 324 331 325 /* Initialize method and iterate */ 332 minex Function.n = NDIM;333 minex Function.f = &MinIntersectDistance;334 minex Function.params = (void *)∥326 minex_func.n = NDIM; 327 minex_func.f = &MinIntersectDistance; 328 minex_func.params = (void *)∥ 335 329 336 330 s = gsl_multimin_fminimizer_alloc(T, NDIM); 337 gsl_multimin_fminimizer_set(s, &minex Function, x, ss);331 gsl_multimin_fminimizer_set(s, &minex_func, x, ss); 338 332 339 333 do { … … 392 386 393 387 return result; 394 };395 396 /** Gets the angle between a point and a reference relative to the provided center.397 * We have two shanks point and reference between which the angle is calculated398 * and by scalar product with OrthogonalVector we decide the interval.399 * @param point to calculate the angle for400 * @param reference to which to calculate the angle401 * @param OrthogonalVector points in direction of [pi,2pi] interval402 *403 * @return angle between point and reference404 */405 double GetAngle(const Vector &point, const Vector &reference, const Vector OrthogonalVector)406 {407 if (reference.IsZero())408 return M_PI;409 410 // calculate both angles and correct with in-plane vector411 if (point.IsZero())412 return M_PI;413 double phi = point.Angle(&reference);414 if (OrthogonalVector.ScalarProduct(&point) > 0) {415 phi = 2.*M_PI - phi;416 }417 418 cout << Verbose(4) << "INFO: " << point << " has angle " << phi << " with respect to reference " << reference << "." << endl;419 420 return phi;421 388 } 422 389 423 424 /** Calculates the volume of a general tetraeder.425 * \param *a first vector426 * \param *a first vector427 * \param *a first vector428 * \param *a first vector429 * \return \f$ \frac{1}{6} \cdot ((a-d) \times (a-c) \cdot (a-b)) \f$430 */431 double CalculateVolumeofGeneralTetraeder(Vector *a, Vector *b, Vector *c, Vector *d)432 {433 Vector Point, TetraederVector[3];434 double volume;435 436 TetraederVector[0].CopyVector(a);437 TetraederVector[1].CopyVector(b);438 TetraederVector[2].CopyVector(c);439 for (int j=0;j<3;j++)440 TetraederVector[j].SubtractVector(d);441 Point.CopyVector(&TetraederVector[0]);442 Point.VectorProduct(&TetraederVector[1]);443 volume = 1./6. * fabs(Point.ScalarProduct(&TetraederVector[2]));444 return volume;445 };446 447 448 /** Checks for a new special triangle whether one of its edges is already present with one one triangle connected.449 * This enforces that special triangles (i.e. degenerated ones) should at last close the open-edge frontier and not450 * make it bigger (i.e. closing one (the baseline) and opening two new ones).451 * \param TPS[3] nodes of the triangle452 * \return true - there is such a line (i.e. creation of degenerated triangle is valid), false - no such line (don't create)453 */454 bool CheckLineCriteriaForDegeneratedTriangle(class BoundaryPointSet *nodes[3])455 {456 bool result = false;457 int counter = 0;458 459 // check all three points460 for (int i=0;i<3;i++)461 for (int j=i+1; j<3; j++) {462 if (nodes[i]->lines.find(nodes[j]->node->nr) != nodes[i]->lines.end()) { // there already is a line463 LineMap::iterator FindLine;464 pair<LineMap::iterator,LineMap::iterator> FindPair;465 FindPair = nodes[i]->lines.equal_range(nodes[j]->node->nr);466 for (FindLine = FindPair.first; FindLine != FindPair.second; ++FindLine) {467 // If there is a line with less than two attached triangles, we don't need a new line.468 if (FindLine->second->triangles.size() < 2) {469 counter++;470 break; // increase counter only once per edge471 }472 }473 } else { // no line474 cout << Verbose(1) << "The line between " << *nodes[i] << " and " << *nodes[j] << " is not yet present, hence no need for a degenerate triangle." << endl;475 result = true;476 }477 }478 if ((!result) && (counter > 1)) {479 cout << Verbose(2) << "INFO: Degenerate triangle is ok, at least two, here " << counter << ", existing lines are used." << endl;480 result = true;481 }482 return result;483 };484 485 486 /** Sort function for the candidate list.487 */488 bool SortCandidates(CandidateForTesselation* candidate1, CandidateForTesselation* candidate2)489 {490 Vector BaseLineVector, OrthogonalVector, helper;491 if (candidate1->BaseLine != candidate2->BaseLine) { // sanity check492 cout << Verbose(0) << "ERROR: sortCandidates was called for two different baselines: " << candidate1->BaseLine << " and " << candidate2->BaseLine << "." << endl;493 //return false;494 exit(1);495 }496 // create baseline vector497 BaseLineVector.CopyVector(candidate1->BaseLine->endpoints[1]->node->node);498 BaseLineVector.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);499 BaseLineVector.Normalize();500 501 // 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!)502 helper.CopyVector(candidate1->BaseLine->endpoints[0]->node->node);503 helper.SubtractVector(candidate1->point->node);504 OrthogonalVector.CopyVector(&helper);505 helper.VectorProduct(&BaseLineVector);506 OrthogonalVector.SubtractVector(&helper);507 OrthogonalVector.Normalize();508 509 // calculate both angles and correct with in-plane vector510 helper.CopyVector(candidate1->point->node);511 helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);512 double phi = BaseLineVector.Angle(&helper);513 if (OrthogonalVector.ScalarProduct(&helper) > 0) {514 phi = 2.*M_PI - phi;515 }516 helper.CopyVector(candidate2->point->node);517 helper.SubtractVector(candidate1->BaseLine->endpoints[0]->node->node);518 double psi = BaseLineVector.Angle(&helper);519 if (OrthogonalVector.ScalarProduct(&helper) > 0) {520 psi = 2.*M_PI - psi;521 }522 523 cout << Verbose(2) << *candidate1->point << " has angle " << phi << endl;524 cout << Verbose(2) << *candidate2->point << " has angle " << psi << endl;525 526 // return comparison527 return phi < psi;528 };529 530 /**531 * Finds the point which is second closest to the provided one.532 *533 * @param Point to which to find the second closest other point534 * @param linked cell structure535 *536 * @return point which is second closest to the provided one537 */538 TesselPoint* FindSecondClosestPoint(const Vector* Point, LinkedCell* LC)539 {540 LinkedNodes *List = NULL;541 TesselPoint* closestPoint = NULL;542 TesselPoint* secondClosestPoint = NULL;543 double distance = 1e16;544 double secondDistance = 1e16;545 Vector helper;546 int N[NDIM], Nlower[NDIM], Nupper[NDIM];547 548 LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly549 for(int i=0;i<NDIM;i++) // store indices of this cell550 N[i] = LC->n[i];551 cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;552 553 LC->GetNeighbourBounds(Nlower, Nupper);554 //cout << endl;555 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)556 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)557 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {558 List = LC->GetCurrentCell();559 //cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;560 if (List != NULL) {561 for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {562 helper.CopyVector(Point);563 helper.SubtractVector((*Runner)->node);564 double currentNorm = helper. Norm();565 if (currentNorm < distance) {566 // remember second point567 secondDistance = distance;568 secondClosestPoint = closestPoint;569 // mark down new closest point570 distance = currentNorm;571 closestPoint = (*Runner);572 //cout << Verbose(2) << "INFO: New Second Nearest Neighbour is " << *secondClosestPoint << "." << endl;573 }574 }575 } else {576 cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << ","577 << LC->n[2] << " is invalid!" << endl;578 }579 }580 581 return secondClosestPoint;582 };583 584 /**585 * Finds the point which is closest to the provided one.586 *587 * @param Point to which to find the closest other point588 * @param SecondPoint the second closest other point on return, NULL if none found589 * @param linked cell structure590 *591 * @return point which is closest to the provided one, NULL if none found592 */593 TesselPoint* FindClosestPoint(const Vector* Point, TesselPoint *&SecondPoint, LinkedCell* LC)594 {595 LinkedNodes *List = NULL;596 TesselPoint* closestPoint = NULL;597 SecondPoint = NULL;598 double distance = 1e16;599 double secondDistance = 1e16;600 Vector helper;601 int N[NDIM], Nlower[NDIM], Nupper[NDIM];602 603 LC->SetIndexToVector(Point); // ignore status as we calculate bounds below sensibly604 for(int i=0;i<NDIM;i++) // store indices of this cell605 N[i] = LC->n[i];606 cout << Verbose(3) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;607 608 LC->GetNeighbourBounds(Nlower, Nupper);609 //cout << endl;610 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)611 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)612 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {613 List = LC->GetCurrentCell();614 //cout << Verbose(3) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl;615 if (List != NULL) {616 for (LinkedNodes::iterator Runner = List->begin(); Runner != List->end(); Runner++) {617 helper.CopyVector(Point);618 helper.SubtractVector((*Runner)->node);619 double currentNorm = helper. Norm();620 if (currentNorm < distance) {621 secondDistance = distance;622 SecondPoint = closestPoint;623 distance = currentNorm;624 closestPoint = (*Runner);625 //cout << Verbose(2) << "INFO: New Nearest Neighbour is " << *closestPoint << "." << endl;626 } else if (currentNorm < secondDistance) {627 secondDistance = currentNorm;628 SecondPoint = (*Runner);629 //cout << Verbose(2) << "INFO: New Second Nearest Neighbour is " << *SecondPoint << "." << endl;630 }631 }632 } else {633 cerr << "ERROR: The current cell " << LC->n[0] << "," << LC->n[1] << ","634 << LC->n[2] << " is invalid!" << endl;635 }636 }637 638 return closestPoint;639 };640 641 /** Returns the closest point on \a *Base with respect to \a *OtherBase.642 * \param *out output stream for debugging643 * \param *Base reference line644 * \param *OtherBase other base line645 * \return Vector on reference line that has closest distance646 */647 Vector * GetClosestPointBetweenLine(ofstream *out, class BoundaryLineSet *Base, class BoundaryLineSet *OtherBase)648 {649 // construct the plane of the two baselines (i.e. take both their directional vectors)650 Vector Normal;651 Vector Baseline, OtherBaseline;652 Baseline.CopyVector(Base->endpoints[1]->node->node);653 Baseline.SubtractVector(Base->endpoints[0]->node->node);654 OtherBaseline.CopyVector(OtherBase->endpoints[1]->node->node);655 OtherBaseline.SubtractVector(OtherBase->endpoints[0]->node->node);656 Normal.CopyVector(&Baseline);657 Normal.VectorProduct(&OtherBaseline);658 Normal.Normalize();659 *out << Verbose(4) << "First direction is " << Baseline << ", second direction is " << OtherBaseline << ", normal of intersection plane is " << Normal << "." << endl;660 661 // project one offset point of OtherBase onto this plane (and add plane offset vector)662 Vector NewOffset;663 NewOffset.CopyVector(OtherBase->endpoints[0]->node->node);664 NewOffset.SubtractVector(Base->endpoints[0]->node->node);665 NewOffset.ProjectOntoPlane(&Normal);666 NewOffset.AddVector(Base->endpoints[0]->node->node);667 Vector NewDirection;668 NewDirection.CopyVector(&NewOffset);669 NewDirection.AddVector(&OtherBaseline);670 671 // calculate the intersection between this projected baseline and Base672 Vector *Intersection = new Vector;673 Intersection->GetIntersectionOfTwoLinesOnPlane(out, Base->endpoints[0]->node->node, Base->endpoints[1]->node->node, &NewOffset, &NewDirection, &Normal);674 Normal.CopyVector(Intersection);675 Normal.SubtractVector(Base->endpoints[0]->node->node);676 *out << Verbose(3) << "Found closest point on " << *Base << " at " << *Intersection << ", factor in line is " << fabs(Normal.ScalarProduct(&Baseline)/Baseline.NormSquared()) << "." << endl;677 678 return Intersection;679 };680 681 682 /** Creates the objects in a VRML file.683 * \param *out output stream for debugging684 * \param *vrmlfile output stream for tecplot data685 * \param *Tess Tesselation structure with constructed triangles686 * \param *mol molecule structure with atom positions687 */688 void WriteVrmlFile(ofstream *out, ofstream *vrmlfile, class Tesselation *Tess, PointCloud *cloud)689 {690 TesselPoint *Walker = NULL;691 int i;692 Vector *center = cloud->GetCenter(out);693 if (vrmlfile != NULL) {694 //cout << Verbose(1) << "Writing Raster3D file ... ";695 *vrmlfile << "#VRML V2.0 utf8" << endl;696 *vrmlfile << "#Created by molecuilder" << endl;697 *vrmlfile << "#All atoms as spheres" << endl;698 cloud->GoToFirst();699 while (!cloud->IsEnd()) {700 Walker = cloud->GetPoint();701 *vrmlfile << "Sphere {" << endl << " "; // 2 is sphere type702 for (i=0;i<NDIM;i++)703 *vrmlfile << Walker->node->x[i]-center->x[i] << " ";704 *vrmlfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour705 cloud->GoToNext();706 }707 708 *vrmlfile << "# All tesselation triangles" << endl;709 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {710 *vrmlfile << "1" << endl << " "; // 1 is triangle type711 for (i=0;i<3;i++) { // print each node712 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates713 *vrmlfile << TriangleRunner->second->endpoints[i]->node->node->x[j]-center->x[j] << " ";714 *vrmlfile << "\t";715 }716 *vrmlfile << "1. 0. 0." << endl; // red as colour717 *vrmlfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object718 }719 } else {720 cerr << "ERROR: Given vrmlfile is " << vrmlfile << "." << endl;721 }722 delete(center);723 };724 725 /** Writes additionally the current sphere (i.e. the last triangle to file).726 * \param *out output stream for debugging727 * \param *rasterfile output stream for tecplot data728 * \param *Tess Tesselation structure with constructed triangles729 * \param *mol molecule structure with atom positions730 */731 void IncludeSphereinRaster3D(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud)732 {733 Vector helper;734 // include the current position of the virtual sphere in the temporary raster3d file735 Vector *center = cloud->GetCenter(out);736 // make the circumsphere's center absolute again737 helper.CopyVector(Tess->LastTriangle->endpoints[0]->node->node);738 helper.AddVector(Tess->LastTriangle->endpoints[1]->node->node);739 helper.AddVector(Tess->LastTriangle->endpoints[2]->node->node);740 helper.Scale(1./3.);741 helper.SubtractVector(center);742 // and add to file plus translucency object743 *rasterfile << "# current virtual sphere\n";744 *rasterfile << "8\n 25.0 0.6 -1.0 -1.0 -1.0 0.2 0 0 0 0\n";745 *rasterfile << "2\n " << helper.x[0] << " " << helper.x[1] << " " << helper.x[2] << "\t" << 5. << "\t1 0 0\n";746 *rasterfile << "9\n terminating special property\n";747 delete(center);748 };749 750 /** Creates the objects in a raster3d file (renderable with a header.r3d).751 * \param *out output stream for debugging752 * \param *rasterfile output stream for tecplot data753 * \param *Tess Tesselation structure with constructed triangles754 * \param *mol molecule structure with atom positions755 */756 void WriteRaster3dFile(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, PointCloud *cloud)757 {758 TesselPoint *Walker = NULL;759 int i;760 Vector *center = cloud->GetCenter(out);761 if (rasterfile != NULL) {762 //cout << Verbose(1) << "Writing Raster3D file ... ";763 *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl;764 *rasterfile << "@header.r3d" << endl;765 *rasterfile << "# All atoms as spheres" << endl;766 cloud->GoToFirst();767 while (!cloud->IsEnd()) {768 Walker = cloud->GetPoint();769 *rasterfile << "2" << endl << " "; // 2 is sphere type770 for (i=0;i<NDIM;i++)771 *rasterfile << Walker->node->x[i]-center->x[i] << " ";772 *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour773 cloud->GoToNext();774 }775 776 *rasterfile << "# All tesselation triangles" << endl;777 *rasterfile << "8\n 25. -1. 1. 1. 1. 0.0 0 0 0 2\n SOLID 1.0 0.0 0.0\n BACKFACE 0.3 0.3 1.0 0 0\n";778 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {779 *rasterfile << "1" << endl << " "; // 1 is triangle type780 for (i=0;i<3;i++) { // print each node781 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates782 *rasterfile << TriangleRunner->second->endpoints[i]->node->node->x[j]-center->x[j] << " ";783 *rasterfile << "\t";784 }785 *rasterfile << "1. 0. 0." << endl; // red as colour786 //*rasterfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object787 }788 *rasterfile << "9\n# terminating special property\n";789 } else {790 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl;791 }792 IncludeSphereinRaster3D(out, rasterfile, Tess, cloud);793 delete(center);794 };795 796 /** This function creates the tecplot file, displaying the tesselation of the hull.797 * \param *out output stream for debugging798 * \param *tecplot output stream for tecplot data799 * \param N arbitrary number to differentiate various zones in the tecplot format800 */801 void WriteTecplotFile(ofstream *out, ofstream *tecplot, class Tesselation *TesselStruct, PointCloud *cloud, int N)802 {803 if ((tecplot != NULL) && (TesselStruct != NULL)) {804 // write header805 *tecplot << "TITLE = \"3D CONVEX SHELL\"" << endl;806 *tecplot << "VARIABLES = \"X\" \"Y\" \"Z\" \"U\"" << endl;807 *tecplot << "ZONE T=\"" << N << "-";808 for (int i=0;i<3;i++)809 *tecplot << (i==0 ? "" : "_") << TesselStruct->LastTriangle->endpoints[i]->node->Name;810 *tecplot << "\", N=" << TesselStruct->PointsOnBoundary.size() << ", E=" << TesselStruct->TrianglesOnBoundary.size() << ", DATAPACKING=POINT, ZONETYPE=FETRIANGLE" << endl;811 int i=0;812 for (cloud->GoToFirst(); !cloud->IsEnd(); cloud->GoToNext(), i++);813 int *LookupList = new int[i];814 for (cloud->GoToFirst(), i=0; !cloud->IsEnd(); cloud->GoToNext(), i++)815 LookupList[i] = -1;816 817 // print atom coordinates818 *out << Verbose(2) << "The following triangles were created:";819 int Counter = 1;820 TesselPoint *Walker = NULL;821 for (PointMap::iterator target = TesselStruct->PointsOnBoundary.begin(); target != TesselStruct->PointsOnBoundary.end(); target++) {822 Walker = target->second->node;823 LookupList[Walker->nr] = Counter++;824 *tecplot << Walker->node->x[0] << " " << Walker->node->x[1] << " " << Walker->node->x[2] << " " << target->second->value << endl;825 }826 *tecplot << endl;827 // print connectivity828 for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) {829 *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name;830 *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl;831 }832 delete[] (LookupList);833 *out << endl;834 }835 };836 837 /** Calculates the concavity for each of the BoundaryPointSet's in a Tesselation.838 * Sets BoundaryPointSet::value equal to the number of connected lines that are not convex.839 * \param *out output stream for debugging840 * \param *TesselStruct pointer to Tesselation structure841 */842 void CalculateConcavityPerBoundaryPoint(ofstream *out, class Tesselation *TesselStruct)843 {844 class BoundaryPointSet *point = NULL;845 class BoundaryLineSet *line = NULL;846 847 //*out << Verbose(2) << "Begin of CalculateConcavityPerBoundaryPoint" << endl;848 // calculate remaining concavity849 for (PointMap::iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) {850 point = PointRunner->second;851 *out << Verbose(1) << "INFO: Current point is " << *point << "." << endl;852 point->value = 0;853 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) {854 line = LineRunner->second;855 //*out << Verbose(2) << "INFO: Current line of point " << *point << " is " << *line << "." << endl;856 if (!line->CheckConvexityCriterion(out))857 point->value += 1;858 }859 }860 //*out << Verbose(2) << "End of CalculateConcavityPerBoundaryPoint" << endl;861 };862 863 864 /** Checks whether each BoundaryLineSet in the Tesselation has two triangles.865 * \param *out output stream for debugging866 * \param *TesselStruct867 * \return true - all have exactly two triangles, false - some not, list is printed to screen868 */869 bool CheckListOfBaselines(ofstream *out, Tesselation *TesselStruct)870 {871 LineMap::iterator testline;872 bool result = false;873 int counter = 0;874 875 *out << Verbose(1) << "Check: List of Baselines with not two connected triangles:" << endl;876 for (testline = TesselStruct->LinesOnBoundary.begin(); testline != TesselStruct->LinesOnBoundary.end(); testline++) {877 if (testline->second->triangles.size() != 2) {878 *out << Verbose(1) << *testline->second << "\t" << testline->second->triangles.size() << endl;879 counter++;880 }881 }882 if (counter == 0) {883 *out << Verbose(1) << "None." << endl;884 result = true;885 }886 return result;887 }888
Note:
See TracChangeset
for help on using the changeset viewer.