Ignore:
Timestamp:
Dec 3, 2008, 2:12:05 PM (17 years ago)
Author:
Christian Neuen <neuen@…>
Children:
3e20fe
Parents:
f5b58e
Message:

Multiple changes to boundary, currently not fully operational.
Molecules has a new routine to create adjacency lists, reading bonds from a dbond file instead of looking for the distances by itself.
Vector function Project onto plane has been updated.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • molecuilder/src/boundary.cpp

    rf5b58e re0c5b1  
    33
    44
    5 // =================spaeter gebrauchte
    6 void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, double *Storage, const double RADIUS, molecule mol);
    7 void Find_non_convex_border(Tesselation Tess, molecule mol);
    85
    96
     
    2926};
    3027
    31 void BoundaryPointSet::AddLine(class BoundaryLineSet *line) 
     28void BoundaryPointSet::AddLine(class BoundaryLineSet *line)
    3229{
    3330  cout << Verbose(6) << "Adding line " << *line << " to " << *this << "." << endl;
     
    4037};
    4138
    42 ostream & operator << (ostream &ost, BoundaryPointSet &a) 
     39ostream & operator << (ostream &ost, BoundaryPointSet &a)
    4340{
    4441  ost << "[" << a.Nr << "|" << a.node->Name << "]";
     
    7370{
    7471  for (int i=0;i<2;i++) {
    75     cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl; 
     72    cout << Verbose(5) << "Erasing Line Nr. " << Nr << " in boundary point " << *endpoints[i] << "." << endl;
    7673    endpoints[i]->lines.erase(Nr);
    7774    LineMap::iterator tester = endpoints[i]->lines.begin();
     
    8582};
    8683
    87 void BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle) 
     84void BoundaryLineSet::AddTriangle(class BoundaryTriangleSet *triangle)
    8885{
    8986  cout << Verbose(6) << "Add " << triangle->Nr << " to line " << *this << "." << endl;
     
    9289};
    9390
    94 ostream & operator << (ostream &ost, BoundaryLineSet &a) 
     91ostream & operator << (ostream &ost, BoundaryLineSet &a)
    9592{
    9693  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "]";
     
    125122    for (int j=0;j<2;j++) { // for both endpoints
    126123      OrderMap.insert ( pair <int, class BoundaryPointSet * >( line[i]->endpoints[j]->Nr, line[i]->endpoints[j]) );
    127       // and we don't care whether insertion fails 
     124      // and we don't care whether insertion fails
    128125    }
    129126  // set endpoints
     
    161158  // get normal vector
    162159  NormalVector.MakeNormalVector(&endpoints[0]->node->x, &endpoints[1]->node->x, &endpoints[2]->node->x);
    163  
     160
    164161  // make it always point inward (any offset vector onto plane projected onto normal vector suffices)
    165162  if (endpoints[0]->node->x.Projection(&NormalVector) > 0)
     
    167164};
    168165
    169 ostream & operator << (ostream &ost, BoundaryTriangleSet &a) 
     166ostream & operator << (ostream &ost, BoundaryTriangleSet &a)
    170167{
    171168  ost << "[" << a.Nr << "|" << a.endpoints[0]->node->Name << "," << a.endpoints[1]->node->Name << "," << a.endpoints[2]->node->Name << "]";
     
    213210  LineMap LinesOnBoundary;
    214211  TriangleMap TrianglesOnBoundary;
    215  
     212
    216213  *out << Verbose(1) << "Finding all boundary points." << endl;
    217214  Boundaries *BoundaryPoints = new Boundaries [NDIM];  // first is alpha, second is (r, nr)
     
    250247      else
    251248        angle = 0.;  // otherwise it's a vector in Axis Direction and unimportant for boundary issues
    252        
     249
    253250      //*out << "Checking sign in quadrant : " << ProjectedVector.Projection(&AngleReferenceNormalVector) << "." << endl;
    254251      if (ProjectedVector.Projection(&AngleReferenceNormalVector) > 0) {
     
    268265        Walker->x.Output(out);
    269266        *out << endl;
    270         double tmp = ProjectedVector.Norm(); 
     267        double tmp = ProjectedVector.Norm();
    271268        if (tmp > BoundaryTestPair.first->second.first) {
    272269          BoundaryTestPair.first->second.first = tmp;
    273           BoundaryTestPair.first->second.second = Walker; 
     270          BoundaryTestPair.first->second.second = Walker;
    274271          *out << Verbose(2) << "Keeping new vector." << endl;
    275272        } else if (tmp == BoundaryTestPair.first->second.first) {
     
    319316        }
    320317        // check distance
    321        
     318
    322319        // construct the vector of each side of the triangle on the projected plane (defined by normal vector AxisVector)
    323320        {
     
    328325  //          SideA.Output(out);
    329326  //          *out << endl;
    330          
     327
    331328          SideB.CopyVector(&right->second.second->x);
    332329          SideB.ProjectOntoPlane(&AxisVector);
     
    334331  //          SideB.Output(out);
    335332  //          *out << endl;
    336          
     333
    337334          SideC.CopyVector(&left->second.second->x);
    338335          SideC.SubtractVector(&right->second.second->x);
     
    341338  //          SideC.Output(out);
    342339  //          *out << endl;
    343  
     340
    344341          SideH.CopyVector(&runner->second.second->x);
    345342          SideH.ProjectOntoPlane(&AxisVector);
     
    347344  //          SideH.Output(out);
    348345  //          *out << endl;
    349          
     346
    350347          // calculate each length
    351348          double a = SideA.Norm();
     
    355352          // calculate the angles
    356353          double alpha = SideA.Angle(&SideH);
    357           double beta = SideA.Angle(&SideC); 
     354          double beta = SideA.Angle(&SideC);
    358355          double gamma = SideB.Angle(&SideH);
    359356          double delta = SideC.Angle(&SideH);
    360357          double MinDistance = a * sin(beta)/(sin(delta)) * (((alpha < M_PI/2.) || (gamma < M_PI/2.)) ? 1. : -1.);
    361   //          *out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl; 
     358  //          *out << Verbose(2) << " I calculated: a = " << a << ", h = " << h << ", beta(" << left->second.second->Name << "," << left->second.second->Name << "-" << right->second.second->Name << ") = " << beta << ", delta(" << left->second.second->Name << "," << runner->second.second->Name << ") = " << delta << ", Min = " << MinDistance << "." << endl;
    362359          //*out << Verbose(1) << "Checking CoG distance of runner " << *runner->second.second << " " << h << " against triangle's side length spanned by (" << *left->second.second << "," << *right->second.second << ") of " << MinDistance << "." << endl;
    363360          if ((fabs(h/fabs(h) - MinDistance/fabs(MinDistance)) < MYEPSILON) && (h <  MinDistance)) {
     
    370367      }
    371368    } while (flag);
    372   } 
     369  }
    373370  return BoundaryPoints;
    374371};
     
    381378 * \param IsAngstroem whether we have angstroem or atomic units
    382379 * \return NDIM array of the diameters
    383  */ 
     380 */
    384381double * GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem)
    385382{
     
    393390    *out << Verbose(1) << "Using given boundary points set." << endl;
    394391  }
    395  
     392
    396393  // determine biggest "diameter" of cluster for each axis
    397394  Boundaries::iterator Neighbour, OtherNeighbour;
     
    418415        DistanceVector.SubtractVector(&Neighbour->second.second->x);
    419416        do {  // seek for neighbour pair where it flips
    420           OldComponent = DistanceVector.x[Othercomponent]; 
     417          OldComponent = DistanceVector.x[Othercomponent];
    421418          Neighbour++;
    422419          if (Neighbour == BoundaryPoints[axis].end())  // make it wrap around
     
    431428            OtherNeighbour = BoundaryPoints[axis].end();
    432429          OtherNeighbour--;
    433           //*out << Verbose(2) << "The pair, where the sign of OtherComponent flips, is: " << *(Neighbour->second.second) << " and " << *(OtherNeighbour->second.second) << "." << endl; 
     430          //*out << Verbose(2) << "The pair, where the sign of OtherComponent flips, is: " << *(Neighbour->second.second) << " and " << *(OtherNeighbour->second.second) << "." << endl;
    434431          // now we have found the pair: Neighbour and OtherNeighbour
    435432          OtherVector.CopyVector(&runner->second.second->x);
     
    466463 * \param *BoundaryPoints NDIM set of boundary points on the projected plane per axis, on return if desired
    467464 * \param *mol molecule structure representing the cluster
    468  * \return determined volume of the cluster in cubed config:GetIsAngstroem() 
     465 * \return determined volume of the cluster in cubed config:GetIsAngstroem()
    469466 */
    470 double VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration, Boundaries *BoundaryPtr, molecule *mol) 
     467double VolumeOfConvexEnvelope(ofstream *out, ofstream *tecplot, config *configuration, Boundaries *BoundaryPtr, molecule *mol)
    471468{
    472469  bool IsAngstroem = configuration->GetIsAngstroem();
     
    477474  double volume = 0.;
    478475  double PyramidVolume = 0.;
    479   double G,h; 
     476  double G,h;
    480477  Vector x,y;
    481478  double a,b,c;
    482479
    483   Find_non_convex_border(*TesselStruct, *mol);
     480  Find_non_convex_border(*TesselStruct, mol);
    484481  /*
    485482  // 1. calculate center of gravity
    486483  *out << endl;
    487484  Vector *CenterOfGravity = mol->DetermineCenterOfGravity(out);
    488  
     485
    489486  // 2. translate all points into CoG
    490487  *out << Verbose(1) << "Translating system to Center of Gravity." << endl;
     
    494491    Walker->x.Translate(CenterOfGravity);
    495492  }
    496  
     493
    497494  // 3. Find all points on the boundary
    498495  if (BoundaryPoints == NULL) {
     
    502499    *out << Verbose(1) << "Using given boundary points set." << endl;
    503500  }
    504  
     501
    505502  // 4. fill the boundary point list
    506503  for (int axis=0;axis<NDIM;axis++)
     
    518515//  }
    519516//  *out << endl;
    520  
     517
    521518  // 5a. guess starting triangle
    522519  TesselStruct->GuessStartingTriangle(out);
    523  
     520
    524521  // 5b. go through all lines, that are not yet part of two triangles (only of one so far)
    525522  TesselStruct->TesselateOnBoundary(out, configuration, mol);
     
    545542    PyramidVolume = (1./3.) * G * h;    // this formula holds for _all_ pyramids (independent of n-edge base or (not) centered peak)
    546543    *out << Verbose(2) << "Area of triangle is " << G << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^2, height is " << h << " and the volume is " << PyramidVolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    547     volume += PyramidVolume; 
     544    volume += PyramidVolume;
    548545  }
    549546  *out << Verbose(0) << "RESULT: The summed volume is " << setprecision(10) << volume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     
    572569    for (int i=0;i<mol->AtomCount;i++)
    573570      LookupList[i] = -1;
    574    
     571
    575572    // print atom coordinates
    576573    *out << Verbose(2) << "The following triangles were created:";
     
    586583    for (TriangleMap::iterator runner =  TesselStruct->TrianglesOnBoundary.begin(); runner !=  TesselStruct->TrianglesOnBoundary.end(); runner++) {
    587584      *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name;
    588       *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl; 
     585      *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl;
    589586    }
    590587    delete[](LookupList);
     
    595592  if (BoundaryFreeFlag)
    596593    delete[](BoundaryPoints);
    597  
     594
    598595  return volume;
    599596};
     
    612609  // transform to PAS
    613610  mol->PrincipalAxisSystem(out, true);
    614  
     611
    615612  // some preparations beforehand
    616613  bool IsAngstroem = configuration->GetIsAngstroem();
     
    619616  if (ClusterVolume == 0)
    620617    clustervolume = VolumeOfConvexEnvelope(out, NULL, configuration, BoundaryPoints, mol);
    621   else 
     618  else
    622619    clustervolume = ClusterVolume;
    623620  double *GreatestDiameter = GetDiametersOfCluster(out, BoundaryPoints, mol, IsAngstroem);
     
    636633  }
    637634  *out << Verbose(0) << "RESULT: The summed mass is " << setprecision(10) << totalmass << " atomicmassunit." << endl;
    638  
     635
    639636  *out << Verbose(0) << "RESULT: The average density is " << setprecision(10) << totalmass/clustervolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    640  
     637
    641638  // solve cubic polynomial
    642639  *out << Verbose(1) << "Solving equidistant suspension in water problem ..." << endl;
     
    647644    cellvolume = (TotalNoClusters*totalmass/SOLVENTDENSITY_a0 - (totalmass/clustervolume))/(celldensity-1);
    648645  *out << Verbose(1) << "Cellvolume needed for a density of " << celldensity << " g/cm^3 is " << cellvolume << " " << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
    649  
     646
    650647  double minimumvolume = TotalNoClusters*(GreatestDiameter[0]*GreatestDiameter[1]*GreatestDiameter[2]);
    651648  *out << Verbose(1) << "Minimum volume of the convex envelope contained in a rectangular box is " << minimumvolume << " atomicmassunit/" << (IsAngstroem ? "angstrom" : "atomiclength") << "^3." << endl;
     
    658655  } else {
    659656    BoxLengths.x[0] = (repetition[0]*GreatestDiameter[0] + repetition[1]*GreatestDiameter[1] + repetition[2]*GreatestDiameter[2]);
    660     BoxLengths.x[1] = (repetition[0]*repetition[1]*GreatestDiameter[0]*GreatestDiameter[1] 
    661               + repetition[0]*repetition[2]*GreatestDiameter[0]*GreatestDiameter[2] 
     657    BoxLengths.x[1] = (repetition[0]*repetition[1]*GreatestDiameter[0]*GreatestDiameter[1]
     658              + repetition[0]*repetition[2]*GreatestDiameter[0]*GreatestDiameter[2]
    662659              + repetition[1]*repetition[2]*GreatestDiameter[1]*GreatestDiameter[2]);
    663660    BoxLengths.x[2] = minimumvolume - cellvolume;
     
    669666      x0 = x2;  // sorted in ascending order
    670667    }
    671  
     668
    672669    cellvolume = 1;
    673670    for(int i=0;i<NDIM;i++) {
     
    675672      cellvolume *= BoxLengths.x[i];
    676673    }
    677  
     674
    678675    // set new box dimensions
    679676    *out << Verbose(0) << "Translating to box with these boundaries." << endl;
     
    692689Tesselation::Tesselation()
    693690{
    694   PointsOnBoundaryCount = 0; 
    695   LinesOnBoundaryCount = 0; 
     691  PointsOnBoundaryCount = 0;
     692  LinesOnBoundaryCount = 0;
    696693  TrianglesOnBoundaryCount = 0;
    697694};
     
    711708 * \param *out output stream for debugging
    712709 * \param PointsOnBoundary set of boundary points defining the convex envelope of the cluster
    713  */ 
     710 */
    714711void Tesselation::GuessStartingTriangle(ofstream *out)
    715712{
     
    722719  A = PointsOnBoundary.begin(); // the first may be chosen arbitrarily
    723720
    724   // with A chosen, take each pair B,C and sort 
     721  // with A chosen, take each pair B,C and sort
    725722  if (A != PointsOnBoundary.end()) {
    726723    B = A;
     
    746743//    }
    747744//    *out << endl;
    748  
     745
    749746  // 4b2. pick three baselines forming a triangle
    750747  // 1. we take from the smallest sum of squared distance as the base line BC (with peak A) onward as the triangle candidate
     
    758755    PlaneVector.Output(out);
    759756    *out << endl;
    760     // 4. loop over all points 
     757    // 4. loop over all points
    761758    double sign = 0.;
    762759    PointMap::iterator checker = PointsOnBoundary.begin();
     
    785782      tmp = checker->second->node->x.Distance(&A->second->node->x);
    786783      int innerpoint = 0;
    787       if ((tmp < A->second->node->x.Distance(&baseline->second.first->second->node->x)) 
     784      if ((tmp < A->second->node->x.Distance(&baseline->second.first->second->node->x))
    788785          && (tmp < A->second->node->x.Distance(&baseline->second.second->second->node->x)))
    789786        innerpoint++;
    790787      tmp = checker->second->node->x.Distance(&baseline->second.first->second->node->x);
    791       if ((tmp < baseline->second.first->second->node->x.Distance(&A->second->node->x)) 
     788      if ((tmp < baseline->second.first->second->node->x.Distance(&A->second->node->x))
    792789          && (tmp < baseline->second.first->second->node->x.Distance(&baseline->second.second->second->node->x)))
    793790        innerpoint++;
    794791      tmp = checker->second->node->x.Distance(&baseline->second.second->second->node->x);
    795       if ((tmp < baseline->second.second->second->node->x.Distance(&baseline->second.first->second->node->x)) 
     792      if ((tmp < baseline->second.second->second->node->x.Distance(&baseline->second.first->second->node->x))
    796793          && (tmp < baseline->second.second->second->node->x.Distance(&A->second->node->x)))
    797794        innerpoint++;
     
    815812    BPS[0] = baseline->second.first->second;
    816813    BPS[1] = A->second;
    817     BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 
    818    
     814    BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
     815
    819816    // 4b3. insert created triangle
    820817    BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     
    825822      LinesOnBoundaryCount++;
    826823    }
    827  
     824
    828825    *out << Verbose(1) << "Starting triangle is " << *BTS << "." << endl;
    829826  } else {
     
    857854  do {
    858855    flag = false;
    859     for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline++) 
     856    for (LineMap::iterator baseline = LinesOnBoundary.begin(); baseline != LinesOnBoundary.end(); baseline++)
    860857      if (baseline->second->TrianglesCount == 1) {
    861         *out << Verbose(2) << "Current baseline is between " << *(baseline->second) << "." << endl; 
     858        *out << Verbose(2) << "Current baseline is between " << *(baseline->second) << "." << endl;
    862859        // 5a. go through each boundary point if not _both_ edges between either endpoint of the current line and this point exist (and belong to 2 triangles)
    863860        SmallestAngle = M_PI;
     
    888885        TempVector.CopyVector(&CenterVector);
    889886        TempVector.SubtractVector(&baseline->second->endpoints[0]->node->x);  // TempVector is vector on triangle plane pointing from one baseline egde towards center!
    890         //*out << Verbose(2) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl; 
     887        //*out << Verbose(2) << "Projection of propagation onto temp: " << PropagationVector.Projection(&TempVector) << "." << endl;
    891888        if (PropagationVector.Projection(&TempVector) > 0)  // make sure normal propagation vector points outward from baseline
    892889          PropagationVector.Scale(-1.);
     
    895892        *out << endl;
    896893        winner = PointsOnBoundary.end();
    897         for (PointMap::iterator target = PointsOnBoundary.begin(); target != PointsOnBoundary.end(); target++) 
     894        for (PointMap::iterator target = PointsOnBoundary.begin(); target != PointsOnBoundary.end(); target++)
    898895          if ((target->second != baseline->second->endpoints[0]) && (target->second != baseline->second->endpoints[1])) { // don't take the same endpoints
    899896            *out << Verbose(3) << "Target point is " << *(target->second) << ":";
    900897            bool continueflag = true;
    901            
     898
    902899            VirtualNormalVector.CopyVector(&baseline->second->endpoints[0]->node->x);
    903900            VirtualNormalVector.AddVector(&baseline->second->endpoints[0]->node->x);
     
    935932            // check whether the envisaged triangle does not already exist (if both lines exist and have same endpoint)
    936933            continueflag = continueflag && (!(
    937                 ((LineChecker[0] != baseline->second->endpoints[0]->lines.end()) && (LineChecker[1] != baseline->second->endpoints[1]->lines.end()) 
     934                ((LineChecker[0] != baseline->second->endpoints[0]->lines.end()) && (LineChecker[1] != baseline->second->endpoints[1]->lines.end())
    938935                && (GetCommonEndpoint(LineChecker[0]->second, LineChecker[1]->second) == peak))
    939936               ));
     
    990987          *out << Verbose(1) << "I could not determine a winner for this baseline " << *(baseline->second) << "." << endl;
    991988        }
    992  
     989
    993990        // 5d. If the set of lines is not yet empty, go to 5. and continue
    994991      } else
    995992        *out << Verbose(2) << "Baseline candidate " << *(baseline->second) << " has a triangle count of " << baseline->second->TrianglesCount << "." << endl;
    996993  } while (flag);
    997  
     994
    998995};
    999996
     
    10211018//====================================================================================================================
    10221019
    1023 
    1024 void Find_next_suitable_point(atom a, atom b, atom Candidate, int n, Vector *d1, Vector *d2, double *Storage, const double RADIUS, molecule mol)
    1025 {
    1026   /* d2 ist der Normalenvektor auf dem Dreieck,
    1027    * d1 ist der Vektor, der normal auf der Kante und d2 steht.
     1020/*!
     1021 * This recursive function finds a third point, to form a triangle with two given ones.
     1022 * Two atoms are fixed, a candidate is supplied, additionally two vectors for direction distinction, a Storage area to \
     1023 *  supply results to the calling function, the radius of the sphere which the triangle shall support and the molecule \
     1024 *  upon which we operate.
     1025 *  If the candidate is more fitting to support the sphere than the already stored atom is, then we write its id, its general \
     1026 *  direction and angle into Storage.
     1027 *  We the determine the recursive level we have reached and if this is not on the threshold yet, call this function again, \
     1028 *  with all neighbours of the candidate.
     1029 */
     1030void Find_next_suitable_point(atom* a, atom* b, atom* Candidate, int n, Vector *Chord, Vector *d1, Vector *d2, double *Storage, const double RADIUS, molecule* mol)
     1031{
     1032  /* d2 is normal vector on the triangle
     1033   * d1 is normal on the triangle line, from which we come, as well as on d2.
    10281034   */
    1029   Vector dif_a;
    1030   Vector dif_b;
    1031   Vector Chord;
    1032   Vector AngleCheck;
    1033   atom *Walker;
    1034 
    1035   dif_a.CopyVector(&a.x);
    1036   dif_a.SubtractVector(&Candidate.x);
    1037   dif_b.CopyVector(&b.x);
    1038   dif_b.SubtractVector(&Candidate.x);
    1039   Chord.CopyVector(&a.x);
    1040   Chord.SubtractVector(&b.x);
     1035  Vector dif_a; //Vector from a to candidate
     1036  Vector dif_b; //Vector from b to candidate
     1037  Vector AngleCheck; // Projection of a difference vector on plane orthogonal on triangle side.
     1038  atom *Walker; // variable atom point
     1039
     1040  dif_a.CopyVector(&(a->x));
     1041  dif_a.SubtractVector(&(Candidate->x));
     1042  dif_b.CopyVector(&(b->x));
     1043  dif_b.SubtractVector(&(Candidate->x));
    10411044  AngleCheck.CopyVector(&dif_a);
    1042   AngleCheck.ProjectOntoPlane(&Chord);
    1043 
    1044   //Storage eintrag fuer aktuelles Atom
    1045   if (Chord.Norm()/(2*sin(dif_a.Angle(&dif_b)))<RADIUS) //Using Formula for relation of chord length with inner angle to find of Ball will touch atom
     1045  AngleCheck.ProjectOntoPlane(Chord);
     1046
     1047  if (Chord->Norm()/(2*sin(dif_a.Angle(&dif_b)))<RADIUS) //Using Formula for relation of chord length with inner angle to find of Ball will touch atom
    10461048  {
    10471049
    10481050    if (dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1))>Storage[1]) //This will give absolute preference to those in "right-hand" quadrants
    10491051      {
    1050         Storage[0]=(double)Candidate.nr;
    1051         Storage[1]=1;
    1052         Storage[2]=AngleCheck.Angle(d2);
     1052        Storage[0]=(double)Candidate->nr;
     1053        Storage[1]=dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1));
     1054        Storage[2]=AngleCheck.Angle(d2);
    10531055      }
    10541056    else
     
    10581060          //Depending on quadrant we prefer higher or lower atom with respect to Triangle normal first.
    10591061          {
    1060             Storage[0]=(double)Candidate.nr;
     1062            Storage[0]=(double)Candidate->nr;
    10611063            Storage[1]=dif_a.ScalarProduct(d1)/fabs(dif_a.ScalarProduct(d1));
    10621064            Storage[2]=AngleCheck.Angle(d2);
     
    10651067  }
    10661068
    1067   if (n<5)
    1068     {
    1069       for(int i=0; i<mol.NumberOfBondsPerAtom[Candidate.nr];i++)
     1069  if (n<5) // Five is the recursion level threshold.
     1070    {
     1071      for(int i=0; i<mol->NumberOfBondsPerAtom[Candidate->nr];i++) // go through all bond
    10701072        {
    1071           while (Candidate.nr != (mol.ListOfBondsPerAtom[Candidate.nr][i]->leftatom->nr ==Candidate.nr ? mol.ListOfBondsPerAtom[Candidate.nr][i]->leftatom->nr : mol.ListOfBondsPerAtom[Candidate.nr][i]->rightatom->nr))
    1072             {
     1073                Walker= mol->start; // go through all atoms
     1074
     1075          while (Walker->nr != (mol->ListOfBondsPerAtom[Candidate->nr][i]->leftatom->nr ==Candidate->nr ? mol->ListOfBondsPerAtom[Candidate->nr][i]->rightatom->nr : mol->ListOfBondsPerAtom[Candidate->nr][i]->leftatom->nr))
     1076            { // until atom found which belongs to bond
    10731077              Walker = Walker->next;
    10741078            }
    10751079
    1076           Find_next_suitable_point(a, b, *Walker, n+1, d1, d2, Storage, RADIUS, mol);
     1080
     1081          Find_next_suitable_point(a, b, Walker, n+1, Chord, d1, d2, Storage, RADIUS, mol);  //call function again
    10771082        }
    10781083    }
    10791084};
    10801085
    1081 
    1082 void Tesselation::Find_next_suitable_triangle(molecule *mol, BoundaryLineSet Line, BoundaryTriangleSet T, const double& RADIUS)
    1083 {
    1084   Vector CenterOfLine = Line.endpoints[0]->node->x;
     1086/*!
     1087 * this function fins a triangle to a line, adjacent to an existing one.
     1088 */
     1089void Tesselation::Find_next_suitable_triangle(molecule* mol, BoundaryLineSet Line, BoundaryTriangleSet T, const double& RADIUS)
     1090{
     1091        printf("Looking for next suitable triangle \n");
    10851092  Vector direction1;
    1086   Vector direction2;
    10871093  Vector helper;
     1094  Vector Chord;
    10881095  atom* Walker;
    10891096
    1090   double Storage[3];
     1097  double *Storage;
     1098  Storage = new double[3];
    10911099  Storage[0]=-1.;   // Id must be positive, we see should nothing be done
    10921100  Storage[1]=-1.;   // This direction is either +1 or -1 one, so any result will take precedence over initial values
    10931101  Storage[2]=-10.;  // This is also lower then any value produced by an eligible atom, which are all positive
    10941102
    1095  
     1103
    10961104  helper.CopyVector(&(Line.endpoints[0]->node->x));
    10971105  for (int i =0; i<3; i++)
     
    11141122    }
    11151123
    1116   Find_next_suitable_point(*Line.endpoints[0]->node, *Line.endpoints[1]->node, *Line.endpoints[0]->node, 0, &direction1, T.NormalVector, Storage, RADIUS, *mol);
    1117  
     1124  Chord.CopyVector(&(Line.endpoints[0]->node->x)); // bring into calling function
     1125  Chord.SubtractVector(&(Line.endpoints[1]->node->x));
     1126
     1127printf("Looking for third point candidates for triangle \n");
     1128  Find_next_suitable_point(Line.endpoints[0]->node, Line.endpoints[1]->node, Line.endpoints[0]->node, 0, &Chord, &direction1, T.NormalVector, Storage, RADIUS, mol);
     1129
    11181130  // Konstruiere nun neues Dreieck am Ende der Liste der Dreiecke
    11191131  // Next Triangle is Line, atom with number in Storage[0]
     
    11411153  for(int i=0;i<NDIM;i++) // sind Linien bereits vorhanden ???
    11421154    {
    1143       if (LinesOnBoundary.find(BTS->lines[i]) == LinesOnBoundary.end)
     1155
     1156
     1157  if ( (LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]))).second);
    11441158        {
    1145           LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
    1146           LinesOnBoundaryCount++;
     1159                LinesOnBoundaryCount++;
    11471160        }
    11481161    }
     
    11541167      BTS->NormalVector->Scale(-1);
    11551168    }
    1156  
    1157 };
    1158 
    1159 
    1160 void Find_second_point_for_Tesselation(atom a, atom Candidate, int n, Vector Oben, double* Storage, molecule mol)
    1161 {
     1169
     1170};
     1171
     1172
     1173void Find_second_point_for_Tesselation(atom* a, atom* Candidate, int n, Vector Oben, double Storage[3], molecule* mol)
     1174{
     1175        printf("Looking for second point of starting triangle \n");
    11621176  int i;
    11631177  Vector *AngleCheck;
    11641178  atom* Walker;
    11651179
    1166   AngleCheck->CopyVector(&Candidate.x);
    1167   AngleCheck->SubtractVector(&a.x);
    1168   if (AngleCheck->ScalarProduct(&Oben) < Storage[1])
    1169     {
    1170       Storage[0]=(double)(Candidate.nr);
    1171       Storage[1]=AngleCheck->ScalarProduct(&Oben);
     1180  AngleCheck->CopyVector(&(Candidate->x));
     1181  AngleCheck->SubtractVector(&(a->x));
     1182  if (AngleCheck->Angle(&Oben) < Storage[1])
     1183    {
     1184          //printf("Old values of Storage: %lf %lf \n", Storage[0], Storage[1]);
     1185      Storage[0]=(double)(Candidate->nr);
     1186      Storage[1]=AngleCheck->Angle(&Oben);
     1187      //printf("Changing something in Storage: %lf %lf. \n", Storage[0], Storage[1]);
    11721188    };
    1173 
     1189  printf("%d \n", n);
    11741190  if (n<5)
    11751191    {
    1176       for (i = 0; i< mol.NumberOfBondsPerAtom[Candidate.nr]; i++)
     1192      for (i = 0; i< mol->NumberOfBondsPerAtom[Candidate->nr]; i++)
    11771193        {
    1178           Walker = mol.start;
    1179           while (Candidate.nr != (mol.ListOfBondsPerAtom[Candidate.nr][i]->leftatom->nr ==Candidate.nr ? mol.ListOfBondsPerAtom[Candidate.nr][i]->leftatom->nr : mol.ListOfBondsPerAtom[Candidate.nr][i]->rightatom->nr))
     1194          Walker = mol->start;
     1195          while (Candidate->nr != (mol->ListOfBondsPerAtom[Candidate->nr][i]->leftatom->nr ==Candidate->nr ? mol->ListOfBondsPerAtom[Candidate->nr][i]->leftatom->nr : mol->ListOfBondsPerAtom[Candidate->nr][i]->rightatom->nr))
    11801196            {
    11811197              Walker = Walker->next;
    11821198            };
    1183          
    1184           Find_second_point_for_Tesselation(a, *Walker, n+1, Oben, Storage, mol);
     1199
     1200          Find_second_point_for_Tesselation(a, Walker, n+1, Oben, Storage, mol);
    11851201            };
    11861202    };
    1187  
    1188 
    1189 };
    1190 
    1191 
    1192 void Tesselation::Find_starting_triangle(molecule mol, const double RADIUS)
    1193 {
     1203
     1204
     1205};
     1206
     1207
     1208void Tesselation::Find_starting_triangle(molecule* mol, const double RADIUS)
     1209{
     1210        printf("Looking for starting triangle \n");
    11941211  int i=0;
    1195   atom Walker;
    1196   atom Walker2;
    1197   atom Walker3;
     1212  atom* Walker;
     1213  atom* Walker2;
     1214  atom* Walker3;
    11981215  int max_index[3];
    11991216  double max_coordinate[3];
    12001217  Vector Oben;
    12011218  Vector helper;
     1219  Vector Chord;
    12021220
    12031221  Oben.Zero();
     
    12091227      max_coordinate[i] =-1;
    12101228    }
    1211 
    1212   Walker = *mol.start;
    1213   while (Walker.next != NULL)
    1214     {
     1229printf("Molecule mol is there and has %d Atoms \n", mol->AtomCount);
     1230  Walker = mol->start;
     1231  while (Walker->next != mol->end)
     1232    {
     1233        Walker = Walker->next;
    12151234      for (i=0; i<3; i++)
    1216         {
    1217           if (Walker.x.x[i]>max_coordinate[i])
     1235      {
     1236          if (Walker->x.x[i] > max_coordinate[i])
    12181237            {
    1219               max_coordinate[i]=Walker.x.x[i];
    1220               max_index[i]=Walker.nr;
     1238              max_coordinate[i]=Walker->x.x[i];
     1239              max_index[i]=Walker->nr;
    12211240            }
    1222         }
    1223     }
    1224 
     1241      }
     1242    }
     1243
     1244printf("Found starting atom \n");
    12251245  //Koennen dies fuer alle Richtungen, legen hier erstmal Richtung auf k=0
    1226   const int k=0;
    1227 
    1228   Oben.x[k]=1;
    1229   Walker = *mol.start;
    1230   while (Walker.nr != max_index[k])
    1231     {
    1232       Walker = *Walker.next;
    1233     }
    1234 
     1246  const int k=2;
     1247
     1248  Oben.x[k]=1.;
     1249  Walker = mol->start;
     1250  Walker = Walker->next;
     1251  while (Walker->nr != max_index[k])
     1252    {
     1253      Walker = Walker->next;
     1254    }
     1255printf("%d \n", Walker->nr);
    12351256  double Storage[3];
    12361257  Storage[0]=-1.;   // Id must be positive, we see should nothing be done
    1237   Storage[1]=-2.;   // 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.
    1238   Storage[2]=-10.;  // This will be an angle looking for the third point.
    1239 
    1240 
    1241   for (i=0; i< mol.NumberOfBondsPerAtom[Walker.nr]; i++)
    1242     {
    1243       Walker2 = *mol.start;
    1244       while (Walker2.nr != (mol.ListOfBondsPerAtom[Walker.nr][i]->leftatom->nr == Walker.nr ? mol.ListOfBondsPerAtom[Walker.nr][i]->rightatom->nr : mol.ListOfBondsPerAtom[Walker.nr][i]->leftatom->nr) )
     1258  Storage[1]=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.
     1259  Storage[2]=999999.;  // This will be an angle looking for the third point.
     1260printf("%d \n", mol->NumberOfBondsPerAtom[Walker->nr]);
     1261
     1262  for (i=1; i< (mol->NumberOfBondsPerAtom[Walker->nr]); i++)
     1263    {
     1264      Walker2 = mol->start;
     1265      Walker2 = Walker2->next;
     1266      while (Walker2->nr != (mol->ListOfBondsPerAtom[Walker->nr][i]->leftatom->nr == Walker->nr ? mol->ListOfBondsPerAtom[Walker->nr][i]->rightatom->nr : mol->ListOfBondsPerAtom[Walker->nr][i]->leftatom->nr) )
    12451267        {
    1246           Walker2 = *Walker2.next;
     1268          Walker2 = Walker2->next;
    12471269        }
    12481270
     
    12501272    }
    12511273
    1252   Walker2 = *mol.start;
    1253 
    1254   while (Walker2.nr != int(Storage[0]))
    1255     {
    1256       Walker = *Walker.next;
    1257     }
    1258  
    1259   helper.CopyVector(&Walker.x);
    1260   helper.SubtractVector(&Walker2.x);
     1274  Walker2 = mol->start;
     1275
     1276  while (Walker2->nr != int(Storage[0]))
     1277    {
     1278      Walker2 = Walker2->next;
     1279    }
     1280
     1281  helper.CopyVector(&(Walker->x));
     1282  helper.SubtractVector(&(Walker2->x));
    12611283  Oben.ProjectOntoPlane(&helper);
    12621284  helper.VectorProduct(&Oben);
    1263 
    1264        Find_next_suitable_point(Walker, Walker2, *(mol.ListOfBondsPerAtom[Walker.nr][i]->leftatom->nr == Walker.nr ? mol.ListOfBondsPerAtom[Walker.nr][i]->rightatom : mol.ListOfBondsPerAtom[Walker.nr][i]->leftatom), 0, &helper, &Oben, Storage, RADIUS, mol);
    1265   Walker3 = *mol.start;
    1266   while (Walker3.nr != int(Storage[0]))
    1267     {
    1268       Walker3 = *Walker3.next;
     1285  Storage[0]=-1.;   // Id must be positive, we see should nothing be done
     1286  Storage[1]=-2.;   // 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.
     1287  Storage[2]= -10.;  // This will be an angle looking for the third point.
     1288
     1289  Chord.CopyVector(&(Walker->x)); // bring into calling function
     1290  Chord.SubtractVector(&(Walker2->x));
     1291
     1292printf("Looking for third point candidates \n");
     1293       Find_next_suitable_point(Walker, Walker2, (mol->ListOfBondsPerAtom[Walker->nr][0]->leftatom->nr == Walker->nr ? mol->ListOfBondsPerAtom[Walker->nr][0]->rightatom : mol->ListOfBondsPerAtom[Walker->nr][0]->leftatom), 0, &Chord, &helper, &Oben, Storage, RADIUS, mol);
     1294  Walker3 = mol->start;
     1295  while (Walker3->nr != int(Storage[0]))
     1296    {
     1297      Walker3 = Walker3->next;
    12691298    }
    12701299
    12711300  //Starting Triangle is Walker, Walker2, index Storage[0]
    12721301
    1273   AddPoint(&Walker);
    1274   AddPoint(&Walker2);
    1275   AddPoint(&Walker3);
    1276 
    1277   BPS[0] = new class BoundaryPointSet(&Walker);
    1278   BPS[1] = new class BoundaryPointSet(&Walker2);
     1302  AddPoint(Walker);
     1303  AddPoint(Walker2);
     1304  AddPoint(Walker3);
     1305
     1306  BPS[0] = new class BoundaryPointSet(Walker);
     1307  BPS[1] = new class BoundaryPointSet(Walker2);
    12791308  BLS[0] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
    1280   BPS[0] = new class BoundaryPointSet(&Walker);
    1281   BPS[1] = new class BoundaryPointSet(&Walker3);
     1309  BPS[0] = new class BoundaryPointSet(Walker);
     1310  BPS[1] = new class BoundaryPointSet(Walker3);
    12821311  BLS[1] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
    1283   BPS[0] = new class BoundaryPointSet(&Walker);
    1284   BPS[1] = new class BoundaryPointSet(&Walker2);
    1285   BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount); 
     1312  BPS[0] = new class BoundaryPointSet(Walker);
     1313  BPS[1] = new class BoundaryPointSet(Walker2);
     1314  BLS[2] = new class BoundaryLineSet(BPS , LinesOnBoundaryCount);
    12861315
    12871316  BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount);
     
    12891318  TrianglesOnBoundaryCount++;
    12901319
    1291   for(int i=0;i<NDIM;i++) 
     1320  for(int i=0;i<NDIM;i++)
    12921321    {
    12931322      LinesOnBoundary.insert( LinePair(LinesOnBoundaryCount, BTS->lines[i]) );
     
    13041333
    13051334
    1306 void Find_non_convex_border(Tesselation* Tess, molecule mol)
    1307 {
     1335void Find_non_convex_border(Tesselation Tess, molecule* mol)
     1336{
     1337        printf("Entering finding of non convex hull. \n");
    13081338  const double RADIUS =6;
    1309   Tess->Find_starting_triangle(mol, RADIUS);
    1310 
    1311   for (LineMap::iterator baseline = Tess->LinesOnBoundary.begin(); baseline != Tess->LinesOnBoundary.end(); baseline++)
    1312     if (baseline->second->TrianglesCount == 1) 
     1339  Tess.Find_starting_triangle(mol, RADIUS);
     1340
     1341  for (LineMap::iterator baseline = Tess.LinesOnBoundary.begin(); baseline != Tess.LinesOnBoundary.end(); baseline++)
     1342    if (baseline->second->TrianglesCount == 1)
    13131343      {
    1314         Tess->Find_next_suitable_triangle(&mol, baseline->second, baseline->second->triangles.begin()->second, RADIUS); //the line is there, so there is a triangle, but only one.
    1315 
     1344                Tess.Find_next_suitable_triangle(mol, *(baseline->second), *(baseline->second->triangles.begin()->second), RADIUS); //the line is there, so there is a triangle, but only one.
    13161345      }
    13171346    else
Note: See TracChangeset for help on using the changeset viewer.