Changes in src/boundary.cpp [196a5a:44fd95]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/boundary.cpp
r196a5a r44fd95 2 2 #include "boundary.hpp" 3 3 4 #define DEBUG 04 #define DEBUG 1 5 5 6 6 // ======================================== Points on Boundary ================================= … … 1422 1422 * @param c vector third point of triangle 1423 1423 * @param Direction vector indicates up/down 1424 * @param AlternativeDirection vecotr, needed in case the triangles have 90 deg angle1425 1424 * @param Halfplaneindicator double indicates whether Direction is up or down 1426 * @param AlternativeIndicator doube indicates in case of orthogonal triangles which direction of AlternativeDirection is suitable1427 1425 * @param alpha double angle at a 1428 1426 * @param beta double, angle at b … … 1432 1430 */ 1433 1431 1434 void Get_center_of_sphere(Vector* Center, Vector a, Vector b, Vector c, Vector* Direction, Vector* AlternativeDirection,1435 double HalfplaneIndicator, double AlternativeIndicator, doublealpha, double beta, double gamma, double RADIUS, double Umkreisradius)1432 void Get_center_of_sphere(Vector* Center, Vector a, Vector b, Vector c, Vector* Direction, double HalfplaneIndicator, 1433 double alpha, double beta, double gamma, double RADIUS, double Umkreisradius) 1436 1434 { 1437 1435 Vector TempNormal, helper; 1438 1436 double Restradius; 1439 1437 cout << Verbose(3) << "Begin of Get_center_of_sphere.\n"; 1440 1438 *Center = a * sin(2.*alpha) + b * sin(2.*beta) + c * sin(2.*gamma) ; 1441 Center->Scale(1 ./(sin(2.*alpha) + sin(2.*beta) + sin(2.*gamma)));1439 Center->Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma))); 1442 1440 // Here we calculated center of circumscribing circle, using barycentric coordinates 1441 cout << Verbose(4) << "Center of circumference is " << *Center << " in direction " << *Direction << ".\n"; 1443 1442 1444 1443 TempNormal.CopyVector(&a); … … 1447 1446 helper.SubtractVector(&c); 1448 1447 TempNormal.VectorProduct(&helper); 1449 if ( fabs(HalfplaneIndicator) < MYEPSILON)1448 if (TempNormal.ScalarProduct(Direction)<0 && HalfplaneIndicator >0 || TempNormal.ScalarProduct(Direction)>0 && HalfplaneIndicator<0) 1450 1449 { 1451 if ((TempNormal.ScalarProduct(AlternativeDirection) <0 and AlternativeIndicator >0) or (TempNormal.ScalarProduct(AlternativeDirection) >0 and AlternativeIndicator <0)) 1452 { 1453 TempNormal.Scale(-1); 1454 } 1455 } 1456 else 1457 { 1458 if (TempNormal.ScalarProduct(Direction)<0 && HalfplaneIndicator >0 || TempNormal.ScalarProduct(Direction)>0 && HalfplaneIndicator<0) 1459 { 1460 TempNormal.Scale(-1); 1461 } 1450 TempNormal.Scale(-1); 1462 1451 } 1463 1452 1464 1453 TempNormal.Normalize(); 1465 1454 Restradius = sqrt(RADIUS*RADIUS - Umkreisradius*Umkreisradius); 1455 cout << Verbose(4) << "Height of center of circumference to center of sphere is " << Restradius << ".\n"; 1466 1456 TempNormal.Scale(Restradius); 1457 cout << Verbose(4) << "Shift vector to sphere of circumference is " << TempNormal << ".\n"; 1467 1458 1468 1459 Center->AddVector(&TempNormal); 1460 cout << Verbose(4) << "Center of sphere of circumference is " << *Center << ".\n"; 1461 cout << Verbose(3) << "End of Get_center_of_sphere.\n"; 1469 1462 } 1470 1463 ; … … 1481 1474 * @param a first point 1482 1475 * @param b second point 1483 * *param c atom old third point of old triangle1484 1476 * @param Candidate base point along whose bonds to start looking from 1485 1477 * @param Parent point to avoid during search as its wrong direction … … 1495 1487 */ 1496 1488 1497 void Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* c, atom*Candidate, atom* Parent,1489 void Find_next_suitable_point_via_Angle_of_Sphere(atom* a, atom* b, atom* Candidate, atom* Parent, 1498 1490 int RecursionLevel, Vector *Chord, Vector *direction1, Vector *OldNormal, Vector ReferencePoint, 1499 1491 atom*& Opt_Candidate, double *Storage, const double RADIUS, molecule* mol) 1500 1492 { 1501 //cout << "ReferencePoint is " << ReferencePoint.x[0] << " "<< ReferencePoint.x[1] << " "<< ReferencePoint.x[2] << " "<< endl; 1493 cout << Verbose(2) << "Begin of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n"; 1494 cout << Verbose(3) << "Candidate is "<< *Candidate << endl; 1495 cout << Verbose(4) << "Baseline vector is " << *Chord << "." << endl; 1496 cout << Verbose(4) << "ReferencePoint is " << ReferencePoint << "." << endl; 1497 cout << Verbose(4) << "Normal of base triangle is " << *OldNormal << "." << endl; 1498 cout << Verbose(4) << "Search direction is " << *direction1 << "." << endl; 1502 1499 /* OldNormal is normal vector on the old triangle 1503 1500 * direction1 is normal on the triangle line, from which we come, as well as on OldNormal. … … 1512 1509 double CurrentEpsilon = 0.1; 1513 1510 double alpha, beta, gamma, SideA, SideB, SideC, sign, Umkreisradius, Restradius, Distance; 1514 double BallAngle , AlternativeSign;1511 double BallAngle; 1515 1512 atom *Walker; // variable atom point 1516 1513 1517 1514 1518 dif_a.CopyVector(&(a->x)); 1519 dif_a.SubtractVector(&(Candidate->x)); 1520 dif_b.CopyVector(&(b->x)); 1521 dif_b.SubtractVector(&(Candidate->x)); 1522 AngleCheck.CopyVector(&(Candidate->x)); 1523 AngleCheck.SubtractVector(&(a->x)); 1524 AngleCheck.ProjectOntoPlane(Chord); 1525 1526 SideA = dif_b.Norm(); 1527 SideB = dif_a.Norm(); 1528 SideC = Chord->Norm(); 1529 //Chord->Scale(-1); 1530 1531 alpha = Chord->Angle(&dif_a); 1532 beta = M_PI - Chord->Angle(&dif_b); 1533 gamma = dif_a.Angle(&dif_b); 1534 1535 1536 if (a != Candidate and b != Candidate and c != Candidate) 1537 { 1515 if (a != Candidate and b != Candidate) 1516 { 1517 cout << Verbose(3) << "We have a unique candidate!" << endl; 1518 dif_a.CopyVector(&(a->x)); 1519 dif_a.SubtractVector(&(Candidate->x)); 1520 dif_b.CopyVector(&(b->x)); 1521 dif_b.SubtractVector(&(Candidate->x)); 1522 AngleCheck.CopyVector(&(Candidate->x)); 1523 AngleCheck.SubtractVector(&(a->x)); 1524 AngleCheck.ProjectOntoPlane(Chord); 1525 1526 SideA = dif_b.Norm(); 1527 SideB = dif_a.Norm(); 1528 SideC = Chord->Norm(); 1529 //Chord->Scale(-1); 1530 1531 alpha = Chord->Angle(&dif_a); 1532 beta = M_PI - Chord->Angle(&dif_b); 1533 gamma = dif_a.Angle(&dif_b); 1534 1535 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; 1536 1537 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) 1538 cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n"; 1538 1539 1539 1540 Umkreisradius = SideA / 2.0 / sin(alpha); … … 1544 1545 if (Umkreisradius < RADIUS) //Checking whether ball will at least rest on points. 1545 1546 { 1546 cout << Verbose( 1) << "Candidate is "<< *Candidate<< endl;1547 cout << Verbose(3) << "Circle of circumference would fit: " << Umkreisradius << " < " << RADIUS << "." << endl; 1547 1548 sign = AngleCheck.ScalarProduct(direction1); 1548 if (fabs(sign)<MYEPSILON) 1549 if (fabs(sign) < MYEPSILON) 1550 sign = 0; 1551 else 1552 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction... 1553 if (sign >= 0) 1549 1554 { 1550 if (AngleCheck.ScalarProduct(OldNormal)<0) 1555 cout << Verbose(3) << "Candidate is in search direction: " << sign << "." << endl; 1556 1557 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), OldNormal, sign, alpha, beta, gamma, RADIUS, Umkreisradius); 1558 1559 AngleCheck.CopyVector(&ReferencePoint); 1560 AngleCheck.Scale(-1); 1561 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1562 AngleCheck.AddVector(&Mittelpunkt); 1563 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1564 cout << Verbose(4) << "Reference vector to sphere's center is " << AngleCheck << "." << endl; 1565 1566 BallAngle = AngleCheck.Angle(OldNormal); 1567 cout << Verbose(3) << "Angle between normal of base triangle and center of ball sphere is :" << BallAngle << "." << endl; 1568 // cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl; 1569 // cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1570 sign = AngleCheck.ScalarProduct(direction1); 1571 if (fabs(sign) < MYEPSILON) 1572 sign = 0; 1573 else 1574 sign /= fabs(sign); 1575 1576 1577 if (Storage[0]< -1.5) // first Candidate at all 1551 1578 { 1552 sign =0; 1553 AlternativeSign=1; 1579 1580 cout << Verbose(2) << "First good candidate is " << *Candidate << " with "; 1581 Opt_Candidate = Candidate; 1582 Storage[0] = sign; 1583 Storage[1] = BallAngle; 1584 cout << " angle " << Storage[1] << " and Up/Down " 1585 << Storage[0] << endl; 1554 1586 } 1555 1587 else 1556 1588 { 1557 sign =0; 1558 AlternativeSign=-1; 1559 } 1560 } 1561 else 1562 { 1563 sign /= fabs(sign); 1564 } 1565 1566 1567 1568 Get_center_of_sphere(&Mittelpunkt, (a->x), (b->x), (Candidate->x), OldNormal, direction1, sign, AlternativeSign, alpha, beta, gamma, RADIUS, Umkreisradius); 1569 1570 AngleCheck.CopyVector(&ReferencePoint); 1571 AngleCheck.Scale(-1); 1572 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1573 AngleCheck.AddVector(&Mittelpunkt); 1574 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1575 1576 BallAngle = AngleCheck.Angle(OldNormal); 1577 1578 //cout << "direction1 is " << direction1->x[0] <<" "<< direction1->x[1] <<" "<< direction1->x[2] <<" " << endl; 1579 //cout << "AngleCheck is " << AngleCheck.x[0] << " "<< AngleCheck.x[1] << " "<< AngleCheck.x[2] << " "<< endl; 1580 1581 cout << Verbose(1) << "BallAngle is " << BallAngle << " Sign is " << sign << endl; 1582 1583 if (AngleCheck.ScalarProduct(direction1) >=0) 1584 { 1585 if (Storage[0]< -1.5) // first Candidate at all 1586 { 1587 1588 cout << "Next better candidate is " << *Candidate << " with "; 1589 Opt_Candidate = Candidate; 1590 Storage[0] = sign; 1591 Storage[1] = AlternativeSign; 1592 Storage[2] = BallAngle; 1593 cout << "Angle is " << Storage[2] << ", Halbraum ist " 1594 << Storage[0] << endl; 1595 1596 1597 } 1598 else 1599 { 1600 if ( Storage[2] > BallAngle) 1589 if ( Storage[1] > BallAngle) 1601 1590 { 1602 cout << "Next better candidate is " << *Candidate << " with ";1591 cout << Verbose(2) << "Next better candidate is " << *Candidate << " with "; 1603 1592 Opt_Candidate = Candidate; 1604 1593 Storage[0] = sign; 1605 Storage[1] = AlternativeSign; 1606 Storage[2] = BallAngle; 1607 cout << "Angle is " << Storage[2] << ", Halbraum ist " 1594 Storage[1] = BallAngle; 1595 cout << " angle " << Storage[1] << " and Up/Down " 1608 1596 << Storage[0] << endl; 1609 1597 } 1610 1598 else 1611 1599 { 1612 //if (DEBUG) 1613 cout << "Looses to better candidate" << endl; 1614 1600 if (DEBUG) 1601 { 1602 cout << Verbose(3) << *Candidate << " looses against better candidate " << *Opt_Candidate << "." << endl; 1603 } 1615 1604 } 1616 1605 } … … 1618 1607 else 1619 1608 { 1620 //if (DEBUG) 1621 cout << "Refused due to bad direction of ball centre." << endl; 1609 if (DEBUG) 1610 { 1611 cout << Verbose(3) << *Candidate << " refused due to Up/Down sign which is " << sign << endl; 1612 } 1622 1613 } 1623 1614 } 1624 1615 else 1625 1616 { 1626 //if (DEBUG) 1627 cout << "Doesn't satisfy requirements for circumscribing circle" << endl; 1617 if (DEBUG) 1618 { 1619 cout << Verbose(3) << *Candidate << " would have circumference of " << Umkreisradius << " bigger than ball's radius " << RADIUS << "." << endl; 1620 } 1628 1621 } 1629 1622 } 1630 1623 else 1631 1624 { 1632 //if (DEBUG) 1633 cout << "identisch mit Ursprungslinie" << endl; 1634 1625 if (DEBUG) 1626 { 1627 cout << Verbose(3) << *Candidate << " is either " << *a << " or " << *b << "." << endl; 1628 } 1635 1629 } 1636 1630 1637 1631 1638 1632 1639 if (RecursionLevel < 9) // Sevenis the recursion level threshold.1633 if (RecursionLevel < 7) // Five is the recursion level threshold. 1640 1634 { 1641 1635 for (int i = 0; i < mol->NumberOfBondsPerAtom[Candidate->nr]; i++) // go through all bond … … 1649 1643 else 1650 1644 { 1651 Find_next_suitable_point_via_Angle_of_Sphere(a, b, c,Walker, Candidate, RecursionLevel1645 Find_next_suitable_point_via_Angle_of_Sphere(a, b, Walker, Candidate, RecursionLevel 1652 1646 + 1, Chord, direction1, OldNormal, ReferencePoint, Opt_Candidate, Storage, RADIUS, 1653 1647 mol); //call function again … … 1655 1649 } 1656 1650 } 1651 cout << Verbose(2) << "End of Find_next_suitable_point_via_Angle_of_Sphere, recursion level " << RecursionLevel << ".\n"; 1657 1652 } 1658 1653 ; … … 1776 1771 d1->ProjectOntoPlane(&AngleCheckReference); 1777 1772 sign = AngleCheck.ScalarProduct(d1); 1778 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction... 1773 if (fabs(sign) < MYEPSILON) 1774 sign = 0; 1775 else 1776 sign /= fabs(sign); // +1 if in direction of triangle plane, -1 if in other direction... 1779 1777 1780 1778 … … 1934 1932 const double& RADIUS, int N) 1935 1933 { 1936 cout << Verbose(1) << " Looking for next suitable triangle\n";1934 cout << Verbose(1) << "Begin of Find_next_suitable_triangle\n"; 1937 1935 Vector direction1; 1938 1936 Vector helper; … … 1940 1938 ofstream *tempstream = NULL; 1941 1939 char filename[255]; 1942 atom* OldThirdPoint; 1943 1944 double Storage[3]; 1940 double tmp; 1941 //atom* Walker; 1942 1943 double Storage[2]; 1945 1944 Storage[0] = -2.; // This direction is either +1 or -1 one, so any result will take precedence over initial values 1946 Storage[1] = -2.; // This is also lower then any value produced by an eligible atom, which are all positive 1947 Storage[2] = 9999999.; 1945 Storage[1] = 9999999.; // This is also lower then any value produced by an eligible atom, which are all positive 1948 1946 atom* Opt_Candidate = NULL; 1949 1947 Vector Opt_Mittelpunkt; 1950 1948 1951 cout << Verbose(1) << "Constructing helpful vectors ... " << endl; 1949 cout << Verbose(1) << "Current baseline is " << Line << " of triangle " << T << "." << endl; 1950 1952 1951 helper.CopyVector(&(Line.endpoints[0]->node->x)); 1953 1952 for (int i = 0; i < 3; i++) … … 1956 1955 && T.endpoints[i]->node->nr != Line.endpoints[1]->node->nr) 1957 1956 { 1958 OldThirdPoint = T.endpoints[i]->node;1959 1957 helper.SubtractVector(&T.endpoints[i]->node->x); 1960 1958 break; … … 1970 1968 direction1.Scale(-1); 1971 1969 } 1970 cout << Verbose(2) << "Looking in direction " << direction1 << " for candidates.\n"; 1972 1971 1973 1972 Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function 1974 1973 Chord.SubtractVector(&(Line.endpoints[1]->node->x)); 1975 1976 1977 Vector Umkreismittelpunkt, a, b, c; 1978 double alpha, beta, gamma; 1979 a.CopyVector(&(T.endpoints[0]->node->x)); 1980 b.CopyVector(&(T.endpoints[1]->node->x)); 1981 c.CopyVector(&(T.endpoints[2]->node->x)); 1982 a.SubtractVector(&(T.endpoints[1]->node->x)); 1983 b.SubtractVector(&(T.endpoints[2]->node->x)); 1984 c.SubtractVector(&(T.endpoints[0]->node->x)); 1985 1986 alpha = M_PI - a.Angle(&c); 1987 beta = M_PI - b.Angle(&a); 1988 gamma = M_PI - c.Angle(&b); 1989 1990 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) ; 1991 //cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl; 1992 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma))); 1993 cout << "UmkreisMittelpunkt is " << Umkreismittelpunkt.x[0] << " "<< Umkreismittelpunkt.x[1] << " "<< Umkreismittelpunkt.x[2] << " "<< endl; 1994 cout << " We look over line " << Line << " in direction " << direction1.x[0] << " " << direction1.x[1] << " " << direction1.x[2] << " " << endl; 1995 cout << " Old Normal is " << (T.NormalVector.x)[0] << " " << T.NormalVector.x[1] << " " << (T.NormalVector.x)[2] << " " << endl; 1996 1974 cout << Verbose(2) << "Baseline vector is " << Chord << ".\n"; 1975 1976 1977 Vector Umkreismittelpunkt, a, b, c; 1978 double alpha, beta, gamma; 1979 a.CopyVector(&(T.endpoints[0]->node->x)); 1980 b.CopyVector(&(T.endpoints[1]->node->x)); 1981 c.CopyVector(&(T.endpoints[2]->node->x)); 1982 a.SubtractVector(&(T.endpoints[1]->node->x)); 1983 b.SubtractVector(&(T.endpoints[2]->node->x)); 1984 c.SubtractVector(&(T.endpoints[0]->node->x)); 1985 1986 alpha = a.Angle(&c) - M_PI/2.; 1987 beta = b.Angle(&a); 1988 gamma = c.Angle(&b) - M_PI/2.; 1989 if (fabs(M_PI - alpha - beta - gamma) > MYEPSILON) 1990 cerr << Verbose(0) << "WARNING: sum of angles for candidate triangle " << (alpha + beta + gamma)/M_PI*180. << " != 180.\n"; 1991 1992 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; 1993 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) ; 1994 Umkreismittelpunkt.Scale(1/(sin(2*alpha) + sin(2*beta) + sin(2*gamma))); 1995 cout << Verbose(2) << "Center of circumference is " << Umkreismittelpunkt << "." << endl; 1996 if (DEBUG) 1997 cout << Verbose(3) << "Check of relative endpoints (same distance, equally spreaded): "<< endl; 1998 tmp = 0; 1999 for (int i=0;i<NDIM;i++) { 2000 helper.CopyVector(&T.endpoints[i]->node->x); 2001 helper.SubtractVector(&Umkreismittelpunkt); 2002 if (DEBUG) 2003 cout << Verbose(3) << "Endpoint[" << i << "]: " << helper << " with length " << helper.Norm() << "." << endl; 2004 if (tmp == 0) // set on first time for comparison against next ones 2005 tmp = helper.Norm(); 2006 if (fabs(helper.Norm() - tmp) > MYEPSILON) 2007 cerr << Verbose(1) << "WARNING: center of circumference is wrong!" << endl; 2008 } 1997 2009 1998 2010 cout << Verbose(1) << "Looking for third point candidates for triangle ... " << endl; 1999 2011 2000 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint,2012 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, 2001 2013 Line.endpoints[0]->node, Line.endpoints[1]->node, 0, &Chord, &direction1, 2002 2014 &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol); 2003 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, OldThirdPoint,2015 Find_next_suitable_point_via_Angle_of_Sphere(Line.endpoints[0]->node, Line.endpoints[1]->node, 2004 2016 Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, 2005 2017 &(T.NormalVector), Umkreismittelpunkt, Opt_Candidate, Storage, RADIUS, mol); 2006 2018 2007 2019 2008 cout << "Letzter Winkel bei " << TrianglesOnBoundaryCount << " Winkel ist " << Storage[2] << endl; 2009 2010 2011 if ((TrianglesOnBoundaryCount % 1) == 0) 2012 { 2020 if ((TrianglesOnBoundaryCount % 10) == 0) 2021 { 2022 cout << Verbose(1) << "Writing temporary non convex hull to file testEnvelope-" << TriangleFilesWritten << "d.dat.\n"; 2013 2023 sprintf(filename, "testEnvelope-%d.dat", TriangleFilesWritten); 2014 2024 tempstream = new ofstream(filename, ios::trunc); … … 2019 2029 } 2020 2030 2021 if (TrianglesOnBoundaryCount >1 89 and TrianglesOnBoundaryCount < 200 )2022 { 2023 c out << Verbose(1)2024 << " No new Atom found, triangle construction will crash" << endl;2031 if (TrianglesOnBoundaryCount >1000 ) 2032 { 2033 cerr << Verbose(0) 2034 << "WARNING: Already more than " << TrianglesOnBoundaryCount-1 << "triangles, construction probably has crashed." << endl; 2025 2035 write_tecplot_file(out, tecplot, this, mol, TriangleFilesWritten); 2026 cout << "This is currently added candidate" << Opt_Candidate << endl;2036 cout << Verbose(2) << "This is currently added candidate" << Opt_Candidate << endl; 2027 2037 } 2028 2038 // Konstruiere nun neues Dreieck am Ende der Liste der Dreiecke 2029 2039 2030 cout << " Optimal candidate is " << *Opt_Candidate << endl;2040 cout << Verbose(2) << " Optimal candidate is " << *Opt_Candidate << endl; 2031 2041 2032 2042 AddTrianglePoint(Opt_Candidate, 0); … … 2040 2050 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2041 2051 AddTriangleToLines(); 2042 cout << "New triangle with " << *BTS << endl; 2043 cout << "We have "<< TrianglesOnBoundaryCount << endl; 2044 cout << Verbose(1) << "Constructing normal vector for this triangle ... " << endl; 2045 2046 BTS->GetNormalVector(BTS->NormalVector); 2047 2048 if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0) || 2049 (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0) || 2050 (fabs(Storage[0]) < MYEPSILON && Storage[1]*BTS->NormalVector.ScalarProduct(&direction1) < 0) ) 2051 2052 { 2053 BTS->NormalVector.Scale(-1); 2054 }; 2055 2052 2053 BTS->GetNormalVector(T.NormalVector); 2054 2055 // if ((BTS->NormalVector.ScalarProduct(&(T.NormalVector)) < 0 && Storage[0] > 0) || 2056 // (BTS->NormalVector.ScalarProduct(&(T.NormalVector)) > 0 && Storage[0] < 0)) 2057 // { 2058 // BTS->NormalVector.Scale(-1); 2059 // }; 2060 cout << Verbose(2) << "New triangle with " << *BTS << "and normal vector " << BTS->NormalVector << " for this triangle ... " << endl; 2061 cout << Verbose(2) << "We have "<< TrianglesOnBoundaryCount << " for line " << Line << "." << endl; 2062 cout << Verbose(1) << "End of Find_next_suitable_triangle\n"; 2056 2063 } 2057 2064 ; 2058 2065 2059 2066 void Find_second_point_for_Tesselation(atom* a, atom* Candidate, atom* Parent, 2060 int RecursionLevel, Vector Oben, atom*& Opt_Candidate, double Storage[ 3],2067 int RecursionLevel, Vector Oben, atom*& Opt_Candidate, double Storage[2], 2061 2068 molecule* mol, double RADIUS) 2062 2069 { 2063 cout << Verbose( 1)2064 << " Looking for second point of starting triangle, recursive level "2065 << RecursionLevel << endl; ;2070 cout << Verbose(2) 2071 << "Begin of Find_second_point_for_Tesselation, recursive level " 2072 << RecursionLevel << endl; 2066 2073 int i; 2067 2074 Vector AngleCheck; 2068 2075 atom* Walker; 2069 double norm = -1. ;2076 double norm = -1., angle; 2070 2077 2071 2078 // check if we only have one unique point yet ... 2072 2079 if (a != Candidate) 2073 2080 { 2081 cout << Verbose(3) << "Current candidate is " << *Candidate << ": "; 2074 2082 AngleCheck.CopyVector(&(Candidate->x)); 2075 2083 AngleCheck.SubtractVector(&(a->x)); … … 2078 2086 if (norm < RADIUS) 2079 2087 { 2080 if (AngleCheck.Angle(&Oben) < Storage[0]) 2088 angle = AngleCheck.Angle(&Oben); 2089 if (angle < Storage[0]) 2081 2090 { 2082 //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[2]); 2083 cout << "Next better candidate is " << *Candidate 2084 << " with distance " << norm << ".\n"; 2091 //cout << Verbose(1) << "Old values of Storage: %lf %lf \n", Storage[0], Storage[1]); 2092 cout << "Is a better candidate with distance " << norm << " and " << angle << ".\n"; 2085 2093 Opt_Candidate = Candidate; 2086 2094 Storage[0] = AngleCheck.Angle(&Oben); 2087 //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[ 2]);2095 //cout << Verbose(1) << "Changing something in Storage: %lf %lf. \n", Storage[0], Storage[1]); 2088 2096 } 2089 2097 else 2090 2098 { 2091 cout << Verbose(1) << "Supposedly loosesto a better candidate "2099 cout << "Looses with angle " << angle << " to a better candidate " 2092 2100 << *Opt_Candidate << endl; 2093 2101 } … … 2095 2103 else 2096 2104 { 2097 cout << Verbose(1) << *Candidate << " refused due to Radius " << norm2105 cout << "Refused due to Radius " << norm 2098 2106 << endl; 2099 2107 } … … 2114 2122 }; 2115 2123 }; 2124 cout << Verbose(2) << "End of Find_second_point_for_Tesselation, recursive level " 2125 << RecursionLevel << endl; 2116 2126 } 2117 2127 ; … … 2119 2129 void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS) 2120 2130 { 2121 cout << Verbose(1) << " Looking for starting triangle\n";2131 cout << Verbose(1) << "Begin of Find_starting_triangle\n"; 2122 2132 int i = 0; 2123 2133 atom* Walker; 2124 2134 atom* FirstPoint; 2125 2135 atom* SecondPoint; 2126 atom* max_index[ 3];2127 double max_coordinate[ 3];2136 atom* max_index[NDIM]; 2137 double max_coordinate[NDIM]; 2128 2138 Vector Oben; 2129 2139 Vector helper; … … 2138 2148 max_coordinate[i] = -1; 2139 2149 } 2140 cout << Verbose( 1) << "Molecule mol is there and has " << mol->AtomCount2150 cout << Verbose(2) << "Molecule mol is there and has " << mol->AtomCount 2141 2151 << " Atoms \n"; 2142 2152 … … 2156 2166 } 2157 2167 2158 cout << Verbose(1) << "Found maximum coordinates. " << endl; 2168 cout << Verbose(2) << "Found maximum coordinates: "; 2169 for (int i=0;i<NDIM;i++) 2170 cout << i << ": " << *max_index[i] << "\t"; 2171 cout << endl; 2159 2172 //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0 2160 2173 const int k = 1; … … 2162 2175 FirstPoint = max_index[k]; 2163 2176 2164 cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << ": " 2165 << FirstPoint->x.x[0] << endl; 2166 double Storage[3]; 2177 cout << Verbose(1) << "Coordinates of start atom " << *FirstPoint << " at " << FirstPoint->x << " with " << mol->NumberOfBondsPerAtom[FirstPoint->nr] << " bonds." << endl; 2178 double Storage[2]; 2167 2179 atom* Opt_Candidate = NULL; 2168 2180 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. 2169 2181 Storage[1] = 999999.; // This will be an angle looking for the third point. 2170 Storage[2] = 999999.;2171 cout << Verbose(1) << "Number of Bonds: "2172 << mol->NumberOfBondsPerAtom[FirstPoint->nr] << endl;2173 2182 2174 2183 Find_second_point_for_Tesselation(FirstPoint, FirstPoint, FirstPoint, 0, 2175 2184 Oben, Opt_Candidate, Storage, mol, RADIUS); // we give same point as next candidate as its bonds are looked into in find_second_... 2176 2185 SecondPoint = Opt_Candidate; 2177 cout << Verbose(1) << "Found second point is " << *SecondPoint << " .\n";2186 cout << Verbose(1) << "Found second point is " << *SecondPoint << " at " << SecondPoint->x << ".\n"; 2178 2187 2179 2188 helper.CopyVector(&(FirstPoint->x)); … … 2185 2194 Storage[0] = -2.; // This will indicate the quadrant. 2186 2195 Storage[1] = 9999999.; // This will be an angle looking for the third point. 2187 Storage[2] = 9999999.;2188 2196 2189 2197 Chord.CopyVector(&(FirstPoint->x)); // bring into calling function … … 2191 2199 // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized) 2192 2200 2193 cout << Verbose(1) << "Looking for third point candidates \n"; 2194 cout << Verbose(1) << " In direction " << helper.x[0] << " " << helper.x[1] << " " << helper.x[2] << " " << endl; 2201 cout << Verbose(2) << "Looking for third point candidates \n"; 2195 2202 // look in one direction of baseline for initial candidate 2196 2203 Opt_Candidate = NULL; 2197 2204 CenterOfFirstLine.CopyVector(&Chord); 2198 CenterOfFirstLine.Scale( 0.5);2205 CenterOfFirstLine.Scale(-0.5); 2199 2206 CenterOfFirstLine.AddVector(&(SecondPoint->x)); 2200 2207 2201 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, SecondPoint, FirstPoint, 0, 2208 cout << Verbose(1) << "Looking for third point candidates from " << *FirstPoint << " onward ...\n"; 2209 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, 0, 2202 2210 &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol); 2203 2211 // look in other direction of baseline for possible better candidate 2204 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, SecondPoint, FirstPoint, SecondPoint, 0, 2212 cout << Verbose(1) << "Looking for third point candidates from " << *SecondPoint << " onward ...\n"; 2213 Find_next_suitable_point_via_Angle_of_Sphere(FirstPoint, SecondPoint, FirstPoint, SecondPoint, 0, 2205 2214 &Chord, &helper, &Oben, CenterOfFirstLine, Opt_Candidate, Storage, RADIUS, mol); 2206 2215 cout << Verbose(1) << "Third Point is " << *Opt_Candidate << endl; 2207 2216 2208 2217 // FOUND Starting Triangle: FirstPoint, SecondPoint, Opt_Candidate 2209 2210 cout << Verbose(1) << "The found starting triangle consists of "2211 << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate2212 << "." << endl;2213 2218 2214 2219 // Finally, we only have to add the found points … … 2226 2231 Oben.Scale(-1.); 2227 2232 BTS->GetNormalVector(Oben); 2233 cout << Verbose(0) << "==> The found starting triangle consists of " 2234 << *FirstPoint << ", " << *SecondPoint << " and " << *Opt_Candidate 2235 << " with normal vector " << BTS->NormalVector << ".\n"; 2236 cout << Verbose(1) << "End of Find_starting_triangle\n"; 2228 2237 } 2229 2238 ; … … 2237 2246 const double RADIUS = 6.; 2238 2247 LineMap::iterator baseline; 2248 cout << Verbose(0) << "Begin of Find_non_convex_border\n"; 2249 bool flag = false; // marks whether we went once through all baselines without finding any without two triangles 2250 2239 2251 Tess->Find_starting_triangle(mol, RADIUS); 2240 2252 2241 2253 baseline = Tess->LinesOnBoundary.begin(); 2242 while ( baseline != Tess->LinesOnBoundary.end())2254 while ((baseline != Tess->LinesOnBoundary.end()) || (!flag)) 2243 2255 { 2244 2256 if (baseline->second->TrianglesCount == 1) 2245 2257 { 2246 cout << Verbose(1) << "Begin of Tesselation ... " << endl;2247 2258 Tess->Find_next_suitable_triangle(out, tecplot, mol, 2248 2259 *(baseline->second), 2249 2260 *(((baseline->second->triangles.begin()))->second), RADIUS, N); //the line is there, so there is a triangle, but only one. 2250 cout << Verbose(1) << "End of Tesselation ... " << endl;2261 flag = true; 2251 2262 } 2252 2263 else 2253 2264 { 2254 cout << Verbose(1) << " There is a line with"2265 cout << Verbose(1) << "Line " << &baseline << " has " 2255 2266 << baseline->second->TrianglesCount << " triangles adjacent" 2256 2267 << endl; … … 2258 2269 N++; 2259 2270 baseline++; 2260 } 2271 if ((baseline == Tess->LinesOnBoundary.end()) && (flag)) { 2272 baseline = Tess->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines 2273 flag = false; 2274 } 2275 } 2276 cout << Verbose(1) << "Writing final tecplot file\n"; 2261 2277 write_tecplot_file(out, tecplot, Tess, mol, -1); 2262 2278 2263 } 2264 ; 2279 cout << Verbose(0) << "End of Find_non_convex_border\n"; 2280 } 2281 ;
Note:
See TracChangeset
for help on using the changeset viewer.