Changeset 542ab3
- Timestamp:
- Jul 9, 2009, 10:22:05 AM (15 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
- Children:
- 4777e9
- Parents:
- 86234b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/boundary.cpp
r86234b r542ab3 1710 1710 1711 1711 1712 1713 /** This recursive function finds a third point, to form a triangle with two given ones.1714 * Two atoms are fixed, a candidate is supplied, additionally two vectors for direction distinction, a Storage area to \1715 * supply results to the calling function, the radius of the sphere which the triangle shall support and the molecule \1716 * upon which we operate.1717 * If the candidate is more fitting to support the sphere than the already stored atom is, then we write its general \1718 * direction and angle into Storage.1719 * We the determine the recursive level we have reached and if this is not on the threshold yet, call this function again, \1720 * with all neighbours of the candidate.1721 * @param a first point1722 * @param b second point1723 * *param c atom old third point of old triangle1724 * @param Candidate base point along whose bonds to start looking from1725 * @param Parent point to avoid during search as its wrong direction1726 * @param RecursionLevel contains current recursion depth1727 * @param Chord baseline vector of first and second point1728 * @param direction1 second in plane vector (along with \a Chord) of the triangle the baseline belongs to1729 * @param OldNormal normal of the triangle which the baseline belongs to1730 * @param ReferencePoint Vector of center of circumscribing circle from which we look towards center of sphere1731 * @param Opt_Candidate candidate reference to return1732 * @param Storage array containing two angles of current Opt_Candidate1733 * @param RADIUS radius of ball1734 * @param mol molecule structure with atoms and bonds1735 */1736 void Tesselation::Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom* Candidate, atom* Parent,1737 int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint,1738 atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol)1739 {1740 cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";1741 cout << Verbose(3) << "Candidate is "<< *Candidate << endl;1742 cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl;1743 cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl;1744 cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl;1745 cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl;1746 /* OldNormal is normal vector on the old triangle1747 * direction1 is normal on the triangle line, from which we come, as well as on OldNormal.1748 * Chord points from b to a!!!1749 */1750 Vector dif_a; //Vector from a to candidate1751 Vector dif_b; //Vector from b to candidate1752 Vector AngleCheck;1753 Vector TempNormal, Umkreismittelpunkt;1754 Vector Mittelpunkt;1755 1756 double CurrentEpsilon = 0.1;1757 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius, Distance;1758 double BallAngle, AlternativeSign;1759 atom *Walker; // variable atom point1760 1761 Vector NewUmkreismittelpunkt;1762 1763 if (a != Candidate and b != Candidate and c != Candidate) {1764 cout << Verbose(3) << "We have a unique candidate!" << endl;1765 dif_a.CopyVector(&(a->x));1766 dif_a.SubtractVector(&(Candidate->x));1767 dif_b.CopyVector(&(b->x));1768 dif_b.SubtractVector(&(Candidate->x));1769 AngleCheck.CopyVector(&(Candidate->x));1770 AngleCheck.SubtractVector(&(a->x));1771 AngleCheck.ProjectOntoPlane(Chord);1772 1773 SideA = dif_b.Norm();1774 SideB = dif_a.Norm();1775 SideC = Chord->Norm();1776 //Chord->Scale(-1);1777 1778 alpha = Chord->Angle(&dif_a);1779 beta = M_PI - Chord->Angle(&dif_b);1780 gamma = dif_a.Angle(&dif_b);1781 1782 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;1783 1784 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) {1785 cerr << Verbose(0) << "WARNING: sum of angles for base triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n";1786 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;1787 }1788 1789 if ((M_PI*179./180. > alpha) && (M_PI*179./180. > beta) && (M_PI*179./180. > gamma)) {1790 Umkreisradius = SideA / 2.0 / sin(alpha);1791 //cout << Umkreisradius << endl;1792 //cout << SideB / 2.0 / sin(beta) << endl;1793 //cout << SideC / 2.0 / sin(gamma) << endl;1794 1795 if (Umkreisradius < RADIUS) { //Checking whether ball will at least rest on points.1796 cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl;1797 cout << Verbose(2) << "Candidate is "<< *Candidate << endl;1798 sign = AngleCheck.ScalarProduct(direction1);1799 if (fabs(sign)<MYEPSILON) {1800 if (AngleCheck.ScalarProduct(OldNormal)<0) {1801 sign =0;1802 AlternativeSign=1;1803 } else {1804 sign =0;1805 AlternativeSign=-1;1806 }1807 } else {1808 sign /= fabs(sign);1809 }1810 if (sign >= 0) {1811 cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl;1812 1813 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), &NewUmkreismittelpunkt, OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius);1814 1815 Mittelpunkt.SubtractVector(&ReferencePoint);1816 cout << Verbose(3) << "Reference vector to sphere's center is " << Mittelpunkt << "." << endl;1817 1818 BallAngle = Mittelpunkt.Angle(OldNormal);1819 cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl;1820 1821 //cout << "direction1 is " << *direction1 << "." << endl;1822 //cout << "Mittelpunkt is " << Mittelpunkt << "."<< endl;1823 1824 //cout << Verbose(3) << "BallAngle is " << BallAngle << " Sign is " << sign << endl;1825 1826 NewUmkreismittelpunkt.SubtractVector(&ReferencePoint);1827 1828 if ((Mittelpunkt.ScalarProduct(direction1) >=0) || (fabs(NewUmkreismittelpunkt.Norm()) < MYEPSILON)) {1829 if (Storage[0]< -1.5) { // first Candidate at all1830 if (1) {//if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {1831 cout << Verbose(2) << "First good candidate is " << *Candidate << " with ";1832 Opt_Candidate = Candidate;1833 Storage[0] = sign;1834 Storage[1] = AlternativeSign;1835 Storage[2] = BallAngle;1836 cout << " angle " << Storage[2] << " and Up/Down "1837 << Storage[0] << endl;1838 } else1839 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;1840 } else {1841 if ( Storage[2] > BallAngle) {1842 if (1) { //if (CheckPresenceOfTriangle((ofstream *)&cout,a,b,Candidate)) {1843 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with ";1844 Opt_Candidate = Candidate;1845 Storage[0] = sign;1846 Storage[1] = AlternativeSign;1847 Storage[2] = BallAngle;1848 cout << " angle " << Storage[2] << " and Up/Down "1849 << Storage[0] << endl;1850 } else1851 cout << "Candidate " << *Candidate << " does not belong to a valid triangle." << endl;1852 } else {1853 if (DEBUG) {1854 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl;1855 }1856 }1857 }1858 } else {1859 if (DEBUG) {1860 cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl;1861 }1862 }1863 } else {1864 if (DEBUG) {1865 cout << Verbose(3) << *Candidate << " is not in search direction." << endl;1866 }1867 }1868 } else {1869 if (DEBUG) {1870 cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl;1871 }1872 }1873 } else {1874 if (DEBUG) {1875 cout << Verbose(0) << "Triangle consisting of " << *Candidate << ", " << *a << " and " << *b << " has an angle >150!" << endl;1876 }1877 }1878 } else {1879 if (DEBUG) {1880 cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl;1881 }1882 }1883 1884 if (RecursionLevel < 5) { // Seven is the recursion level threshold.1885 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) { // go through all bond1886 Walker = mol->ListOfBondsPerAtom[Candidate->nr][i]->GetOtherAtom(Candidate);1887 if (Walker == Parent) { // don't go back the same bond1888 continue;1889 } else {1890 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 again1891 }1892 }1893 }1894 cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n";1895 }1896 ;1897 1898 1899 1712 /** Constructs the center of the circumcircle defined by three points \a *a, \a *b and \a *c. 1900 1713 * \param *Center new center on return … … 1978 1791 } 1979 1792 }; 1980 1981 1982 /** This recursive function finds a third point, to form a triangle with two given ones.1983 * The idea is as follows: A sphere with fixed radius is (almost) uniquely defined in space by three points1984 * that sit on its boundary. Hence, when two points are given and we look for the (next) third point, then1985 * the center of the sphere is still fixed up to a single parameter. The band of possible values1986 * describes a circle in 3D-space. The old center of the sphere for the current base triangle gives1987 * us the "null" on this circle, the new center of the candidate point will be some way along this1988 * circle. The shorter the way the better is the candidate. Note that the direction is clearly given1989 * by the normal vector of the base triangle that always points outwards by construction.1990 * Hence, we construct a Center of this circle which sits right in the middle of the current base line.1991 * We construct the normal vector that defines the plane this circle lies in, it is just in the1992 * direction of the baseline. And finally, we need the radius of the circle, which is given by the rest1993 * with respect to the length of the baseline and the sphere's fixed \a RADIUS.1994 * Note that there is one difficulty: The circumcircle is uniquely defined, but for the circumsphere's center1995 * there are two possibilities which becomes clear from the construction as seen below. Hence, we must check1996 * both.1997 * Note also that the acos() function is not unique on [0, 2.*M_PI). Hence, we need an additional check1998 * to decide for one of the two possible angles. Therefore we need a SearchDirection and to make this check1999 * sensible we need OldSphereCenter to be orthogonal to it. Either we construct SearchDirection orthogonal2000 * right away, or -- what we do here -- we rotate the relative sphere centers such that this orthogonality2001 * holds. Then, the normalized projection onto the SearchDirection is either +1 or -1 and thus states whether2002 * the angle is uniquely in either (0,M_PI] or [M_PI, 2.*M_PI).2003 * @param BaseTriangle BoundaryTriangleSet of the current base triangle with all three points2004 * @param BaseLine BoundaryLineSet of BaseTriangle with the current base line2005 * @param OptCandidate candidate reference on return2006 * @param OptCandidateCenter candidate's sphere center on return2007 * @param ShortestAngle the current path length on this circle band for the current Opt_Candidate2008 * @param RADIUS radius of sphere2009 * @param *LC LinkedCell structure with neighbouring atoms2010 */2011 // void Find_next_suitable_point(class BoundaryTriangleSet *BaseTriangle, class BoundaryLineSet *BaseLine, atom*& OptCandidate, Vector *OptCandidateCenter, double *ShortestAngle, const double RADIUS, LinkedCell *LC)2012 // {2013 // atom *Walker = NULL;2014 // Vector CircleCenter; // center of the circle, i.e. of the band of sphere's centers2015 // Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in2016 // Vector OldSphereCenter; // center of the sphere defined by the three points of BaseTriangle2017 // Vector NewSphereCenter; // center of the sphere defined by the two points of BaseLine and the one of Candidate, first possibility2018 // Vector OtherNewSphereCenter; // center of the sphere defined by the two points of BaseLine and the one of Candidate, second possibility2019 // Vector NewNormalVector; // normal vector of the Candidate's triangle2020 // Vector SearchDirection; // vector that points out of BaseTriangle and is orthonormal to its NormalVector (i.e. the desired direction for the best Candidate)2021 // Vector helper;2022 // LinkedAtoms *List = NULL;2023 // double CircleRadius; // radius of this circle2024 // double radius;2025 // double alpha, Otheralpha; // angles (i.e. parameter for the circle).2026 // double Nullalpha; // angle between OldSphereCenter and NormalVector of base triangle2027 // int N[NDIM], Nlower[NDIM], Nupper[NDIM];2028 // atom *Candidate = NULL;2029 //2030 // cout << Verbose(1) << "Begin of Find_next_suitable_point" << endl;2031 //2032 // cout << Verbose(2) << "INFO: NormalVector of BaseTriangle is " << BaseTriangle->NormalVector << "." << endl;2033 //2034 // // construct center of circle2035 // CircleCenter.CopyVector(&(BaseLine->endpoints[0]->node->x));2036 // CircleCenter.AddVector(&BaseLine->endpoints[1]->node->x);2037 // CircleCenter.Scale(0.5);2038 //2039 // // construct normal vector of circle2040 // CirclePlaneNormal.CopyVector(&BaseLine->endpoints[0]->node->x);2041 // CirclePlaneNormal.SubtractVector(&BaseLine->endpoints[1]->node->x);2042 //2043 // // calculate squared radius of circle2044 // radius = CirclePlaneNormal.ScalarProduct(&CirclePlaneNormal);2045 // if (radius/4. < RADIUS*RADIUS) {2046 // CircleRadius = RADIUS*RADIUS - radius/4.;2047 // CirclePlaneNormal.Normalize();2048 // cout << Verbose(2) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;2049 //2050 // // construct old center2051 // GetCenterofCircumcircle(&OldSphereCenter, &(BaseTriangle->endpoints[0]->node->x), &(BaseTriangle->endpoints[1]->node->x), &(BaseTriangle->endpoints[2]->node->x));2052 // helper.CopyVector(&BaseTriangle->NormalVector); // normal vector ensures that this is correct center of the two possible ones2053 // radius = BaseLine->endpoints[0]->node->x.DistanceSquared(&OldSphereCenter);2054 // helper.Scale(sqrt(RADIUS*RADIUS - radius));2055 // OldSphereCenter.AddVector(&helper);2056 // OldSphereCenter.SubtractVector(&CircleCenter);2057 // cout << Verbose(2) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl;2058 //2059 // // test whether old center is on the band's plane2060 // if (fabs(OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) > HULLEPSILON) {2061 // cerr << "ERROR: Something's very wrong here: OldSphereCenter is not on the band's plane as desired by " << fabs(OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) << "!" << endl;2062 // OldSphereCenter.ProjectOntoPlane(&CirclePlaneNormal);2063 // }2064 // radius = OldSphereCenter.ScalarProduct(&OldSphereCenter);2065 // if (fabs(radius - CircleRadius) < HULLEPSILON) {2066 //2067 // // construct SearchDirection2068 // SearchDirection.MakeNormalVector(&BaseTriangle->NormalVector, &CirclePlaneNormal);2069 // helper.CopyVector(&BaseLine->endpoints[0]->node->x);2070 // for(int i=0;i<3;i++) // just take next different endpoint2071 // if ((BaseTriangle->endpoints[i]->node != BaseLine->endpoints[0]->node) && (BaseTriangle->endpoints[i]->node != BaseLine->endpoints[1]->node)) {2072 // helper.SubtractVector(&BaseTriangle->endpoints[i]->node->x);2073 // }2074 // if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON) // ohoh, SearchDirection points inwards!2075 // SearchDirection.Scale(-1.);2076 // SearchDirection.ProjectOntoPlane(&OldSphereCenter);2077 // SearchDirection.Normalize();2078 // cout << Verbose(2) << "INFO: SearchDirection is " << SearchDirection << "." << endl;2079 // if (fabs(OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { // rotated the wrong way!2080 // cerr << "ERROR: SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl;2081 // }2082 //2083 // if (LC->SetIndexToVector(&CircleCenter)) { // get cell for the starting atom2084 // for(int i=0;i<NDIM;i++) // store indices of this cell2085 // N[i] = LC->n[i];2086 // cout << Verbose(2) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl;2087 // } else {2088 // cerr << "ERROR: Vector " << CircleCenter << " is outside of LinkedCell's bounding box." << endl;2089 // return;2090 // }2091 // // then go through the current and all neighbouring cells and check the contained atoms for possible candidates2092 // cout << Verbose(2) << "LC Intervals:";2093 // for (int i=0;i<NDIM;i++) {2094 // Nlower[i] = ((N[i]-1) >= 0) ? N[i]-1 : 0;2095 // Nupper[i] = ((N[i]+1) < LC->N[i]) ? N[i]+1 : LC->N[i]-1;2096 // cout << " [" << Nlower[i] << "," << Nupper[i] << "] ";2097 // }2098 // cout << endl;2099 // for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++)2100 // for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++)2101 // for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) {2102 // List = LC->GetCurrentCell();2103 // cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl;2104 // if (List != NULL) {2105 // for (LinkedAtoms::iterator Runner = List->begin(); Runner != List->end(); Runner++) {2106 // Candidate = (*Runner);2107 //2108 // // check for three unique points2109 // if ((Candidate != BaseTriangle->endpoints[0]->node) && (Candidate != BaseTriangle->endpoints[1]->node) && (Candidate != BaseTriangle->endpoints[2]->node)) {2110 // cout << Verbose(1) << "INFO: Current Candidate is " << *Candidate << " at " << Candidate->x << "." << endl;2111 //2112 // // construct both new centers2113 // GetCenterofCircumcircle(&NewSphereCenter, &(BaseLine->endpoints[0]->node->x), &(BaseLine->endpoints[1]->node->x), &(Candidate->x));2114 // OtherNewSphereCenter.CopyVector(&NewSphereCenter);2115 //2116 // if ((NewNormalVector.MakeNormalVector(&(BaseLine->endpoints[0]->node->x), &(BaseLine->endpoints[1]->node->x), &(Candidate->x))) && (fabs(NewNormalVector.ScalarProduct(&NewNormalVector)) > HULLEPSILON)) {2117 // helper.CopyVector(&NewNormalVector);2118 // cout << Verbose(2) << "INFO: NewNormalVector is " << NewNormalVector << "." << endl;2119 // radius = BaseLine->endpoints[0]->node->x.DistanceSquared(&NewSphereCenter);2120 // if (radius < RADIUS*RADIUS) {2121 // helper.Scale(sqrt(RADIUS*RADIUS - radius));2122 // cout << Verbose(3) << "INFO: Distance of NewCircleCenter to NewSphereCenter is " << helper.Norm() << "." << endl;2123 // NewSphereCenter.AddVector(&helper);2124 // NewSphereCenter.SubtractVector(&CircleCenter);2125 // cout << Verbose(2) << "INFO: NewSphereCenter is at " << NewSphereCenter << "." << endl;2126 //2127 // helper.Scale(-1.); // OtherNewSphereCenter is created by the same vector just in the other direction2128 // OtherNewSphereCenter.AddVector(&helper);2129 // OtherNewSphereCenter.SubtractVector(&CircleCenter);2130 // cout << Verbose(2) << "INFO: OtherNewSphereCenter is at " << OtherNewSphereCenter << "." << endl;2131 //2132 // // check both possible centers2133 // alpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, NewSphereCenter, OldSphereCenter, BaseTriangle->NormalVector, SearchDirection);2134 // Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, BaseTriangle->NormalVector, SearchDirection);2135 // alpha = min(alpha, Otheralpha);2136 // if (*ShortestAngle > alpha) {2137 // OptCandidate = Candidate;2138 // *ShortestAngle = alpha;2139 // if (alpha != Otheralpha)2140 // OptCandidateCenter->CopyVector(&NewSphereCenter);2141 // else2142 // OptCandidateCenter->CopyVector(&OtherNewSphereCenter);2143 // cout << Verbose(1) << "We have found a better candidate: " << *OptCandidate << " with " << alpha << " and circumsphere's center at " << *OptCandidateCenter << "." << endl;2144 // } else {2145 // if (OptCandidate != NULL)2146 // cout << Verbose(1) << "REJECT: Old candidate: " << *OptCandidate << " is better than " << alpha << " with " << *ShortestAngle << "." << endl;2147 // else2148 // cout << Verbose(2) << "REJECT: Candidate " << *Candidate << " with " << alpha << " was rejected." << endl;2149 // }2150 //2151 // } else {2152 // cout << Verbose(1) << "REJECT: NewSphereCenter " << NewSphereCenter << " is too far away: " << radius << "." << endl;2153 // }2154 // } else {2155 // cout << Verbose(1) << "REJECT: Three points from " << *BaseLine << " and Candidate " << *Candidate << " are linear-dependent." << endl;2156 // }2157 // } else {2158 // cout << Verbose(1) << "REJECT: Base triangle " << *BaseTriangle << " contains Candidate " << *Candidate << "." << endl;2159 // }2160 // }2161 // }2162 // }2163 // } else {2164 // cerr << Verbose(1) << "ERROR: The projected center of the old sphere has radius " << radius << " instead of " << CircleRadius << "." << endl;2165 // }2166 // } else {2167 // cout << Verbose(1) << "Circumcircle for base line " << *BaseLine << " and base triangle " << *BaseTriangle << " is too big!" << endl;2168 // }2169 //2170 // cout << Verbose(1) << "End of Find_next_suitable_point" << endl;2171 // };2172 1793 2173 1794 … … 2450 2071 }; 2451 2072 2452 /**2453 * Finds the preferable out of two third-point candidates with equal angles.2454 *2455 * @param Candidate - this and the second parameter are evaluated2456 * @param OptCandidate - this and the second parameter are evaluated2457 * @param current base line2458 * @param third node of the base triangle2459 * @param tesselation object2460 *2461 * @return true if Candidate should be taken, false if OptCandidate should be kept2462 */2463 bool Choose_preferable_third_point(2464 atom *Candidate, atom *OptCandidate, class BoundaryLineSet *BaseLine,2465 atom *ThirdNode, Tesselation *Tess2466 ) {2467 bool takeNewCandidate;2468 2469 ofstream *out = new ofstream();2470 atom *Atoms[3];2471 bool optCandidateAndBaseLineFormTriangle = (ThirdNode != NULL) && (OptCandidate == ThirdNode);2472 bool candidateAndBaseLineFormTriangle = (ThirdNode != NULL) && (Candidate == ThirdNode);2473 Atoms[0] = Candidate;2474 Atoms[1] = OptCandidate;2475 Atoms[2] = BaseLine->endpoints[0]->node;2476 bool candidatesAndBaseLineNode0FormTriangle = (Tess->CheckPresenceOfTriangle(out, Atoms) > 0);2477 Atoms[0] = Candidate;2478 Atoms[1] = OptCandidate;2479 Atoms[2] = BaseLine->endpoints[1]->node;2480 bool candidatesAndBaseLineNode1FormTriangle = (Tess->CheckPresenceOfTriangle(out, Atoms) > 0);2481 Vector halfBaseLine;2482 halfBaseLine.CopyVector(&BaseLine->endpoints[0]->node->x);2483 halfBaseLine.AddVector(&BaseLine->endpoints[1]->node->x);2484 halfBaseLine.Scale(0.5);2485 2486 if (optCandidateAndBaseLineFormTriangle) {2487 takeNewCandidate = (!existsIntersection(Candidate->x, halfBaseLine, OptCandidate->x, BaseLine->endpoints[0]->node->x)2488 && !existsIntersection(Candidate->x, halfBaseLine, OptCandidate->x, BaseLine->endpoints[1]->node->x));2489 } else if (candidateAndBaseLineFormTriangle) {2490 takeNewCandidate = (existsIntersection(OptCandidate->x, halfBaseLine, Candidate->x, BaseLine->endpoints[0]->node->x)2491 || existsIntersection(OptCandidate->x, halfBaseLine, Candidate->x, BaseLine->endpoints[1]->node->x));2492 } else if (candidatesAndBaseLineNode0FormTriangle) {2493 takeNewCandidate = !existsIntersection(OptCandidate->x, BaseLine->endpoints[0]->node->x, Candidate->x, halfBaseLine);2494 } else if (candidatesAndBaseLineNode1FormTriangle) {2495 takeNewCandidate = !existsIntersection(OptCandidate->x, BaseLine->endpoints[1]->node->x, Candidate->x, halfBaseLine);2496 } else {2497 takeNewCandidate = (ThirdNode == NULL)2498 || ((!existsIntersection(Candidate->x, halfBaseLine, ThirdNode->x, BaseLine->endpoints[0]->node->x)2499 && !existsIntersection(Candidate->x, halfBaseLine, ThirdNode->x, BaseLine->endpoints[1]->node->x)));2500 }2501 2502 return takeNewCandidate;2503 };2504 2505 2073 2506 2074 struct Intersection {
Note:
See TracChangeset
for help on using the changeset viewer.