Changeset ce5ac3 for src/boundary.cpp
- Timestamp:
- Jul 23, 2009, 12:32:48 PM (16 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, Candidate_v1.7.0, 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:
- d067d45
- Parents:
- 986c80
- File:
-
- 1 edited
-
src/boundary.cpp (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/boundary.cpp
r986c80 rce5ac3 86 86 BoundaryLineSet::~BoundaryLineSet() 87 87 { 88 for (int i = 0; i < 2; i++) {89 cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;90 endpoints[i]->lines.erase(Nr);91 LineMap::iterator tester = endpoints[i]->lines.begin();92 tester++;93 if (tester == endpoints[i]->lines.end()) {94 cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl;95 if (endpoints[i] != NULL) {96 delete(endpoints[i]);97 endpoints[i] = NULL;98 } else99 cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl;100 } else101 cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl;102 }88 for (int i = 0; i < 2; i++) { 89 cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 90 endpoints[i]->lines.erase(Nr); 91 LineMap::iterator tester = endpoints[i]->lines.begin(); 92 tester++; 93 if (tester == endpoints[i]->lines.end()) { 94 cout << Verbose(5) << *endpoints[i] << " has no more lines it's attached to, erasing." << endl; 95 if (endpoints[i] != NULL) { 96 delete(endpoints[i]); 97 endpoints[i] = NULL; 98 } else 99 cerr << "ERROR: Endpoint " << i << " has already been free'd." << endl; 100 } else 101 cout << Verbose(5) << *endpoints[i] << " has still lines it's attached to." << endl; 102 } 103 103 } 104 104 ; … … 181 181 BoundaryTriangleSet::~BoundaryTriangleSet() 182 182 { 183 for (int i = 0; i < 3; i++) {184 cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl;185 lines[i]->triangles.erase(Nr);186 if (lines[i]->triangles.empty()) {187 cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl;188 if (lines[i] != NULL) {189 delete (lines[i]);190 lines[i] = NULL;191 } else192 cerr << "ERROR: This line " << i << " has already been free'd." << endl;193 } else194 cout << Verbose(5) << *lines[i] << " is still attached to a triangle." << endl;195 }183 for (int i = 0; i < 3; i++) { 184 cout << Verbose(5) << "Erasing triangle Nr." << Nr << endl; 185 lines[i]->triangles.erase(Nr); 186 if (lines[i]->triangles.empty()) { 187 cout << Verbose(5) << *lines[i] << " is no more attached to any triangle, erasing." << endl; 188 if (lines[i] != NULL) { 189 delete (lines[i]); 190 lines[i] = NULL; 191 } else 192 cerr << "ERROR: This line " << i << " has already been free'd." << endl; 193 } else 194 cout << Verbose(5) << *lines[i] << " is still attached to a triangle." << endl; 195 } 196 196 } 197 197 ; … … 573 573 void write_raster3d_file(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, class molecule *mol) 574 574 { 575 atom *Walker = mol->start;576 bond *Binder = mol->first;577 int i;578 Vector *center = mol->DetermineCenterOfAll(out);579 if (rasterfile != NULL) {580 //cout << Verbose(1) << "Writing Raster3D file ... ";581 *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl;582 *rasterfile << "@header.r3d" << endl;583 *rasterfile << "# All atoms as spheres" << endl;584 while (Walker->next != mol->end) {585 Walker = Walker->next;586 *rasterfile << "2" << endl << " ";// 2 is sphere type587 for (i=0;i<NDIM;i++)588 *rasterfile << Walker->x.x[i]+center->x[i] << " ";589 *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour590 }591 592 *rasterfile << "# All bonds as vertices" << endl;593 while (Binder->next != mol->last) {594 Binder = Binder->next;595 *rasterfile << "3" << endl << " ";// 2 is round-ended cylinder type596 for (i=0;i<NDIM;i++)597 *rasterfile << Binder->leftatom->x.x[i]+center->x[i] << " ";598 *rasterfile << "\t0.03\t";599 for (i=0;i<NDIM;i++)600 *rasterfile << Binder->rightatom->x.x[i]+center->x[i] << " ";601 *rasterfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour602 }603 604 *rasterfile << "# All tesselation triangles" << endl;605 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) {606 *rasterfile << "1" << endl << " ";// 1 is triangle type607 for (i=0;i<3;i++) {// print each node608 for (int j=0;j<NDIM;j++)// and for each node all NDIM coordinates609 *rasterfile << TriangleRunner->second->endpoints[i]->node->x.x[j]+center->x[j] << " ";610 *rasterfile << "\t";611 }612 *rasterfile << "1. 0. 0." << endl;// red as colour613 *rasterfile << "18" << endl << " 0.5 0.5 0.5" << endl;// 18 is transparency type for previous object614 }615 } else {616 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl;617 }618 delete(center);575 atom *Walker = mol->start; 576 bond *Binder = mol->first; 577 int i; 578 Vector *center = mol->DetermineCenterOfAll(out); 579 if (rasterfile != NULL) { 580 //cout << Verbose(1) << "Writing Raster3D file ... "; 581 *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl; 582 *rasterfile << "@header.r3d" << endl; 583 *rasterfile << "# All atoms as spheres" << endl; 584 while (Walker->next != mol->end) { 585 Walker = Walker->next; 586 *rasterfile << "2" << endl << " "; // 2 is sphere type 587 for (i=0;i<NDIM;i++) 588 *rasterfile << Walker->x.x[i]+center->x[i] << " "; 589 *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour 590 } 591 592 *rasterfile << "# All bonds as vertices" << endl; 593 while (Binder->next != mol->last) { 594 Binder = Binder->next; 595 *rasterfile << "3" << endl << " "; // 2 is round-ended cylinder type 596 for (i=0;i<NDIM;i++) 597 *rasterfile << Binder->leftatom->x.x[i]+center->x[i] << " "; 598 *rasterfile << "\t0.03\t"; 599 for (i=0;i<NDIM;i++) 600 *rasterfile << Binder->rightatom->x.x[i]+center->x[i] << " "; 601 *rasterfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour 602 } 603 604 *rasterfile << "# All tesselation triangles" << endl; 605 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) { 606 *rasterfile << "1" << endl << " "; // 1 is triangle type 607 for (i=0;i<3;i++) { // print each node 608 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates 609 *rasterfile << TriangleRunner->second->endpoints[i]->node->x.x[j]+center->x[j] << " "; 610 *rasterfile << "\t"; 611 } 612 *rasterfile << "1. 0. 0." << endl; // red as colour 613 *rasterfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object 614 } 615 } else { 616 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl; 617 } 618 delete(center); 619 619 }; 620 620 … … 946 946 Tesselation::~Tesselation() 947 947 { 948 cout << Verbose(1) << "Free'ing TesselStruct ... " << endl;949 for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) {950 if (runner->second != NULL) {951 delete (runner->second);952 runner->second = NULL;953 } else954 cerr << "ERROR: The triangle " << runner->first << " has already been free'd." << endl;955 }956 for (LineMap::iterator runner = LinesOnBoundary.begin(); runner != LinesOnBoundary.end(); runner++) {957 if (runner->second != NULL) {958 delete (runner->second);959 runner->second = NULL;960 } else961 cerr << "ERROR: The line " << runner->first << " has already been free'd." << endl;962 }963 for (PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) {964 if (runner->second != NULL) {965 delete (runner->second);966 runner->second = NULL;967 } else968 cerr << "ERROR: The point " << runner->first << " has already been free'd." << endl;969 }948 cout << Verbose(1) << "Free'ing TesselStruct ... " << endl; 949 for (TriangleMap::iterator runner = TrianglesOnBoundary.begin(); runner != TrianglesOnBoundary.end(); runner++) { 950 if (runner->second != NULL) { 951 delete (runner->second); 952 runner->second = NULL; 953 } else 954 cerr << "ERROR: The triangle " << runner->first << " has already been free'd." << endl; 955 } 956 for (LineMap::iterator runner = LinesOnBoundary.begin(); runner != LinesOnBoundary.end(); runner++) { 957 if (runner->second != NULL) { 958 delete (runner->second); 959 runner->second = NULL; 960 } else 961 cerr << "ERROR: The line " << runner->first << " has already been free'd." << endl; 962 } 963 for (PointMap::iterator runner = PointsOnBoundary.begin(); runner != PointsOnBoundary.end(); runner++) { 964 if (runner->second != NULL) { 965 delete (runner->second); 966 runner->second = NULL; 967 } else 968 cerr << "ERROR: The point " << runner->first << " has already been free'd." << endl; 969 } 970 970 } 971 971 ; … … 1585 1585 atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol) 1586 1586 { 1587 cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";1588 cout << Verbose(3) << "Candidate is "<< *Candidate << endl;1589 cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;1590 cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;1591 cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;1592 cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;1593 /* OldNormal is normal vector on the old triangle1594 * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.1595 * Chord points from b to a!!!1596 */1597 Vector dif_a; //Vector from a to candidate1598 Vector dif_b; //Vector from b to candidate1599 Vector AngleCheck;1600 Vector TempNormal, Umkreismittelpunkt;1601 Vector Mittelpunkt;1602 1603 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius;1604 double BallAngle, AlternativeSign;1605 atom *Walker; // variable atom point1606 1607 Vector NewUmkreismittelpunkt;1608 1609 if (a != Candidate and b != Candidate and c != Candidate) {1610 cout << Verbose(3) << "We have a unique candidate!" << endl;1611 dif_a.CopyVector(&(a->x));1612 dif_a.SubtractVector(&(Candidate->x));1613 dif_b.CopyVector(&(b->x));1614 dif_b.SubtractVector(&(Candidate->x));1615 AngleCheck.CopyVector(&(Candidate->x));1616 AngleCheck.SubtractVector(&(a->x));1617 AngleCheck.ProjectOntoPlane(Chord);1618 1619 SideA = dif_b.Norm();1620 SideB = dif_a.Norm();1621 SideC = Chord->Norm();1622 //Chord->Scale(-1);1623 1624 alpha = Chord->Angle(&dif_a);1625 beta = M_PI - Chord->Angle(&dif_b);1626 gamma = dif_a.Angle(&dif_b);1627 1628 cout << Verbose(2) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;1629 1630 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) {1631 cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";1632 cout << Verbose(1) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;1633 }1634 1635 if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) {1636 Umkreisradius = SideA / 2.0 / sin(alpha);1637 //cout << Umkreisradius << endl;1638 //cout << SideB / 2.0 / sin(beta) << endl;1639 //cout << SideC / 2.0 / sin(gamma) << endl;1640 1641 if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points.1642 cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;1643 cout << Verbose(2) << "Candidate is "<< *Candidate << endl;1644 sign = AngleCheck.ScalarProduct(direction1);1645 if (fabs(sign)<MYEPSILON) {1646 if (AngleCheck.ScalarProduct(OldNormal)<0) {1647 sign =0;1648 AlternativeSign=1;1649 } else {1650 sign =0;1651 AlternativeSign=-1;1652 }1653 } else {1654 sign /= fabs(sign);1655 cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;1656 }1657 1658 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);1659 1660 AngleCheck.CopyVector(&ReferencePoint);1661 AngleCheck.Scale(-1);1662 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;1663 AngleCheck.AddVector(&Mittelpunkt);1664 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;1665 cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl;1666 1667 BallAngle = AngleCheck.Angle(OldNormal);1668 cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;1669 1670 //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl;1671 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl;1672 1673 cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;1674 1675 NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);1676 1677 if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {1678 if (Storage[0]< -1.5) { // first Candidate at all1679 if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {1680 cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";1681 Opt_Candidate = Candidate;1682 Storage[0] = sign;1683 Storage[1] = AlternativeSign;1684 Storage[2] = BallAngle;1685 cout << " angle " << Storage[2] << " and Up/Down "1686 << Storage[0] << endl;1687 } else1688 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;1689 } else {1690 if ( Storage[2] > BallAngle) {1691 if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {1692 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";1693 Opt_Candidate = Candidate;1694 Storage[0] = sign;1695 Storage[1] = AlternativeSign;1696 Storage[2] = BallAngle;1697 cout << " angle " << Storage[2] << " and Up/Down "1698 << Storage[0] << endl;1699 } else1700 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;1701 } else {1702 if (DEBUG) {1703 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;1704 }1705 }1706 }1707 } else {1708 if (DEBUG) {1709 cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;1710 }1711 }1712 } else {1713 if (DEBUG) {1714 cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;1715 }1716 }1717 } else {1718 if (DEBUG) {1719 cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl;1720 }1721 }1722 } else {1723 if (DEBUG) {1724 cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;1725 }1726 }1727 1728 if (RecursionLevel < 5) { // Seven is the recursion level threshold.1729 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond1730 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);1731 if (Walker == Parent) { // don't go back the same bond1732 continue;1733 } else {1734 Find_next_suitable_point_via_Angle_of_Sphere(a, b, c, Walker, Candidate, RecursionLevel+1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS, mol); //call function again1735 }1736 }1737 }1738 cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";1587 cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n"; 1588 cout << Verbose(3) << "Candidate is "<< *Candidate << endl; 1589 cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl; 1590 cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl; 1591 cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl; 1592 cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl; 1593 /* OldNormal is normal vector on the old triangle 1594 * direction1 is normal on the triangle line, from which we come, as well as on OldNormal. 1595 * Chord points from b to a!!! 1596 */ 1597 Vector dif_a; //Vector from a to candidate 1598 Vector dif_b; //Vector from b to candidate 1599 Vector AngleCheck; 1600 Vector TempNormal, Umkreismittelpunkt; 1601 Vector Mittelpunkt; 1602 1603 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius; 1604 double BallAngle, AlternativeSign; 1605 atom *Walker; // variable atom point 1606 1607 Vector NewUmkreismittelpunkt; 1608 1609 if (a != Candidate and b != Candidate and c != Candidate) { 1610 cout << Verbose(3) << "We have a unique candidate!" << endl; 1611 dif_a.CopyVector(&(a->x)); 1612 dif_a.SubtractVector(&(Candidate->x)); 1613 dif_b.CopyVector(&(b->x)); 1614 dif_b.SubtractVector(&(Candidate->x)); 1615 AngleCheck.CopyVector(&(Candidate->x)); 1616 AngleCheck.SubtractVector(&(a->x)); 1617 AngleCheck.ProjectOntoPlane(Chord); 1618 1619 SideA = dif_b.Norm(); 1620 SideB = dif_a.Norm(); 1621 SideC = Chord->Norm(); 1622 //Chord->Scale(-1); 1623 1624 alpha = Chord->Angle(&dif_a); 1625 beta = M_PI - Chord->Angle(&dif_b); 1626 gamma = dif_a.Angle(&dif_b); 1627 1628 cout << Verbose(2) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl; 1629 1630 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) { 1631 cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n"; 1632 cout << Verbose(1) << "Base triangle has sides " << dif_a << ", " << dif_b << ", " << *Chord << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl; 1633 } 1634 1635 if ((M_PI*4. > alpha*5.) && (M_PI*4. > beta*5.) && (M_PI*4 > gamma*5.)) { 1636 Umkreisradius = SideA / 2.0 / sin(alpha); 1637 //cout << Umkreisradius << endl; 1638 //cout << SideB / 2.0 / sin(beta) << endl; 1639 //cout << SideC / 2.0 / sin(gamma) << endl; 1640 1641 if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points. 1642 cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl; 1643 cout << Verbose(2) << "Candidate is "<< *Candidate << endl; 1644 sign = AngleCheck.ScalarProduct(direction1); 1645 if (fabs(sign)<MYEPSILON) { 1646 if (AngleCheck.ScalarProduct(OldNormal)<0) { 1647 sign =0; 1648 AlternativeSign=1; 1649 } else { 1650 sign =0; 1651 AlternativeSign=-1; 1652 } 1653 } else { 1654 sign /= fabs(sign); 1655 cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl; 1656 } 1657 1658 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius); 1659 1660 AngleCheck.CopyVector(&ReferencePoint); 1661 AngleCheck.Scale(-1); 1662 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1663 AngleCheck.AddVector(&Mittelpunkt); 1664 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1665 cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl; 1666 1667 BallAngle = AngleCheck.Angle(OldNormal); 1668 cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl; 1669 1670 //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl; 1671 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1672 1673 cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl; 1674 1675 NewUmkreismittelpunkt.SubtractVector(&ReferencePoint); 1676 1677 if ((AngleCheck.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) { 1678 if (Storage[0]< -1.5) { // first Candidate at all 1679 if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) { 1680 cout << Verbose(2) << "First good candidate is " << *Candidate << " with "; 1681 Opt_Candidate = Candidate; 1682 Storage[0] = sign; 1683 Storage[1] = AlternativeSign; 1684 Storage[2] = BallAngle; 1685 cout << " angle " << Storage[2] << " and Up/Down " 1686 << Storage[0] << endl; 1687 } else 1688 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl; 1689 } else { 1690 if ( Storage[2] > BallAngle) { 1691 if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) { 1692 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with "; 1693 Opt_Candidate = Candidate; 1694 Storage[0] = sign; 1695 Storage[1] = AlternativeSign; 1696 Storage[2] = BallAngle; 1697 cout << " angle " << Storage[2] << " and Up/Down " 1698 << Storage[0] << endl; 1699 } else 1700 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl; 1701 } else { 1702 if (DEBUG) { 1703 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl; 1704 } 1705 } 1706 } 1707 } else { 1708 if (DEBUG) { 1709 cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl; 1710 } 1711 } 1712 } else { 1713 if (DEBUG) { 1714 cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl; 1715 } 1716 } 1717 } else { 1718 if (DEBUG) { 1719 cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl; 1720 } 1721 } 1722 } else { 1723 if (DEBUG) { 1724 cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl; 1725 } 1726 } 1727 1728 if (RecursionLevel < 5) { // Seven is the recursion level threshold. 1729 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond 1730 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate); 1731 if (Walker == Parent) { // don't go back the same bond 1732 continue; 1733 } else { 1734 Find_next_suitable_point_via_Angle_of_Sphere(a, b, c, Walker, Candidate, RecursionLevel+1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS, mol); //call function again 1735 } 1736 } 1737 } 1738 cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n"; 1739 1739 } 1740 1740 ; … … 1767 1767 atom*& Opt_Candidate, Vector *Opt_Mittelpunkt, double *Storage, const double RADIUS, molecule* mol) 1768 1768 { 1769 /* OldNormal is normal vector on the old triangle1770 * d1 is normal on the triangle line, from which we come, as well as on OldNormal.1771 * Chord points from b to a!!!1772 */1773 Vector dif_a; //Vector from a to candidate1774 Vector dif_b; //Vector from b to candidate1775 Vector AngleCheck, AngleCheckReference, DirectionCheckPoint;1776 Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper;1777 1778 double CurrentEpsilon = 0.1;1779 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius;1780 double BallAngle;1781 atom *Walker; // variable atom point1782 1783 1784 dif_a.CopyVector(&(a->x));1785 dif_a.SubtractVector(&(Candidate->x));1786 dif_b.CopyVector(&(b->x));1787 dif_b.SubtractVector(&(Candidate->x));1788 DirectionCheckPoint.CopyVector(&dif_a);1789 DirectionCheckPoint.Scale(-1);1790 DirectionCheckPoint.ProjectOntoPlane(Chord);1791 1792 SideA = dif_b.Norm();1793 SideB = dif_a.Norm();1794 SideC = Chord->Norm();1795 //Chord->Scale(-1);1796 1797 alpha = Chord->Angle(&dif_a);1798 beta = M_PI - Chord->Angle(&dif_b);1799 gamma = dif_a.Angle(&dif_b);1800 1801 1802 if (DEBUG) {1803 cout << "Atom number" << Candidate->nr << endl;1804 Candidate->x.Output((ofstream *) &cout);1805 cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl;1806 }1807 1808 if (a != Candidate and b != Candidate) {1809 // alpha = dif_a.Angle(&dif_b) / 2.;1810 // SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha);1811 // SideB = dif_a.Norm();1812 // centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos(1813 // alpha); // note this is squared of center line length1814 // centerline = (Chord->Norm()/2.) / sin(0.5*alpha);1815 // Those are remains from Freddie. Needed?1816 1817 Umkreisradius = SideA / 2.0 / sin(alpha);1818 //cout << Umkreisradius << endl;1819 //cout << SideB / 2.0 / sin(beta) << endl;1820 //cout << SideC / 2.0 / sin(gamma) << endl;1821 1822 if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points.1823 // intermediate calculations to aquire centre of sphere, called Mittelpunkt:1824 Umkreismittelpunkt.Zero();1825 helper.CopyVector(&a->x);1826 helper.Scale(sin(2.*alpha));1827 Umkreismittelpunkt.AddVector(&helper);1828 helper.CopyVector(&b->x);1829 helper.Scale(sin(2.*beta));1830 Umkreismittelpunkt.AddVector(&helper);1831 helper.CopyVector(&Candidate->x);1832 helper.Scale(sin(2.*gamma));1833 Umkreismittelpunkt.AddVector(&helper);1834 //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ;1835 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));1836 1837 TempNormal.CopyVector(&dif_a);1838 TempNormal.VectorProduct(&dif_b);1839 if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) {1840 TempNormal.Scale(-1);1841 }1842 TempNormal.Normalize();1843 Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius);1844 TempNormal.Scale(Restradius);1845 1846 Mittelpunkt.CopyVector(&Umkreismittelpunkt);1847 Mittelpunkt.AddVector(&TempNormal); //this is center of sphere supported by a, b and Candidate1848 1849 AngleCheck.CopyVector(Chord);1850 AngleCheck.Scale(-0.5);1851 AngleCheck.SubtractVector(&(b->x));1852 AngleCheckReference.CopyVector(&AngleCheck);1853 AngleCheckReference.AddVector(Opt_Mittelpunkt);1854 AngleCheck.AddVector(&Mittelpunkt);1855 1856 BallAngle = AngleCheck.Angle(&AngleCheckReference);1857 1858 d1->ProjectOntoPlane(&AngleCheckReference);1859 sign = AngleCheck.ScalarProduct(d1);1860 if (fabs(sign) < MYEPSILON)1861 sign = 0;1862 else1863 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction...1864 1865 1866 if (Storage[0]< -1.5) { // first Candidate at all1867 cout << "Next better candidate is " << *Candidate << " with ";1868 Opt_Candidate = Candidate;1869 Storage[0] = sign;1870 Storage[1] = BallAngle;1871 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);1872 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;1873 } else {1874 /*1875 * removed due to change in criterium, now checking angle of ball to old normal.1876 //We will now check for non interference, that is if the new candidate would have the Opt_Candidate1877 //within the ball.1878 1879 Distance = Opt_Candidate->x.Distance(&Mittelpunkt);1880 //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl;1881 1882 1883 if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better.1884 */1885 //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl;1886 1887 if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants1888 //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS)) //and those where Candidate would be within old Sphere.1889 cout << "Next better candidate is " << *Candidate << " with ";1890 Opt_Candidate = Candidate;1891 Storage[0] = sign;1892 Storage[1] = BallAngle;1893 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);1894 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;1895 } else {1896 if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) {1897 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.1898 cout << "Next better candidate is " << *Candidate << " with ";1899 Opt_Candidate = Candidate;1900 Storage[0] = sign;1901 Storage[1] = BallAngle;1902 Opt_Mittelpunkt->CopyVector(&Mittelpunkt);1903 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl;1904 }1905 }1906 }1769 /* OldNormal is normal vector on the old triangle 1770 * d1 is normal on the triangle line, from which we come, as well as on OldNormal. 1771 * Chord points from b to a!!! 1772 */ 1773 Vector dif_a; //Vector from a to candidate 1774 Vector dif_b; //Vector from b to candidate 1775 Vector AngleCheck, AngleCheckReference, DirectionCheckPoint; 1776 Vector TempNormal, Umkreismittelpunkt, Mittelpunkt, helper; 1777 1778 double CurrentEpsilon = 0.1; 1779 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius; 1780 double BallAngle; 1781 atom *Walker; // variable atom point 1782 1783 1784 dif_a.CopyVector(&(a->x)); 1785 dif_a.SubtractVector(&(Candidate->x)); 1786 dif_b.CopyVector(&(b->x)); 1787 dif_b.SubtractVector(&(Candidate->x)); 1788 DirectionCheckPoint.CopyVector(&dif_a); 1789 DirectionCheckPoint.Scale(-1); 1790 DirectionCheckPoint.ProjectOntoPlane(Chord); 1791 1792 SideA = dif_b.Norm(); 1793 SideB = dif_a.Norm(); 1794 SideC = Chord->Norm(); 1795 //Chord->Scale(-1); 1796 1797 alpha = Chord->Angle(&dif_a); 1798 beta = M_PI - Chord->Angle(&dif_b); 1799 gamma = dif_a.Angle(&dif_b); 1800 1801 1802 if (DEBUG) { 1803 cout << "Atom number" << Candidate->nr << endl; 1804 Candidate->x.Output((ofstream *) &cout); 1805 cout << "number of bonds " << mol->NumberOfBondsPerAtom[Candidate->nr] << endl; 1806 } 1807 1808 if (a != Candidate and b != Candidate) { 1809 // alpha = dif_a.Angle(&dif_b) / 2.; 1810 // SideA = Chord->Norm() / 2.;// (Chord->Norm()/2.) / sin(0.5*alpha); 1811 // SideB = dif_a.Norm(); 1812 // centerline = SideA * SideA + SideB * SideB - 2. * SideA * SideB * cos( 1813 // alpha); // note this is squared of center line length 1814 // centerline = (Chord->Norm()/2.) / sin(0.5*alpha); 1815 // Those are remains from Freddie. Needed? 1816 1817 Umkreisradius = SideA / 2.0 / sin(alpha); 1818 //cout << Umkreisradius << endl; 1819 //cout << SideB / 2.0 / sin(beta) << endl; 1820 //cout << SideC / 2.0 / sin(gamma) << endl; 1821 1822 if (Umkreisradius < RADIUS && DirectionCheckPoint.ScalarProduct(&(Candidate->x))>0) { //Checking whether ball will at least rest o points. 1823 // intermediate calculations to aquire centre of sphere, called Mittelpunkt: 1824 Umkreismittelpunkt.Zero(); 1825 helper.CopyVector(&a->x); 1826 helper.Scale(sin(2.*alpha)); 1827 Umkreismittelpunkt.AddVector(&helper); 1828 helper.CopyVector(&b->x); 1829 helper.Scale(sin(2.*beta)); 1830 Umkreismittelpunkt.AddVector(&helper); 1831 helper.CopyVector(&Candidate->x); 1832 helper.Scale(sin(2.*gamma)); 1833 Umkreismittelpunkt.AddVector(&helper); 1834 //Umkreismittelpunkt = (a->x) * sin(2.*alpha) + b->x * sin(2.*beta) + (Candidate->x) * sin(2.*gamma) ; 1835 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma))); 1836 1837 TempNormal.CopyVector(&dif_a); 1838 TempNormal.VectorProduct(&dif_b); 1839 if (TempNormal.ScalarProduct(OldNormal)<0 && sign>0 || TempNormal.ScalarProduct(OldNormal)>0 && sign<0) { 1840 TempNormal.Scale(-1); 1841 } 1842 TempNormal.Normalize(); 1843 Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius); 1844 TempNormal.Scale(Restradius); 1845 1846 Mittelpunkt.CopyVector(&Umkreismittelpunkt); 1847 Mittelpunkt.AddVector(&TempNormal); //this is center of sphere supported by a, b and Candidate 1848 1849 AngleCheck.CopyVector(Chord); 1850 AngleCheck.Scale(-0.5); 1851 AngleCheck.SubtractVector(&(b->x)); 1852 AngleCheckReference.CopyVector(&AngleCheck); 1853 AngleCheckReference.AddVector(Opt_Mittelpunkt); 1854 AngleCheck.AddVector(&Mittelpunkt); 1855 1856 BallAngle = AngleCheck.Angle(&AngleCheckReference); 1857 1858 d1->ProjectOntoPlane(&AngleCheckReference); 1859 sign = AngleCheck.ScalarProduct(d1); 1860 if (fabs(sign) < MYEPSILON) 1861 sign = 0; 1862 else 1863 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction... 1864 1865 1866 if (Storage[0]< -1.5) { // first Candidate at all 1867 cout << "Next better candidate is " << *Candidate << " with "; 1868 Opt_Candidate = Candidate; 1869 Storage[0] = sign; 1870 Storage[1] = BallAngle; 1871 Opt_Mittelpunkt->CopyVector(&Mittelpunkt); 1872 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl; 1873 } else { 1874 /* 1875 * removed due to change in criterium, now checking angle of ball to old normal. 1876 //We will now check for non interference, that is if the new candidate would have the Opt_Candidate 1877 //within the ball. 1878 1879 Distance = Opt_Candidate->x.Distance(&Mittelpunkt); 1880 //cout << "Opt_Candidate " << Opt_Candidate << " has distance " << Distance << " to Center of Candidate " << endl; 1881 1882 1883 if (Distance >RADIUS) { // We have no interference and may now check whether the new point is better. 1884 */ 1885 //cout << "Atom " << Candidate << " has distance " << Candidate->x.Distance(Opt_Mittelpunkt) << " to Center of Candidate " << endl; 1886 1887 if (((Storage[0] < 0 && fabs(sign - Storage[0]) > CurrentEpsilon))) { //This will give absolute preference to those in "right-hand" quadrants 1888 //(Candidate->x.Distance(Opt_Mittelpunkt) < RADIUS)) //and those where Candidate would be within old Sphere. 1889 cout << "Next better candidate is " << *Candidate << " with "; 1890 Opt_Candidate = Candidate; 1891 Storage[0] = sign; 1892 Storage[1] = BallAngle; 1893 Opt_Mittelpunkt->CopyVector(&Mittelpunkt); 1894 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl; 1895 } else { 1896 if ((fabs(sign - Storage[0]) < CurrentEpsilon && sign > 0 && Storage[1] > BallAngle) || (fabs(sign - Storage[0]) < CurrentEpsilon && sign < 0 && Storage[1] < BallAngle)) { 1897 //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first. 1898 cout << "Next better candidate is " << *Candidate << " with "; 1899 Opt_Candidate = Candidate; 1900 Storage[0] = sign; 1901 Storage[1] = BallAngle; 1902 Opt_Mittelpunkt->CopyVector(&Mittelpunkt); 1903 cout << "Angle is " << Storage[1] << ", Halbraum ist " << Storage[0] << endl; 1904 } 1905 } 1906 } 1907 1907 /* 1908 1908 * This is for checking point-angle and presence of Candidates in Ball, currently we are checking the ball Angle. … … 1947 1947 } 1948 1948 */ 1949 } else {1950 if (DEBUG) {1951 cout << "Doesn't satisfy requirements for circumscribing circle" << endl;1952 }1953 }1954 } else {1955 if (DEBUG) {1956 cout << "identisch mit Ursprungslinie" << endl;1957 }1958 }1959 1960 if (RecursionLevel < 9) { // Five is the recursion level threshold.1961 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond1962 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);1963 if (Walker == Parent) { // don't go back the same bond1964 continue;1965 } else {1966 Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again1967 }1968 }1969 }1949 } else { 1950 if (DEBUG) { 1951 cout << "Doesn't satisfy requirements for circumscribing circle" << endl; 1952 } 1953 } 1954 } else { 1955 if (DEBUG) { 1956 cout << "identisch mit Ursprungslinie" << endl; 1957 } 1958 } 1959 1960 if (RecursionLevel < 9) { // Five is the recursion level threshold. 1961 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond 1962 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate); 1963 if (Walker == Parent) { // don't go back the same bond 1964 continue; 1965 } else { 1966 Find_next_suitable_point(a, b, Walker, Candidate, RecursionLevel+1, Chord, d1, OldNormal, Opt_Candidate, Opt_Mittelpunkt, Storage, RADIUS, mol); //call function again 1967 } 1968 } 1969 } 1970 1970 }; 1971 1971 … … 1984 1984 const double& RADIUS, int N, const char *tempbasename) 1985 1985 { 1986 cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n";1987 Vector direction1;1988 Vector helper;1989 Vector Chord;1990 ofstream *tempstream = NULL;1991 char NumberName[255];1992 double tmp;1993 //atom* Walker;1994 atom* OldThirdPoint;1995 1996 double Storage[3];1997 Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values1998 Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive1999 Storage[2] = 9999999.;2000 atom* Opt_Candidate = NULL;2001 Vector Opt_Mittelpunkt;2002 2003 cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl;2004 2005 helper.CopyVector(&(Line.endpoints[0]->node->x));2006 for (int i = 0; i < 3; i++) {2007 if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) {2008 OldThirdPoint = T.endpoints[i]->node;2009 helper.SubtractVector(&T.endpoints[i]->node->x);2010 break;2011 }2012 }2013 2014 direction1.CopyVector(&Line.endpoints[0]->node->x);2015 direction1.SubtractVector(&Line.endpoints[1]->node->x);2016 direction1.VectorProduct(&(T.NormalVector));2017 2018 if (direction1.ScalarProduct(&helper) < 0) {2019 direction1.Scale(-1);2020 }2021 cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n";2022 2023 Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function2024 Chord.SubtractVector(&(Line.endpoints[1]->node->x));2025 cout << Verbose(2) << "Baseline vector is " << Chord << ".\n";2026 2027 2028 Vector Umkreismittelpunkt, a, b, c;2029 double alpha, beta, gamma;2030 a.CopyVector(&(T.endpoints[0]->node->x));2031 b.CopyVector(&(T.endpoints[1]->node->x));2032 c.CopyVector(&(T.endpoints[2]->node->x));2033 a.SubtractVector(&(T.endpoints[1]->node->x));2034 b.SubtractVector(&(T.endpoints[2]->node->x));2035 c.SubtractVector(&(T.endpoints[0]->node->x));2036 2037 alpha = M_PI - a.Angle(&c);2038 beta = M_PI - b.Angle(&a);2039 gamma = M_PI - c.Angle(&b);2040 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON)2041 cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";2042 2043 Umkreismittelpunkt.Zero();2044 helper.CopyVector(&T.endpoints[0]->node->x);2045 helper.Scale(sin(2.*alpha));2046 Umkreismittelpunkt.AddVector(&helper);2047 helper.CopyVector(&T.endpoints[1]->node->x);2048 helper.Scale(sin(2.*beta));2049 Umkreismittelpunkt.AddVector(&helper);2050 helper.CopyVector(&T.endpoints[2]->node->x);2051 helper.Scale(sin(2.*gamma));2052 Umkreismittelpunkt.AddVector(&helper);2053 //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ;2054 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;2055 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma)));2056 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl;2057 cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl;2058 cout << " Old Normal is " << (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl;2059 2060 cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl;2061 cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl;2062 if (DEBUG)2063 cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl;2064 tmp = 0;2065 for (int i=0;i<NDIM;i++) {2066 helper.CopyVector(&T.endpoints[i]->node->x);2067 helper.SubtractVector(&Umkreismittelpunkt);2068 if (DEBUG)2069 cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl;2070 if (tmp == 0) // set on first time for comparison against next ones2071 tmp = helper.Norm();2072 if (fabs(helper.Norm() - tmp) > MYEPSILON)2073 cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl;2074 }2075 2076 cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl;2077 2078 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);2079 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol);2080 if (Opt_Candidate == NULL) {2081 cerr << "WARNING: Could not find a suitable candidate." << endl;2082 return false;2083 }2084 cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl;2085 2086 // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2)2087 bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node);2088 2089 if (flag) { // if so, add2090 AddTrianglePoint(Opt_Candidate, 0);2091 AddTrianglePoint(Line.endpoints[0]->node, 1);2092 AddTrianglePoint(Line.endpoints[1]->node, 2);2093 2094 AddTriangleLine(TPS[0], TPS[1], 0);2095 AddTriangleLine(TPS[0], TPS[2], 1);2096 AddTriangleLine(TPS[1], TPS[2], 2);2097 2098 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);2099 AddTriangleToLines();2100 2101 BTS->GetNormalVector(BTS->NormalVector);2102 2103 if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0) || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) {2104 BTS->NormalVector.Scale(-1);2105 };2106 cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl;2107 cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl;2108 } else { // else, yell and do nothing2109 cout << Verbose(1) << "This triangle consisting of ";2110 cout << *Opt_Candidate << ", ";2111 cout << *Line.endpoints[0]->node << " and ";2112 cout << *Line.endpoints[1]->node << " ";2113 cout << "is invalid!" << endl;2114 return false;2115 }2116 2117 if ((TrianglesOnBoundaryCount % 10) == 0) {2118 sprintf(NumberName, "-%d", TriangleFilesWritten);2119 if (DoTecplotOutput) {2120 string NameofTempFile(tempbasename);2121 NameofTempFile.append(NumberName);2122 NameofTempFile.append(TecplotSuffix);2123 cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";2124 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);2125 write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten);2126 tempstream->close();2127 tempstream->flush();2128 delete(tempstream);2129 }2130 2131 if (DoRaster3DOutput) {2132 string NameofTempFile(tempbasename);2133 NameofTempFile.append(NumberName);2134 NameofTempFile.append(Raster3DSuffix);2135 cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n";2136 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc);2137 write_raster3d_file(out, tempstream, this, mol);2138 tempstream->close();2139 tempstream->flush();2140 delete(tempstream);2141 }2142 if (DoTecplotOutput || DoRaster3DOutput)2143 TriangleFilesWritten++;2144 }2145 2146 cout << Verbose(1) << "End of Find_next_suitable_triangle\n";2147 return true;1986 cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n"; 1987 Vector direction1; 1988 Vector helper; 1989 Vector Chord; 1990 ofstream *tempstream = NULL; 1991 char NumberName[255]; 1992 double tmp; 1993 //atom* Walker; 1994 atom* OldThirdPoint; 1995 1996 double Storage[3]; 1997 Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values 1998 Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive 1999 Storage[2] = 9999999.; 2000 atom* Opt_Candidate = NULL; 2001 Vector Opt_Mittelpunkt; 2002 2003 cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl; 2004 2005 helper.CopyVector(&(Line.endpoints[0]->node->x)); 2006 for (int i = 0; i < 3; i++) { 2007 if (T.endpoints[i]->node->nr != Line.endpoints[0]->node->nr && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) { 2008 OldThirdPoint = T.endpoints[i]->node; 2009 helper.SubtractVector(&T.endpoints[i]->node->x); 2010 break; 2011 } 2012 } 2013 2014 direction1.CopyVector(&Line.endpoints[0]->node->x); 2015 direction1.SubtractVector(&Line.endpoints[1]->node->x); 2016 direction1.VectorProduct(&(T.NormalVector)); 2017 2018 if (direction1.ScalarProduct(&helper) < 0) { 2019 direction1.Scale(-1); 2020 } 2021 cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n"; 2022 2023 Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function 2024 Chord.SubtractVector(&(Line.endpoints[1]->node->x)); 2025 cout << Verbose(2) << "Baseline vector is " << Chord << ".\n"; 2026 2027 2028 Vector Umkreismittelpunkt, a, b, c; 2029 double alpha, beta, gamma; 2030 a.CopyVector(&(T.endpoints[0]->node->x)); 2031 b.CopyVector(&(T.endpoints[1]->node->x)); 2032 c.CopyVector(&(T.endpoints[2]->node->x)); 2033 a.SubtractVector(&(T.endpoints[1]->node->x)); 2034 b.SubtractVector(&(T.endpoints[2]->node->x)); 2035 c.SubtractVector(&(T.endpoints[0]->node->x)); 2036 2037 alpha = M_PI - a.Angle(&c); 2038 beta = M_PI - b.Angle(&a); 2039 gamma = M_PI - c.Angle(&b); 2040 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) 2041 cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n"; 2042 2043 Umkreismittelpunkt.Zero(); 2044 helper.CopyVector(&T.endpoints[0]->node->x); 2045 helper.Scale(sin(2.*alpha)); 2046 Umkreismittelpunkt.AddVector(&helper); 2047 helper.CopyVector(&T.endpoints[1]->node->x); 2048 helper.Scale(sin(2.*beta)); 2049 Umkreismittelpunkt.AddVector(&helper); 2050 helper.CopyVector(&T.endpoints[2]->node->x); 2051 helper.Scale(sin(2.*gamma)); 2052 Umkreismittelpunkt.AddVector(&helper); 2053 //Umkreismittelpunkt = (T.endpoints[0]->node->x) * sin(2.*alpha) + T.endpoints[1]->node->x * sin(2.*beta) + (T.endpoints[2]->node->x) * sin(2.*gamma) ; 2054 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl; 2055 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma))); 2056 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl; 2057 cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl; 2058 cout << " Old Normal is " << (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl; 2059 2060 cout << Verbose(2) << "Base triangle has sides " << a << ", " << b << ", " << c << " with angles " << alpha/M_PI*180. << ", " << beta/M_PI*180. << ", " << gamma/M_PI*180. << "." << endl; 2061 cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl; 2062 if (DEBUG) 2063 cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl; 2064 tmp = 0; 2065 for (int i=0;i<NDIM;i++) { 2066 helper.CopyVector(&T.endpoints[i]->node->x); 2067 helper.SubtractVector(&Umkreismittelpunkt); 2068 if (DEBUG) 2069 cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl; 2070 if (tmp == 0) // set on first time for comparison against next ones 2071 tmp = helper.Norm(); 2072 if (fabs(helper.Norm() - tmp) > MYEPSILON) 2073 cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl; 2074 } 2075 2076 cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl; 2077 2078 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol); 2079 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol); 2080 if (Opt_Candidate == NULL) { 2081 cerr << "WARNING: Could not find a suitable candidate." << endl; 2082 return false; 2083 } 2084 cout << Verbose(1) << " Optimal candidate is " << *Opt_Candidate << endl; 2085 2086 // check whether all edges of the new triangle still have space for one more triangle (i.e. TriangleCount <2) 2087 bool flag = CheckPresenceOfTriangle(out, Opt_Candidate, Line.endpoints[0]->node, Line.endpoints[1]->node); 2088 2089 if (flag) { // if so, add 2090 AddTrianglePoint(Opt_Candidate, 0); 2091 AddTrianglePoint(Line.endpoints[0]->node, 1); 2092 AddTrianglePoint(Line.endpoints[1]->node, 2); 2093 2094 AddTriangleLine(TPS[0], TPS[1], 0); 2095 AddTriangleLine(TPS[0], TPS[2], 1); 2096 AddTriangleLine(TPS[1], TPS[2], 2); 2097 2098 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2099 AddTriangleToLines(); 2100 2101 BTS->GetNormalVector(BTS->NormalVector); 2102 2103 if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0) || (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) { 2104 BTS->NormalVector.Scale(-1); 2105 }; 2106 cout << Verbose(1) << "New triangle with " << *BTS << " and normal vector " << BTS->NormalVector << " for this triangle ... " << endl; 2107 cout << Verbose(1) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl; 2108 } else { // else, yell and do nothing 2109 cout << Verbose(1) << "This triangle consisting of "; 2110 cout << *Opt_Candidate << ", "; 2111 cout << *Line.endpoints[0]->node << " and "; 2112 cout << *Line.endpoints[1]->node << " "; 2113 cout << "is invalid!" << endl; 2114 return false; 2115 } 2116 2117 if ((TrianglesOnBoundaryCount % 10) == 0) { 2118 sprintf(NumberName, "-%d", TriangleFilesWritten); 2119 if (DoTecplotOutput) { 2120 string NameofTempFile(tempbasename); 2121 NameofTempFile.append(NumberName); 2122 NameofTempFile.append(TecplotSuffix); 2123 cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 2124 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 2125 write_tecplot_file(out, tempstream, this, mol, TriangleFilesWritten); 2126 tempstream->close(); 2127 tempstream->flush(); 2128 delete(tempstream); 2129 } 2130 2131 if (DoRaster3DOutput) { 2132 string NameofTempFile(tempbasename); 2133 NameofTempFile.append(NumberName); 2134 NameofTempFile.append(Raster3DSuffix); 2135 cout << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 2136 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 2137 write_raster3d_file(out, tempstream, this, mol); 2138 tempstream->close(); 2139 tempstream->flush(); 2140 delete(tempstream); 2141 } 2142 if (DoTecplotOutput || DoRaster3DOutput) 2143 TriangleFilesWritten++; 2144 } 2145 2146 cout << Verbose(1) << "End of Find_next_suitable_triangle\n"; 2147 return true; 2148 2148 }; 2149 2149 … … 2159 2159 */ 2160 2160 bool Tesselation::CheckPresenceOfTriangle(ofstream *out, atom *a, atom *b, atom *c) { 2161 LineMap::iterator TryAndError;2162 PointTestPair InsertPoint;2163 bool Present[3];2164 2165 *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl;2166 TPS[0] = new class BoundaryPointSet(a);2167 TPS[1] = new class BoundaryPointSet(b);2168 TPS[2] = new class BoundaryPointSet(c);2169 for (int i=0;i<3;i++) { // check through all endpoints2170 InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i]));2171 Present[i] = !InsertPoint.second;2172 if (Present[i]) { // if new point was not present before, increase counter2173 delete TPS[i];2174 *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl;2175 TPS[i] = (InsertPoint.first)->second;2176 }2177 }2178 2179 // check lines2180 for (int i=0;i<3;i++)2181 if (Present[i])2182 for (int j=i;j<3;j++)2183 if (Present[j]) {2184 TryAndError = TPS[i]->lines.find(TPS[j]->node->nr);2185 if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) {2186 *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl;2187 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;2188 return false;2189 }2190 }2191 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl;2192 return true;2161 LineMap::iterator TryAndError; 2162 PointTestPair InsertPoint; 2163 bool Present[3]; 2164 2165 *out << Verbose(2) << "Begin of CheckPresenceOfTriangle" << endl; 2166 TPS[0] = new class BoundaryPointSet(a); 2167 TPS[1] = new class BoundaryPointSet(b); 2168 TPS[2] = new class BoundaryPointSet(c); 2169 for (int i=0;i<3;i++) { // check through all endpoints 2170 InsertPoint = PointsOnBoundary.insert(PointPair(TPS[i]->node->nr, TPS[i])); 2171 Present[i] = !InsertPoint.second; 2172 if (Present[i]) { // if new point was not present before, increase counter 2173 delete TPS[i]; 2174 *out << Verbose(2) << "Atom " << *((InsertPoint.first)->second->node) << " gibt's schon in der PointMap." << endl; 2175 TPS[i] = (InsertPoint.first)->second; 2176 } 2177 } 2178 2179 // check lines 2180 for (int i=0;i<3;i++) 2181 if (Present[i]) 2182 for (int j=i;j<3;j++) 2183 if (Present[j]) { 2184 TryAndError = TPS[i]->lines.find(TPS[j]->node->nr); 2185 if ((TryAndError != TPS[i]->lines.end()) && (TryAndError->second->TrianglesCount > 1)) { 2186 *out << "WARNING: Line " << *TryAndError->second << " already present with " << TryAndError->second->TrianglesCount << " triangles attached." << endl; 2187 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl; 2188 return false; 2189 } 2190 } 2191 *out << Verbose(2) << "End of CheckPresenceOfTriangle" << endl; 2192 return true; 2193 2193 }; 2194 2194 … … 2198 2198 molecule* mol, double RADIUS) 2199 2199 { 2200 cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;2201 int i;2202 Vector AngleCheck;2203 atom* Walker;2204 double norm = -1., angle;2205 2206 // check if we only have one unique point yet ...2207 if (a != Candidate) {2208 cout << Verbose(3) << "Current candidate is " << *Candidate << ": ";2209 AngleCheck.CopyVector(&(Candidate->x));2210 AngleCheck.SubtractVector(&(a->x));2211 norm = AngleCheck.Norm();2212 // second point shall have smallest angle with respect to Oben vector2213 if (norm < RADIUS) {2214 angle = AngleCheck.Angle(&Oben);2215 if (angle < Storage[0]) {2216 //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);2217 cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n";2218 Opt_Candidate = Candidate;2219 Storage[0] = AngleCheck.Angle(&Oben);2220 //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]);2221 } else {2222 cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl;2223 }2224 } else {2225 cout << "Refused due to Radius " << norm << endl;2226 }2227 }2228 2229 // if not recursed to deeply, look at all its bonds2230 if (RecursionLevel < 7) {2231 for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) {2232 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);2233 if (Walker == Parent) // don't go back along the bond we came from2234 continue;2235 else2236 Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS);2237 }2238 }2239 cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl;2200 cout << Verbose(2) << "Begin of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl; 2201 int i; 2202 Vector AngleCheck; 2203 atom* Walker; 2204 double norm = -1., angle; 2205 2206 // check if we only have one unique point yet ... 2207 if (a != Candidate) { 2208 cout << Verbose(3) << "Current candidate is " << *Candidate << ": "; 2209 AngleCheck.CopyVector(&(Candidate->x)); 2210 AngleCheck.SubtractVector(&(a->x)); 2211 norm = AngleCheck.Norm(); 2212 // second point shall have smallest angle with respect to Oben vector 2213 if (norm < RADIUS) { 2214 angle = AngleCheck.Angle(&Oben); 2215 if (angle < Storage[0]) { 2216 //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]); 2217 cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n"; 2218 Opt_Candidate = Candidate; 2219 Storage[0] = AngleCheck.Angle(&Oben); 2220 //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[2]); 2221 } else { 2222 cout << "Looses with angle " << angle << " to a better candidate " << *Opt_Candidate << endl; 2223 } 2224 } else { 2225 cout << "Refused due to Radius " << norm << endl; 2226 } 2227 } 2228 2229 // if not recursed to deeply, look at all its bonds 2230 if (RecursionLevel < 7) { 2231 for (i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { 2232 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate); 2233 if (Walker == Parent) // don't go back along the bond we came from 2234 continue; 2235 else 2236 Find_second_point_for_Tesselation(a, Walker, Candidate, RecursionLevel + 1, Oben, Opt_Candidate, Storage, mol, RADIUS); 2237 } 2238 } 2239 cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " << RecursionLevel << endl; 2240 2240 }; 2241 2241 2242 2242 void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS) 2243 2243 { 2244 cout << Verbose(1) << "Begin of Find_starting_triangle\n";2245 int i = 0;2246 atom* Walker;2247 atom* FirstPoint;2248 atom* SecondPoint;2249 atom* max_index[NDIM];2250 double max_coordinate[NDIM];2251 Vector Oben;2252 Vector helper;2253 Vector Chord;2254 Vector CenterOfFirstLine;2255 2256 Oben.Zero();2257 2258 for (i = 0; i < 3; i++) {2259 max_index[i] = NULL;2260 max_coordinate[i] = -1;2261 }2262 cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n";2263 2264 // 1. searching topmost atom with respect to each axis2265 Walker = mol->start;2266 while (Walker->next != mol->end) {2267 Walker = Walker->next;2268 for (i = 0; i < 3; i++) {2269 if (Walker->x.x[i] > max_coordinate[i]) {2270 max_coordinate[i] = Walker->x.x[i];2271 max_index[i] = Walker;2272 }2273 }2274 }2275 2276 cout << Verbose(2) << "Found maximum coordinates: ";2277 for (int i=0;i<NDIM;i++)2278 cout << i << ": " << *max_index[i] << "\t";2279 cout << endl;2244 cout << Verbose(1) << "Begin of Find_starting_triangle\n"; 2245 int i = 0; 2246 atom* Walker; 2247 atom* FirstPoint; 2248 atom* SecondPoint; 2249 atom* max_index[NDIM]; 2250 double max_coordinate[NDIM]; 2251 Vector Oben; 2252 Vector helper; 2253 Vector Chord; 2254 Vector CenterOfFirstLine; 2255 2256 Oben.Zero(); 2257 2258 for (i = 0; i < 3; i++) { 2259 max_index[i] = NULL; 2260 max_coordinate[i] = -1; 2261 } 2262 cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount << " Atoms \n"; 2263 2264 // 1. searching topmost atom with respect to each axis 2265 Walker = mol->start; 2266 while (Walker->next != mol->end) { 2267 Walker = Walker->next; 2268 for (i = 0; i < 3; i++) { 2269 if (Walker->x.x[i] > max_coordinate[i]) { 2270 max_coordinate[i] = Walker->x.x[i]; 2271 max_index[i] = Walker; 2272 } 2273 } 2274 } 2275 2276 cout << Verbose(2) << "Found maximum coordinates: "; 2277 for (int i=0;i<NDIM;i++) 2278 cout << i << ": " << *max_index[i] << "\t"; 2279 cout << endl; 2280 2280 //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0 2281 const int k = 1;2282 Oben.x[k] = 1.;2283 FirstPoint = max_index[k];2284 2285 cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl;2286 double Storage[3];2287 atom* Opt_Candidate = NULL;2288 Storage[0] = 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.2289 Storage[1] = 999999.; // This will be an angle looking for the third point.2290 Storage[2] = 999999.;2291 2292 Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_...2293 SecondPoint = Opt_Candidate;2294 cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n";2295 2296 helper.CopyVector(&(FirstPoint->x));2297 helper.SubtractVector(&(SecondPoint->x));2298 helper.Normalize();2299 Oben.ProjectOntoPlane(&helper);2300 Oben.Normalize();2301 helper.VectorProduct(&Oben);2302 Storage[0] = -2.; // This will indicate the quadrant.2303 Storage[1] = 9999999.; // This will be an angle looking for the third point.2304 Storage[2] = 9999999.;2305 2306 Chord.CopyVector(&(FirstPoint->x)); // bring into calling function2307 Chord.SubtractVector(&(SecondPoint->x));2308 // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized)2309 2310 cout << Verbose(2) << "Looking for third point candidates \n";2311 // look in one direction of baseline for initial candidate2312 Opt_Candidate = NULL;2313 CenterOfFirstLine.CopyVector(&Chord);2314 CenterOfFirstLine.Scale(0.5);2315 CenterOfFirstLine.AddVector(&(SecondPoint->x));2316 2317 cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n";2318 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);2319 // look in other direction of baseline for possible better candidate2320 cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n";2321 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol);2322 cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl;2323 2324 // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate2325 2326 // Finally, we only have to add the found points2327 AddTrianglePoint(FirstPoint, 0);2328 AddTrianglePoint(SecondPoint, 1);2329 AddTrianglePoint(Opt_Candidate, 2);2330 // ... and respective lines2331 AddTriangleLine(TPS[0], TPS[1], 0);2332 AddTriangleLine(TPS[1], TPS[2], 1);2333 AddTriangleLine(TPS[0], TPS[2], 2);2334 // ... and triangles to the Maps of the Tesselation class2335 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);2336 AddTriangleToLines();2337 // ... and calculate its normal vector (with correct orientation)2338 Oben.Scale(-1.);2339 BTS->GetNormalVector(Oben);2340 cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n";2341 cout << Verbose(1) << "End of Find_starting_triangle\n";2281 const int k = 1; 2282 Oben.x[k] = 1.; 2283 FirstPoint = max_index[k]; 2284 2285 cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl; 2286 double Storage[3]; 2287 atom* Opt_Candidate = NULL; 2288 Storage[0] = 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. 2289 Storage[1] = 999999.; // This will be an angle looking for the third point. 2290 Storage[2] = 999999.; 2291 2292 Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_... 2293 SecondPoint = Opt_Candidate; 2294 cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n"; 2295 2296 helper.CopyVector(&(FirstPoint->x)); 2297 helper.SubtractVector(&(SecondPoint->x)); 2298 helper.Normalize(); 2299 Oben.ProjectOntoPlane(&helper); 2300 Oben.Normalize(); 2301 helper.VectorProduct(&Oben); 2302 Storage[0] = -2.; // This will indicate the quadrant. 2303 Storage[1] = 9999999.; // This will be an angle looking for the third point. 2304 Storage[2] = 9999999.; 2305 2306 Chord.CopyVector(&(FirstPoint->x)); // bring into calling function 2307 Chord.SubtractVector(&(SecondPoint->x)); 2308 // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized) 2309 2310 cout << Verbose(2) << "Looking for third point candidates \n"; 2311 // look in one direction of baseline for initial candidate 2312 Opt_Candidate = NULL; 2313 CenterOfFirstLine.CopyVector(&Chord); 2314 CenterOfFirstLine.Scale(0.5); 2315 CenterOfFirstLine.AddVector(&(SecondPoint->x)); 2316 2317 cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n"; 2318 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol); 2319 // look in other direction of baseline for possible better candidate 2320 cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n"; 2321 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol); 2322 cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl; 2323 2324 // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate 2325 2326 // Finally, we only have to add the found points 2327 AddTrianglePoint(FirstPoint, 0); 2328 AddTrianglePoint(SecondPoint, 1); 2329 AddTrianglePoint(Opt_Candidate, 2); 2330 // ... and respective lines 2331 AddTriangleLine(TPS[0], TPS[1], 0); 2332 AddTriangleLine(TPS[1], TPS[2], 1); 2333 AddTriangleLine(TPS[0], TPS[2], 2); 2334 // ... and triangles to the Maps of the Tesselation class 2335 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2336 AddTriangleToLines(); 2337 // ... and calculate its normal vector (with correct orientation) 2338 Oben.Scale(-1.); 2339 BTS->GetNormalVector(Oben); 2340 cout << Verbose(0) << "==> The found starting triangle consists of " << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate << " with normal vector " << BTS->NormalVector << ".\n"; 2341 cout << Verbose(1) << "End of Find_starting_triangle\n"; 2342 2342 }; 2343 2343 2344 2344 void Find_non_convex_border(ofstream *out, ofstream *tecplot, molecule* mol, const char *filename, const double RADIUS) 2345 2345 { 2346 int N = 0;2347 struct Tesselation *Tess = new Tesselation;2348 cout << Verbose(1) << "Entering search for non convex hull. " << endl;2349 cout << flush;2350 LineMap::iterator baseline;2351 cout << Verbose(0) << "Begin of Find_non_convex_border\n";2352 bool flag = false; // marks whether we went once through all baselines without finding any without two triangles2353 bool failflag = false;2354 if ((mol->first->next == mol->last) || (mol->last->previous == mol->first))2355 mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true);2356 2357 Tess->Find_starting_triangle(mol, RADIUS);2358 2359 baseline = Tess->LinesOnBoundary.begin();2360 while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) {2361 if (baseline->second->TrianglesCount == 1) {2362 failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one.2363 flag = flag || failflag;2364 if (!failflag)2365 cerr << "WARNING: Find_next_suitable_triangle failed." << endl;2366 } else {2367 cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl;2368 }2369 N++;2370 baseline++;2371 if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) {2372 baseline = Tess->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines2373 flag = false;2374 }2375 }2376 if (failflag) {2377 cout << Verbose(1) << "Writing final tecplot file\n";2378 if (DoTecplotOutput)2379 write_tecplot_file(out, tecplot, Tess, mol, -1);2380 if (DoRaster3DOutput)2381 write_raster3d_file(out, tecplot, Tess, mol);2382 } else {2383 cerr << "ERROR: Could definately not find all necessary triangles!" << endl;2384 }2385 2386 cout << Verbose(0) << "End of Find_non_convex_border\n";2387 delete(Tess);2346 int N = 0; 2347 struct Tesselation *Tess = new Tesselation; 2348 cout << Verbose(1) << "Entering search for non convex hull. " << endl; 2349 cout << flush; 2350 LineMap::iterator baseline; 2351 cout << Verbose(0) << "Begin of Find_non_convex_border\n"; 2352 bool flag = false; // marks whether we went once through all baselines without finding any without two triangles 2353 bool failflag = false; 2354 if ((mol->first->next == mol->last) || (mol->last->previous == mol->first)) 2355 mol->CreateAdjacencyList((ofstream *)&cout, 1.6, true); 2356 2357 Tess->Find_starting_triangle(mol, RADIUS); 2358 2359 baseline = Tess->LinesOnBoundary.begin(); 2360 while ((baseline != Tess->LinesOnBoundary.end()) || (flag)) { 2361 if (baseline->second->TrianglesCount == 1) { 2362 failflag = Tess->Find_next_suitable_triangle(out, tecplot, mol, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, filename); //the line is there, so there is a triangle, but only one. 2363 flag = flag || failflag; 2364 if (!failflag) 2365 cerr << "WARNING: Find_next_suitable_triangle failed." << endl; 2366 } else { 2367 cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->TrianglesCount << " triangles adjacent" << endl; 2368 } 2369 N++; 2370 baseline++; 2371 if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) { 2372 baseline = Tess->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines 2373 flag = false; 2374 } 2375 } 2376 if (failflag) { 2377 cout << Verbose(1) << "Writing final tecplot file\n"; 2378 if (DoTecplotOutput) 2379 write_tecplot_file(out, tecplot, Tess, mol, -1); 2380 if (DoRaster3DOutput) 2381 write_raster3d_file(out, tecplot, Tess, mol); 2382 } else { 2383 cerr << "ERROR: Could definately not find all necessary triangles!" << endl; 2384 } 2385 2386 cout << Verbose(0) << "End of Find_non_convex_border\n"; 2387 delete(Tess); 2388 2388 }; 2389 2389
Note:
See TracChangeset
for help on using the changeset viewer.
