Changes in molecuilder/src/tesselation.cpp [246a3c:591f15]
- File:
-
- 1 edited
-
molecuilder/src/tesselation.cpp (modified) (74 diffs)
Legend:
- Unmodified
- Added
- Removed
-
molecuilder/src/tesselation.cpp
r246a3c r591f15 35 35 * \param *Walker TesselPoint this boundary point represents 36 36 */ 37 BoundaryPointSet::BoundaryPointSet(TesselPoint * Walker) :37 BoundaryPointSet::BoundaryPointSet(TesselPoint * const Walker) : 38 38 LinesCount(0), 39 39 node(Walker), … … 61 61 * \param *line line to add 62 62 */ 63 void BoundaryPointSet::AddLine( class BoundaryLineSet *line)63 void BoundaryPointSet::AddLine(BoundaryLineSet * const line) 64 64 { 65 65 Info FunctionInfo(__func__); … … 105 105 * \param number number of the list 106 106 */ 107 BoundaryLineSet::BoundaryLineSet( class BoundaryPointSet *Point[2], const int number)107 BoundaryLineSet::BoundaryLineSet(BoundaryPointSet * const Point[2], const int number) 108 108 { 109 109 Info FunctionInfo(__func__); … … 115 115 Point[0]->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding. 116 116 Point[1]->AddLine(this); // 117 // set skipped to false 118 skipped = false; 119 // clear triangles list 120 Log() << Verbose(0) << "New Line with endpoints " << *this << "." << endl; 121 }; 122 123 /** Constructor of BoundaryLineSet with two endpoints. 124 * Adds line automatically to each endpoints' LineMap 125 * \param *Point1 first boundary point 126 * \param *Point2 second boundary point 127 * \param number number of the list 128 */ 129 BoundaryLineSet::BoundaryLineSet(BoundaryPointSet * const Point1, BoundaryPointSet * const Point2, const int number) 130 { 131 Info FunctionInfo(__func__); 132 // set number 133 Nr = number; 134 // set endpoints in ascending order 135 SetEndpointsOrdered(endpoints, Point1, Point2); 136 // add this line to the hash maps of both endpoints 137 Point1->AddLine(this); //Taken out, to check whether we can avoid unwanted double adding. 138 Point2->AddLine(this); // 117 139 // set skipped to false 118 140 skipped = false; … … 171 193 * \param *triangle to add 172 194 */ 173 void BoundaryLineSet::AddTriangle( class BoundaryTriangleSet *triangle)195 void BoundaryLineSet::AddTriangle(BoundaryTriangleSet * const triangle) 174 196 { 175 197 Info FunctionInfo(__func__); … … 182 204 * \return true - common endpoint present, false - not connected 183 205 */ 184 bool BoundaryLineSet::IsConnectedTo(c lass BoundaryLineSet *line)206 bool BoundaryLineSet::IsConnectedTo(const BoundaryLineSet * const line) const 185 207 { 186 208 Info FunctionInfo(__func__); … … 197 219 * \return true - triangles are convex, false - concave or less than two triangles connected 198 220 */ 199 bool BoundaryLineSet::CheckConvexityCriterion() 221 bool BoundaryLineSet::CheckConvexityCriterion() const 200 222 { 201 223 Info FunctionInfo(__func__); … … 221 243 int i=0; 222 244 class BoundaryPointSet *node = NULL; 223 for(TriangleMap:: iterator runner = triangles.begin(); runner != triangles.end(); runner++) {245 for(TriangleMap::const_iterator runner = triangles.begin(); runner != triangles.end(); runner++) { 224 246 //Log() << Verbose(0) << "INFO: NormalVector of " << *(runner->second) << " is " << runner->second->NormalVector << "." << endl; 225 247 NormalCheck.AddVector(&runner->second->NormalVector); … … 264 286 * \return true - point is of the line, false - is not 265 287 */ 266 bool BoundaryLineSet::ContainsBoundaryPoint(c lass BoundaryPointSet *point)288 bool BoundaryLineSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const 267 289 { 268 290 Info FunctionInfo(__func__); … … 277 299 * \return NULL - if endpoint not contained in BoundaryLineSet, or pointer to BoundaryPointSet otherwise 278 300 */ 279 class BoundaryPointSet *BoundaryLineSet::GetOtherEndpoint(c lass BoundaryPointSet *point)301 class BoundaryPointSet *BoundaryLineSet::GetOtherEndpoint(const BoundaryPointSet * const point) const 280 302 { 281 303 Info FunctionInfo(__func__); … … 317 339 * \param number number of triangle 318 340 */ 319 BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet * line[3],int number) :341 BoundaryTriangleSet::BoundaryTriangleSet(class BoundaryLineSet * const line[3], const int number) : 320 342 Nr(number) 321 343 { … … 376 398 * \param &OtherVector direction vector to make normal vector unique. 377 399 */ 378 void BoundaryTriangleSet::GetNormalVector( Vector &OtherVector)400 void BoundaryTriangleSet::GetNormalVector(const Vector &OtherVector) 379 401 { 380 402 Info FunctionInfo(__func__); … … 388 410 }; 389 411 390 /** Finds the point on the triangle \a *BTS th e line defined by \a *MolCenter and \a *x crosses through.412 /** Finds the point on the triangle \a *BTS through which the line defined by \a *MolCenter and \a *x crosses. 391 413 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane 392 * Th is we test if it's really on the plane and whether it's inside the triangle on the plane or not.414 * Thus we test if it's really on the plane and whether it's inside the triangle on the plane or not. 393 415 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line 394 416 * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between … … 400 422 * \return true - \a *Intersection contains intersection on plane defined by triangle, false - zero vector if outside of triangle. 401 423 */ 402 bool BoundaryTriangleSet::GetIntersectionInsideTriangle( Vector *MolCenter, Vector *x, Vector *Intersection)403 { 404 Info FunctionInfo(__func__);424 bool BoundaryTriangleSet::GetIntersectionInsideTriangle(const Vector * const MolCenter, const Vector * const x, Vector * const Intersection) const 425 { 426 Info FunctionInfo(__func__); 405 427 Vector CrossPoint; 406 428 Vector helper; … … 411 433 } 412 434 435 Log() << Verbose(1) << "INFO: Triangle is " << *this << "." << endl; 436 Log() << Verbose(1) << "INFO: Line is from " << *MolCenter << " to " << *x << "." << endl; 437 Log() << Verbose(1) << "INFO: Intersection is " << *Intersection << "." << endl; 438 439 if (Intersection->DistanceSquared(endpoints[0]->node->node) < MYEPSILON) { 440 Log() << Verbose(1) << "Intersection coindices with first endpoint." << endl; 441 return true; 442 } else if (Intersection->DistanceSquared(endpoints[1]->node->node) < MYEPSILON) { 443 Log() << Verbose(1) << "Intersection coindices with second endpoint." << endl; 444 return true; 445 } else if (Intersection->DistanceSquared(endpoints[2]->node->node) < MYEPSILON) { 446 Log() << Verbose(1) << "Intersection coindices with third endpoint." << endl; 447 return true; 448 } 413 449 // Calculate cross point between one baseline and the line from the third endpoint to intersection 414 450 int i=0; … … 417 453 helper.CopyVector(endpoints[(i+1)%3]->node->node); 418 454 helper.SubtractVector(endpoints[i%3]->node->node); 455 CrossPoint.SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector 456 const double s = CrossPoint.ScalarProduct(&helper)/helper.NormSquared(); 457 Log() << Verbose(1) << "INFO: Factor s is " << s << "." << endl; 458 if ((s < -MYEPSILON) || ((s-1.) > MYEPSILON)) { 459 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << "outside of triangle." << endl; 460 i=4; 461 break; 462 } 463 i++; 419 464 } else 420 i++;421 if (i>2)422 465 break; 423 } while ( CrossPoint.NormSquared() < MYEPSILON);466 } while (i<3); 424 467 if (i==3) { 425 eLog() << Verbose(0) << "Could not find any cross points, something's utterly wrong here!" << endl; 426 } 427 CrossPoint.SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector 428 429 // check whether intersection is inside or not by comparing length of intersection and length of cross point 430 if ((CrossPoint.NormSquared() - helper.NormSquared()) < MYEPSILON) { // inside 468 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " inside of triangle." << endl; 431 469 return true; 432 } else { // outside!433 Intersection->Zero();470 } else { 471 Log() << Verbose(1) << "INFO: Crosspoint " << CrossPoint << " outside of triangle." << endl; 434 472 return false; 435 473 } 474 }; 475 476 /** Finds the point on the triangle \a *BTS through which the line defined by \a *MolCenter and \a *x crosses. 477 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane 478 * Thus we test if it's really on the plane and whether it's inside the triangle on the plane or not. 479 * The latter is done as follows: We calculate the cross point of one of the triangle's baseline with the line 480 * given by the intersection and the third basepoint. Then, we check whether it's on the baseline (i.e. between 481 * the first two basepoints) or not. 482 * \param *x point 483 * \param *ClosestPoint desired closest point inside triangle to \a *x, is absolute vector 484 * \return Distance squared between \a *x and closest point inside triangle 485 */ 486 double BoundaryTriangleSet::GetClosestPointInsideTriangle(const Vector * const x, Vector * const ClosestPoint) const 487 { 488 Info FunctionInfo(__func__); 489 Vector Direction; 490 491 // 1. get intersection with plane 492 Log() << Verbose(1) << "INFO: Looking for closest point of triangle " << *this << " to " << *x << "." << endl; 493 GetCenter(&Direction); 494 if (!ClosestPoint->GetIntersectionWithPlane(&NormalVector, endpoints[0]->node->node, x, &Direction)) { 495 ClosestPoint->CopyVector(x); 496 } 497 498 // 2. Calculate in plane part of line (x, intersection) 499 Vector InPlane; 500 InPlane.CopyVector(x); 501 InPlane.SubtractVector(ClosestPoint); // points from plane intersection to straight-down point 502 InPlane.ProjectOntoPlane(&NormalVector); 503 InPlane.AddVector(ClosestPoint); 504 505 Log() << Verbose(2) << "INFO: Triangle is " << *this << "." << endl; 506 Log() << Verbose(2) << "INFO: Line is from " << Direction << " to " << *x << "." << endl; 507 Log() << Verbose(2) << "INFO: In-plane part is " << InPlane << "." << endl; 508 509 // Calculate cross point between one baseline and the desired point such that distance is shortest 510 double ShortestDistance = -1.; 511 bool InsideFlag = false; 512 Vector CrossDirection[3]; 513 Vector CrossPoint[3]; 514 Vector helper; 515 for (int i=0;i<3;i++) { 516 // treat direction of line as normal of a (cut)plane and the desired point x as the plane offset, the intersect line with point 517 Direction.CopyVector(endpoints[(i+1)%3]->node->node); 518 Direction.SubtractVector(endpoints[i%3]->node->node); 519 // calculate intersection, line can never be parallel to Direction (is the same vector as PlaneNormal); 520 CrossPoint[i].GetIntersectionWithPlane(&Direction, &InPlane, endpoints[i%3]->node->node, endpoints[(i+1)%3]->node->node); 521 CrossDirection[i].CopyVector(&CrossPoint[i]); 522 CrossDirection[i].SubtractVector(&InPlane); 523 CrossPoint[i].SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector 524 const double s = CrossPoint[i].ScalarProduct(&Direction)/Direction.NormSquared(); 525 Log() << Verbose(2) << "INFO: Factor s is " << s << "." << endl; 526 if ((s >= -MYEPSILON) && ((s-1.) <= MYEPSILON)) { 527 CrossPoint[i].AddVector(endpoints[i%3]->node->node); // make cross point absolute again 528 Log() << Verbose(2) << "INFO: Crosspoint is " << CrossPoint[i] << ", intersecting BoundaryLine between " << *endpoints[i%3]->node->node << " and " << *endpoints[(i+1)%3]->node->node << "." << endl; 529 const double distance = CrossPoint[i].DistanceSquared(x); 530 if ((ShortestDistance < 0.) || (ShortestDistance > distance)) { 531 ShortestDistance = distance; 532 ClosestPoint->CopyVector(&CrossPoint[i]); 533 } 534 } else 535 CrossPoint[i].Zero(); 536 } 537 InsideFlag = true; 538 for (int i=0;i<3;i++) { 539 const double sign = CrossDirection[i].ScalarProduct(&CrossDirection[(i+1)%3]); 540 const double othersign = CrossDirection[i].ScalarProduct(&CrossDirection[(i+2)%3]);; 541 if ((sign > -MYEPSILON) && (othersign > -MYEPSILON)) // have different sign 542 InsideFlag = false; 543 } 544 if (InsideFlag) { 545 ClosestPoint->CopyVector(&InPlane); 546 ShortestDistance = InPlane.DistanceSquared(x); 547 } else { // also check endnodes 548 for (int i=0;i<3;i++) { 549 const double distance = x->DistanceSquared(endpoints[i]->node->node); 550 if ((ShortestDistance < 0.) || (ShortestDistance > distance)) { 551 ShortestDistance = distance; 552 ClosestPoint->CopyVector(endpoints[i]->node->node); 553 } 554 } 555 } 556 Log() << Verbose(1) << "INFO: Closest Point is " << *ClosestPoint << " with shortest squared distance is " << ShortestDistance << "." << endl; 557 return ShortestDistance; 436 558 }; 437 559 … … 440 562 * \return true - line is of the triangle, false - is not 441 563 */ 442 bool BoundaryTriangleSet::ContainsBoundaryLine(c lass BoundaryLineSet *line)564 bool BoundaryTriangleSet::ContainsBoundaryLine(const BoundaryLineSet * const line) const 443 565 { 444 566 Info FunctionInfo(__func__); … … 453 575 * \return true - point is of the triangle, false - is not 454 576 */ 455 bool BoundaryTriangleSet::ContainsBoundaryPoint(c lass BoundaryPointSet *point)577 bool BoundaryTriangleSet::ContainsBoundaryPoint(const BoundaryPointSet * const point) const 456 578 { 457 579 Info FunctionInfo(__func__); … … 466 588 * \return true - point is of the triangle, false - is not 467 589 */ 468 bool BoundaryTriangleSet::ContainsBoundaryPoint(c lass TesselPoint *point)590 bool BoundaryTriangleSet::ContainsBoundaryPoint(const TesselPoint * const point) const 469 591 { 470 592 Info FunctionInfo(__func__); … … 479 601 * \return true - is the very triangle, false - is not 480 602 */ 481 bool BoundaryTriangleSet::IsPresentTupel(class BoundaryPointSet *Points[3]) 482 { 483 Info FunctionInfo(__func__); 603 bool BoundaryTriangleSet::IsPresentTupel(const BoundaryPointSet * const Points[3]) const 604 { 605 Info FunctionInfo(__func__); 606 Log() << Verbose(1) << "INFO: Checking " << Points[0] << "," << Points[1] << "," << Points[2] << " against " << endpoints[0] << "," << endpoints[1] << "," << endpoints[2] << "." << endl; 484 607 return (((endpoints[0] == Points[0]) 485 608 || (endpoints[0] == Points[1]) … … 501 624 * \return true - is the very triangle, false - is not 502 625 */ 503 bool BoundaryTriangleSet::IsPresentTupel(c lass BoundaryTriangleSet *T)626 bool BoundaryTriangleSet::IsPresentTupel(const BoundaryTriangleSet * const T) const 504 627 { 505 628 Info FunctionInfo(__func__); … … 523 646 * \return pointer third endpoint or NULL if line does not belong to triangle. 524 647 */ 525 class BoundaryPointSet *BoundaryTriangleSet::GetThirdEndpoint(c lass BoundaryLineSet *line)648 class BoundaryPointSet *BoundaryTriangleSet::GetThirdEndpoint(const BoundaryLineSet * const line) const 526 649 { 527 650 Info FunctionInfo(__func__); … … 540 663 * \param *center central point on return. 541 664 */ 542 void BoundaryTriangleSet::GetCenter(Vector * center)665 void BoundaryTriangleSet::GetCenter(Vector * const center) const 543 666 { 544 667 Info FunctionInfo(__func__); … … 547 670 center->AddVector(endpoints[i]->node->node); 548 671 center->Scale(1./3.); 672 Log() << Verbose(1) << "INFO: Center is at " << *center << "." << endl; 549 673 } 550 674 … … 1422 1546 TesselPoint *Walker = NULL; 1423 1547 Vector *Center = cloud->GetCenter(); 1424 list<BoundaryTriangleSet*>*triangles = NULL;1548 TriangleList *triangles = NULL; 1425 1549 bool AddFlag = false; 1426 1550 LinkedCell *BoundaryPoints = NULL; … … 1437 1561 Log() << Verbose(0) << "Current point is " << *Walker << "." << endl; 1438 1562 // get the next triangle 1439 triangles = FindClosestTrianglesTo Point(Walker->node, BoundaryPoints);1563 triangles = FindClosestTrianglesToVector(Walker->node, BoundaryPoints); 1440 1564 BTS = triangles->front(); 1441 1565 if ((triangles == NULL) || (BTS->ContainsBoundaryPoint(Walker))) { … … 1587 1711 bool insertNewLine = true; 1588 1712 1589 if (a->lines.find(b->node->nr) != a->lines.end()) { 1590 LineMap::iterator FindLine = a->lines.find(b->node->nr); 1713 LineMap::iterator FindLine = a->lines.find(b->node->nr); 1714 if (FindLine != a->lines.end()) { 1715 Log() << Verbose(1) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl; 1716 1591 1717 pair<LineMap::iterator,LineMap::iterator> FindPair; 1592 1718 FindPair = a->lines.equal_range(b->node->nr); 1593 Log() << Verbose(1) << "INFO: There is at least one line between " << *a << " and " << *b << ": " << *(FindLine->second) << "." << endl;1594 1719 1595 1720 for (FindLine = FindPair.first; FindLine != FindPair.second; FindLine++) { … … 1915 2040 double maxCoordinate[NDIM]; 1916 2041 BoundaryLineSet BaseLine; 1917 Vector Oben;1918 2042 Vector helper; 1919 2043 Vector Chord; 1920 2044 Vector SearchDirection; 1921 1922 Oben.Zero(); 2045 Vector CircleCenter; // center of the circle, i.e. of the band of sphere's centers 2046 Vector CirclePlaneNormal; // normal vector defining the plane this circle lives in 2047 Vector SphereCenter; 2048 Vector NormalVector; 2049 2050 NormalVector.Zero(); 1923 2051 1924 2052 for (i = 0; i < 3; i++) { … … 1955 2083 BTS = NULL; 1956 2084 for (int k=0;k<NDIM;k++) { 1957 Oben.Zero();1958 Oben.x[k] = 1.;2085 NormalVector.Zero(); 2086 NormalVector.x[k] = 1.; 1959 2087 BaseLine.endpoints[0] = new BoundaryPointSet(MaxPoint[k]); 1960 2088 Log() << Verbose(0) << "Coordinates of start node at " << *BaseLine.endpoints[0]->node << "." << endl; … … 1963 2091 ShortestAngle = 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. 1964 2092 1965 FindSecondPointForTesselation(BaseLine.endpoints[0]->node, Oben, Temporary, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_...2093 FindSecondPointForTesselation(BaseLine.endpoints[0]->node, NormalVector, Temporary, &ShortestAngle, RADIUS, LC); // we give same point as next candidate as its bonds are looked into in find_second_... 1966 2094 if (Temporary == NULL) // have we found a second point? 1967 2095 continue; 1968 2096 BaseLine.endpoints[1] = new BoundaryPointSet(Temporary); 1969 2097 1970 helper.CopyVector(BaseLine.endpoints[0]->node->node); 1971 helper.SubtractVector(BaseLine.endpoints[1]->node->node); 1972 helper.Normalize(); 1973 Oben.ProjectOntoPlane(&helper); 1974 Oben.Normalize(); 1975 helper.VectorProduct(&Oben); 2098 // construct center of circle 2099 CircleCenter.CopyVector(BaseLine.endpoints[0]->node->node); 2100 CircleCenter.AddVector(BaseLine.endpoints[1]->node->node); 2101 CircleCenter.Scale(0.5); 2102 2103 // construct normal vector of circle 2104 CirclePlaneNormal.CopyVector(BaseLine.endpoints[0]->node->node); 2105 CirclePlaneNormal.SubtractVector(BaseLine.endpoints[1]->node->node); 2106 2107 double radius = CirclePlaneNormal.NormSquared(); 2108 double CircleRadius = sqrt(RADIUS*RADIUS - radius/4.); 2109 2110 NormalVector.ProjectOntoPlane(&CirclePlaneNormal); 2111 NormalVector.Normalize(); 1976 2112 ShortestAngle = 2.*M_PI; // This will indicate the quadrant. 1977 2113 1978 Chord.CopyVector(BaseLine.endpoints[0]->node->node); // bring into calling function 1979 Chord.SubtractVector(BaseLine.endpoints[1]->node->node); 1980 double radius = Chord.ScalarProduct(&Chord); 1981 double CircleRadius = sqrt(RADIUS*RADIUS - radius/4.); 1982 helper.CopyVector(&Oben); 1983 helper.Scale(CircleRadius); 1984 // Now, oben and helper are two orthonormalized vectors in the plane defined by Chord (not normalized) 2114 SphereCenter.CopyVector(&NormalVector); 2115 SphereCenter.Scale(CircleRadius); 2116 SphereCenter.AddVector(&CircleCenter); 2117 // Now, NormalVector and SphereCenter are two orthonormalized vectors in the plane defined by CirclePlaneNormal (not normalized) 1985 2118 1986 2119 // look in one direction of baseline for initial candidate 1987 SearchDirection.MakeNormalVector(&C hord, &Oben); // whether we look "left" first or "right" first is not important ...2120 SearchDirection.MakeNormalVector(&CirclePlaneNormal, &NormalVector); // whether we look "left" first or "right" first is not important ... 1988 2121 1989 2122 // adding point 1 and point 2 and add the line between them … … 1993 2126 //Log() << Verbose(1) << "INFO: OldSphereCenter is at " << helper << ".\n"; 1994 2127 CandidateForTesselation OptCandidates(&BaseLine); 1995 FindThirdPointForTesselation( Oben, SearchDirection, helper, OptCandidates, NULL, RADIUS, LC);2128 FindThirdPointForTesselation(NormalVector, SearchDirection, SphereCenter, OptCandidates, NULL, RADIUS, LC); 1996 2129 Log() << Verbose(0) << "List of third Points is:" << endl; 1997 2130 for (TesselPointList::iterator it = OptCandidates.pointlist.begin(); it != OptCandidates.pointlist.end(); it++) { … … 2167 2300 Vector CircleCenter; 2168 2301 Vector CirclePlaneNormal; 2169 Vector OldSphereCenter;2302 Vector RelativeSphereCenter; 2170 2303 Vector SearchDirection; 2171 2304 Vector helper; … … 2174 2307 double radius, CircleRadius; 2175 2308 2176 Log() << Verbose(0) << "Current baseline is " << *CandidateLine.BaseLine << " of triangle " << T << "." << endl;2177 2309 for (int i=0;i<3;i++) 2178 if ((T.endpoints[i]->node != CandidateLine.BaseLine->endpoints[0]->node) && (T.endpoints[i]->node != CandidateLine.BaseLine->endpoints[1]->node)) 2310 if ((T.endpoints[i]->node != CandidateLine.BaseLine->endpoints[0]->node) && (T.endpoints[i]->node != CandidateLine.BaseLine->endpoints[1]->node)) { 2179 2311 ThirdNode = T.endpoints[i]->node; 2312 break; 2313 } 2314 Log() << Verbose(0) << "Current baseline is " << *CandidateLine.BaseLine << " with ThirdNode " << *ThirdNode << " of triangle " << T << "." << endl; 2180 2315 2181 2316 // construct center of circle … … 2191 2326 radius = CirclePlaneNormal.ScalarProduct(&CirclePlaneNormal); 2192 2327 if (radius/4. < RADIUS*RADIUS) { 2328 // construct relative sphere center with now known CircleCenter 2329 RelativeSphereCenter.CopyVector(&T.SphereCenter); 2330 RelativeSphereCenter.SubtractVector(&CircleCenter); 2331 2193 2332 CircleRadius = RADIUS*RADIUS - radius/4.; 2194 2333 CirclePlaneNormal.Normalize(); 2195 2334 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 2196 2335 2197 // construct old center 2198 GetCenterofCircumcircle(&OldSphereCenter, *T.endpoints[0]->node->node, *T.endpoints[1]->node->node, *T.endpoints[2]->node->node); 2199 helper.CopyVector(&T.NormalVector); // normal vector ensures that this is correct center of the two possible ones 2200 radius = CandidateLine.BaseLine->endpoints[0]->node->node->DistanceSquared(&OldSphereCenter); 2201 helper.Scale(sqrt(RADIUS*RADIUS - radius)); 2202 OldSphereCenter.AddVector(&helper); 2203 OldSphereCenter.SubtractVector(&CircleCenter); 2204 Log() << Verbose(1) << "INFO: OldSphereCenter is at " << OldSphereCenter << "." << endl; 2205 2206 // construct SearchDirection 2207 SearchDirection.MakeNormalVector(&T.NormalVector, &CirclePlaneNormal); 2208 helper.CopyVector(CandidateLine.BaseLine->endpoints[0]->node->node); 2336 Log() << Verbose(1) << "INFO: OldSphereCenter is at " << T.SphereCenter << "." << endl; 2337 2338 // construct SearchDirection and an "outward pointer" 2339 SearchDirection.MakeNormalVector(&RelativeSphereCenter, &CirclePlaneNormal); 2340 helper.CopyVector(&CircleCenter); 2209 2341 helper.SubtractVector(ThirdNode->node); 2210 2342 if (helper.ScalarProduct(&SearchDirection) < -HULLEPSILON)// ohoh, SearchDirection points inwards! 2211 2343 SearchDirection.Scale(-1.); 2212 SearchDirection.ProjectOntoPlane(&OldSphereCenter);2213 SearchDirection.Normalize();2214 2344 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 2215 if (fabs( OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) {2345 if (fabs(RelativeSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { 2216 2346 // rotated the wrong way! 2217 2347 eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are still not orthogonal!" << endl; … … 2219 2349 2220 2350 // add third point 2221 FindThirdPointForTesselation(T.NormalVector, SearchDirection, OldSphereCenter, CandidateLine, ThirdNode, RADIUS, LC);2351 FindThirdPointForTesselation(T.NormalVector, SearchDirection, T.SphereCenter, CandidateLine, ThirdNode, RADIUS, LC); 2222 2352 2223 2353 } else { … … 2332 2462 2333 2463 // fill the set of neighbours 2334 Center.CopyVector(CandidateLine.BaseLine->endpoints[1]->node->node); 2335 Center.SubtractVector(TurningPoint->node); 2336 set<TesselPoint*> SetOfNeighbours; 2464 TesselPointSet SetOfNeighbours; 2337 2465 SetOfNeighbours.insert(CandidateLine.BaseLine->endpoints[1]->node); 2338 2466 for (TesselPointList::iterator Runner = CandidateLine.pointlist.begin(); Runner != CandidateLine.pointlist.end(); Runner++) 2339 2467 SetOfNeighbours.insert(*Runner); 2340 TesselPointList *connectedClosestPoints = GetCircleOfSetOfPoints(&SetOfNeighbours, TurningPoint, &Center);2468 TesselPointList *connectedClosestPoints = GetCircleOfSetOfPoints(&SetOfNeighbours, TurningPoint, CandidateLine.BaseLine->endpoints[1]->node->node); 2341 2469 2342 2470 // go through all angle-sorted candidates (in degenerate n-nodes case we may have to add multiple triangles) 2471 Log() << Verbose(0) << "List of Candidates for Turning Point: " << *TurningPoint << "." << endl; 2472 for (TesselPointList::iterator TesselRunner = connectedClosestPoints->begin(); TesselRunner != connectedClosestPoints->end(); ++TesselRunner) 2473 Log() << Verbose(0) << **TesselRunner << endl; 2343 2474 TesselPointList::iterator Runner = connectedClosestPoints->begin(); 2344 2475 TesselPointList::iterator Sprinter = Runner; … … 2350 2481 AddTesselationPoint((*Sprinter), 2); 2351 2482 2352 Center.CopyVector(&CandidateLine.OptCenter);2353 2483 // add the lines 2354 2484 AddTesselationLine(TPS[0], TPS[1], 0); … … 2359 2489 BTS = new class BoundaryTriangleSet(BLS, TrianglesOnBoundaryCount); 2360 2490 AddTesselationTriangle(); 2361 Center.Scale(-1.); 2491 BTS->GetCenter(&Center); 2492 Center.SubtractVector(&CandidateLine.OptCenter); 2493 BTS->SphereCenter.CopyVector(&CandidateLine.OptCenter); 2362 2494 BTS->GetNormalVector(Center); 2363 2495 … … 2365 2497 Runner = Sprinter; 2366 2498 Sprinter++; 2499 Log() << Verbose(0) << "Current Runner is " << **Runner << "." << endl; 2500 if (Sprinter != connectedClosestPoints->end()) 2501 Log() << Verbose(0) << " There are still more triangles to add." << endl; 2367 2502 } 2368 2503 delete(connectedClosestPoints); … … 2766 2901 Vector NewNormalVector; // normal vector of the Candidate's triangle 2767 2902 Vector helper, OptCandidateCenter, OtherOptCandidateCenter; 2903 Vector RelativeOldSphereCenter; 2904 Vector NewPlaneCenter; 2768 2905 double CircleRadius; // radius of this circle 2769 2906 double radius; 2907 double otherradius; 2770 2908 double alpha, Otheralpha; // angles (i.e. parameter for the circle). 2771 2909 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; … … 2783 2921 CirclePlaneNormal.SubtractVector(CandidateLine.BaseLine->endpoints[1]->node->node); 2784 2922 2923 RelativeOldSphereCenter.CopyVector(&OldSphereCenter); 2924 RelativeOldSphereCenter.SubtractVector(&CircleCenter); 2925 2785 2926 // calculate squared radius TesselPoint *ThirdNode,f circle 2786 radius = CirclePlaneNormal. ScalarProduct(&CirclePlaneNormal);2787 if (radius /4.< RADIUS*RADIUS) {2788 CircleRadius = RADIUS*RADIUS - radius /4.;2927 radius = CirclePlaneNormal.NormSquared()/4.; 2928 if (radius < RADIUS*RADIUS) { 2929 CircleRadius = RADIUS*RADIUS - radius; 2789 2930 CirclePlaneNormal.Normalize(); 2790 //Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl;2931 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 2791 2932 2792 2933 // test whether old center is on the band's plane 2793 if (fabs( OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) > HULLEPSILON) {2794 eLog() << Verbose(1) << "Something's very wrong here: OldSphereCenter is not on the band's plane as desired by " << fabs(OldSphereCenter.ScalarProduct(&CirclePlaneNormal)) << "!" << endl;2795 OldSphereCenter.ProjectOntoPlane(&CirclePlaneNormal);2796 } 2797 radius = OldSphereCenter.ScalarProduct(&OldSphereCenter);2934 if (fabs(RelativeOldSphereCenter.ScalarProduct(&CirclePlaneNormal)) > HULLEPSILON) { 2935 eLog() << Verbose(1) << "Something's very wrong here: RelativeOldSphereCenter is not on the band's plane as desired by " << fabs(RelativeOldSphereCenter.ScalarProduct(&CirclePlaneNormal)) << "!" << endl; 2936 RelativeOldSphereCenter.ProjectOntoPlane(&CirclePlaneNormal); 2937 } 2938 radius = RelativeOldSphereCenter.NormSquared(); 2798 2939 if (fabs(radius - CircleRadius) < HULLEPSILON) { 2799 //Log() << Verbose(1) << "INFO: OldSphereCenter is at " <<OldSphereCenter << "." << endl;2940 Log() << Verbose(1) << "INFO: RelativeOldSphereCenter is at " << RelativeOldSphereCenter << "." << endl; 2800 2941 2801 2942 // check SearchDirection 2802 //Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl;2803 if (fabs( OldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { // rotated the wrong way!2943 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 2944 if (fabs(RelativeOldSphereCenter.ScalarProduct(&SearchDirection)) > HULLEPSILON) { // rotated the wrong way! 2804 2945 eLog() << Verbose(1) << "SearchDirection and RelativeOldSphereCenter are not orthogonal!" << endl; 2805 2946 } … … 2832 2973 2833 2974 // check for three unique points 2834 Log() << Verbose(2) << "INFO: Current Candidate is " << *Candidate << " at " << *(Candidate->node)<< "." << endl;2975 Log() << Verbose(2) << "INFO: Current Candidate is " << *Candidate << " for BaseLine " << *CandidateLine.BaseLine << " with OldSphereCenter " << OldSphereCenter << "." << endl; 2835 2976 if ((Candidate != CandidateLine.BaseLine->endpoints[0]->node) && (Candidate != CandidateLine.BaseLine->endpoints[1]->node) ){ 2836 2977 2837 // construct both new centers2838 GetCenterofCircumcircle(&New SphereCenter, *CandidateLine.BaseLine->endpoints[0]->node->node, *CandidateLine.BaseLine->endpoints[1]->node->node, *Candidate->node);2839 OtherNewSphereCenter.CopyVector(&NewSphereCenter);2840 2841 if ( (NewNormalVector.MakeNormalVector(CandidateLine.BaseLine->endpoints[0]->node->node, CandidateLine.BaseLine->endpoints[1]->node->node, Candidate->node))2842 && (fabs(NewNormalVector. ScalarProduct(&NewNormalVector)) > HULLEPSILON)2978 // find center on the plane 2979 GetCenterofCircumcircle(&NewPlaneCenter, *CandidateLine.BaseLine->endpoints[0]->node->node, *CandidateLine.BaseLine->endpoints[1]->node->node, *Candidate->node); 2980 Log() << Verbose(1) << "INFO: NewPlaneCenter is " << NewPlaneCenter << "." << endl; 2981 2982 if (NewNormalVector.MakeNormalVector(CandidateLine.BaseLine->endpoints[0]->node->node, CandidateLine.BaseLine->endpoints[1]->node->node, Candidate->node) 2983 && (fabs(NewNormalVector.NormSquared()) > HULLEPSILON) 2843 2984 ) { 2844 helper.CopyVector(&NewNormalVector);2845 2985 Log() << Verbose(1) << "INFO: NewNormalVector is " << NewNormalVector << "." << endl; 2846 radius = CandidateLine.BaseLine->endpoints[0]->node->node->DistanceSquared(&NewSphereCenter); 2986 radius = CandidateLine.BaseLine->endpoints[0]->node->node->DistanceSquared(&NewPlaneCenter); 2987 Log() << Verbose(1) << "INFO: CircleCenter is at " << CircleCenter << ", CirclePlaneNormal is " << CirclePlaneNormal << " with circle radius " << sqrt(CircleRadius) << "." << endl; 2988 Log() << Verbose(1) << "INFO: SearchDirection is " << SearchDirection << "." << endl; 2989 Log() << Verbose(1) << "INFO: Radius of CircumCenterCircle is " << radius << "." << endl; 2847 2990 if (radius < RADIUS*RADIUS) { 2991 otherradius = CandidateLine.BaseLine->endpoints[1]->node->node->DistanceSquared(&NewPlaneCenter); 2992 if (fabs(radius - otherradius) > HULLEPSILON) { 2993 eLog() << Verbose(1) << "Distance to center of circumcircle is not the same from each corner of the triangle: " << fabs(radius-otherradius) << endl; 2994 } 2995 // construct both new centers 2996 NewSphereCenter.CopyVector(&NewPlaneCenter); 2997 OtherNewSphereCenter.CopyVector(&NewPlaneCenter); 2998 helper.CopyVector(&NewNormalVector); 2848 2999 helper.Scale(sqrt(RADIUS*RADIUS - radius)); 2849 Log() << Verbose(2) << "INFO: Distance of New CircleCenter to NewSphereCenter is " << helper.Norm()<< " with sphere radius " << RADIUS << "." << endl;3000 Log() << Verbose(2) << "INFO: Distance of NewPlaneCenter " << NewPlaneCenter << " to either NewSphereCenter is " << helper.Norm() << " of vector " << helper << " with sphere radius " << RADIUS << "." << endl; 2850 3001 NewSphereCenter.AddVector(&helper); 2851 NewSphereCenter.SubtractVector(&CircleCenter);2852 3002 Log() << Verbose(2) << "INFO: NewSphereCenter is at " << NewSphereCenter << "." << endl; 2853 2854 3003 // OtherNewSphereCenter is created by the same vector just in the other direction 2855 3004 helper.Scale(-1.); 2856 3005 OtherNewSphereCenter.AddVector(&helper); 2857 OtherNewSphereCenter.SubtractVector(&CircleCenter);2858 3006 Log() << Verbose(2) << "INFO: OtherNewSphereCenter is at " << OtherNewSphereCenter << "." << endl; 2859 3007 … … 2861 3009 Otheralpha = GetPathLengthonCircumCircle(CircleCenter, CirclePlaneNormal, CircleRadius, OtherNewSphereCenter, OldSphereCenter, NormalVector, SearchDirection); 2862 3010 alpha = min(alpha, Otheralpha); 3011 2863 3012 // if there is a better candidate, drop the current list and add the new candidate 2864 3013 // otherwise ignore the new candidate and keep the list … … 2892 3041 } 2893 3042 } 2894 2895 3043 } else { 2896 3044 Log() << Verbose(1) << "REJECT: NewSphereCenter " << NewSphereCenter << " for " << *Candidate << " is too far away: " << radius << "." << endl; … … 2936 3084 const BoundaryLineSet * lines[2] = { line1, line2 }; 2937 3085 class BoundaryPointSet *node = NULL; 2938 map<int, class BoundaryPointSet *>OrderMap;2939 pair<map<int, class BoundaryPointSet *>::iterator, bool>OrderTest;3086 PointMap OrderMap; 3087 PointTestPair OrderTest; 2940 3088 for (int i = 0; i < 2; i++) 2941 3089 // for both lines … … 2957 3105 }; 2958 3106 3107 /** Finds the boundary points that are closest to a given Vector \a *x. 3108 * \param *out output stream for debugging 3109 * \param *x Vector to look from 3110 * \return map of BoundaryPointSet of closest points sorted by squared distance or NULL. 3111 */ 3112 DistanceToPointMap * Tesselation::FindClosestBoundaryPointsToVector(const Vector *x, const LinkedCell* LC) const 3113 { 3114 Info FunctionInfo(__func__); 3115 PointMap::const_iterator FindPoint; 3116 int N[NDIM], Nlower[NDIM], Nupper[NDIM]; 3117 3118 if (LinesOnBoundary.empty()) { 3119 eLog() << Verbose(1) << "There is no tesselation structure to compare the point with, please create one first." << endl; 3120 return NULL; 3121 } 3122 3123 // gather all points close to the desired one 3124 LC->SetIndexToVector(x); // ignore status as we calculate bounds below sensibly 3125 for(int i=0;i<NDIM;i++) // store indices of this cell 3126 N[i] = LC->n[i]; 3127 Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 3128 3129 DistanceToPointMap * points = new DistanceToPointMap; 3130 LC->GetNeighbourBounds(Nlower, Nupper); 3131 //Log() << Verbose(1) << endl; 3132 for (LC->n[0] = Nlower[0]; LC->n[0] <= Nupper[0]; LC->n[0]++) 3133 for (LC->n[1] = Nlower[1]; LC->n[1] <= Nupper[1]; LC->n[1]++) 3134 for (LC->n[2] = Nlower[2]; LC->n[2] <= Nupper[2]; LC->n[2]++) { 3135 const LinkedNodes *List = LC->GetCurrentCell(); 3136 //Log() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << endl; 3137 if (List != NULL) { 3138 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 3139 FindPoint = PointsOnBoundary.find((*Runner)->nr); 3140 if (FindPoint != PointsOnBoundary.end()) { 3141 points->insert(DistanceToPointPair (FindPoint->second->node->node->DistanceSquared(x), FindPoint->second) ); 3142 Log() << Verbose(1) << "INFO: Putting " << *FindPoint->second << " into the list." << endl; 3143 } 3144 } 3145 } else { 3146 eLog() << Verbose(1) << "The current cell " << LC->n[0] << "," << LC->n[1] << "," << LC->n[2] << " is invalid!" << endl; 3147 } 3148 } 3149 3150 // check whether we found some points 3151 if (points->empty()) { 3152 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl; 3153 delete(points); 3154 return NULL; 3155 } 3156 return points; 3157 }; 3158 3159 /** Finds the boundary line that is closest to a given Vector \a *x. 3160 * \param *out output stream for debugging 3161 * \param *x Vector to look from 3162 * \return closest BoundaryLineSet or NULL in degenerate case. 3163 */ 3164 BoundaryLineSet * Tesselation::FindClosestBoundaryLineToVector(const Vector *x, const LinkedCell* LC) const 3165 { 3166 Info FunctionInfo(__func__); 3167 3168 // get closest points 3169 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x,LC); 3170 if (points == NULL) { 3171 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl; 3172 return NULL; 3173 } 3174 3175 // for each point, check its lines, remember closest 3176 Log() << Verbose(1) << "Finding closest BoundaryLine to " << *x << " ... " << endl; 3177 BoundaryLineSet *ClosestLine = NULL; 3178 double MinDistance = -1.; 3179 Vector helper; 3180 Vector Center; 3181 Vector BaseLine; 3182 for (DistanceToPointMap::iterator Runner = points->begin(); Runner != points->end(); Runner++) { 3183 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 3184 // calculate closest point on line to desired point 3185 helper.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3186 helper.AddVector((LineRunner->second)->endpoints[1]->node->node); 3187 helper.Scale(0.5); 3188 Center.CopyVector(x); 3189 Center.SubtractVector(&helper); 3190 BaseLine.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3191 BaseLine.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3192 Center.ProjectOntoPlane(&BaseLine); 3193 const double distance = Center.NormSquared(); 3194 if ((ClosestLine == NULL) || (distance < MinDistance)) { 3195 // additionally calculate intersection on line (whether it's on the line section or not) 3196 helper.CopyVector(x); 3197 helper.SubtractVector((LineRunner->second)->endpoints[0]->node->node); 3198 helper.SubtractVector(&Center); 3199 const double lengthA = helper.ScalarProduct(&BaseLine); 3200 helper.CopyVector(x); 3201 helper.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3202 helper.SubtractVector(&Center); 3203 const double lengthB = helper.ScalarProduct(&BaseLine); 3204 if (lengthB*lengthA < 0) { // if have different sign 3205 ClosestLine = LineRunner->second; 3206 MinDistance = distance; 3207 Log() << Verbose(1) << "ACCEPT: New closest line is " << *ClosestLine << " with projected distance " << MinDistance << "." << endl; 3208 } else { 3209 Log() << Verbose(1) << "REJECT: Intersection is outside of the line section: " << lengthA << " and " << lengthB << "." << endl; 3210 } 3211 } else { 3212 Log() << Verbose(1) << "REJECT: Point is too further away than present line: " << distance << " >> " << MinDistance << "." << endl; 3213 } 3214 } 3215 } 3216 delete(points); 3217 // check whether closest line is "too close" :), then it's inside 3218 if (ClosestLine == NULL) { 3219 Log() << Verbose(0) << "Is the only point, no one else is closeby." << endl; 3220 return NULL; 3221 } 3222 return ClosestLine; 3223 }; 3224 3225 2959 3226 /** Finds the triangle that is closest to a given Vector \a *x. 2960 3227 * \param *out output stream for debugging 2961 3228 * \param *x Vector to look from 2962 * \return list of BoundaryTriangleSet of nearest triangles or NULL in degenerate case. 2963 */ 2964 list<BoundaryTriangleSet*> * Tesselation::FindClosestTrianglesToPoint(const Vector *x, const LinkedCell* LC) const 2965 { 2966 Info FunctionInfo(__func__); 2967 TesselPoint *trianglePoints[3]; 2968 TesselPoint *SecondPoint = NULL; 2969 list<BoundaryTriangleSet*> *triangles = NULL; 2970 2971 if (LinesOnBoundary.empty()) { 2972 eLog() << Verbose(1) << "Error: There is no tesselation structure to compare the point with, please create one first."; 3229 * \return BoundaryTriangleSet of nearest triangle or NULL. 3230 */ 3231 TriangleList * Tesselation::FindClosestTrianglesToVector(const Vector *x, const LinkedCell* LC) const 3232 { 3233 Info FunctionInfo(__func__); 3234 3235 // get closest points 3236 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x,LC); 3237 if (points == NULL) { 3238 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl; 2973 3239 return NULL; 2974 3240 } 2975 Log() << Verbose(1) << "Finding closest Tesselpoint to " << *x << " ... " << endl; 2976 trianglePoints[0] = FindClosestPoint(x, SecondPoint, LC); 2977 2978 // check whether closest point is "too close" :), then it's inside 2979 if (trianglePoints[0] == NULL) { 3241 3242 // for each point, check its lines, remember closest 3243 Log() << Verbose(1) << "Finding closest BoundaryTriangle to " << *x << " ... " << endl; 3244 LineSet ClosestLines; 3245 double MinDistance = 1e+16; 3246 Vector BaseLineIntersection; 3247 Vector Center; 3248 Vector BaseLine; 3249 Vector BaseLineCenter; 3250 for (DistanceToPointMap::iterator Runner = points->begin(); Runner != points->end(); Runner++) { 3251 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 3252 3253 BaseLine.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3254 BaseLine.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3255 const double lengthBase = BaseLine.NormSquared(); 3256 3257 BaseLineIntersection.CopyVector(x); 3258 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[0]->node->node); 3259 const double lengthEndA = BaseLineIntersection.NormSquared(); 3260 3261 BaseLineIntersection.CopyVector(x); 3262 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3263 const double lengthEndB = BaseLineIntersection.NormSquared(); 3264 3265 if ((lengthEndA > lengthBase) || (lengthEndB > lengthBase) || ((lengthEndA < MYEPSILON) || (lengthEndB < MYEPSILON))) { // intersection would be outside, take closer endpoint 3266 const double lengthEnd = Min(lengthEndA, lengthEndB); 3267 if (lengthEnd - MinDistance < -MYEPSILON) { // new best line 3268 ClosestLines.clear(); 3269 ClosestLines.insert(LineRunner->second); 3270 MinDistance = lengthEnd; 3271 Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[0]->node << " is closer with " << lengthEnd << "." << endl; 3272 } else if (fabs(lengthEnd - MinDistance) < MYEPSILON) { // additional best candidate 3273 ClosestLines.insert(LineRunner->second); 3274 Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is equally good with " << lengthEnd << "." << endl; 3275 } else { // line is worse 3276 Log() << Verbose(1) << "REJECT: Line " << *LineRunner->second << " to either endpoints is further away than present closest line candidate: " << lengthEndA << ", " << lengthEndB << ", and distance is longer than baseline:" << lengthBase << "." << endl; 3277 } 3278 } else { // intersection is closer, calculate 3279 // calculate closest point on line to desired point 3280 BaseLineIntersection.CopyVector(x); 3281 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3282 Center.CopyVector(&BaseLineIntersection); 3283 Center.ProjectOntoPlane(&BaseLine); 3284 BaseLineIntersection.SubtractVector(&Center); 3285 const double distance = BaseLineIntersection.NormSquared(); 3286 if (Center.NormSquared() > BaseLine.NormSquared()) { 3287 eLog() << Verbose(0) << "Algorithmic error: In second case we have intersection outside of baseline!" << endl; 3288 } 3289 if ((ClosestLines.empty()) || (distance < MinDistance)) { 3290 ClosestLines.insert(LineRunner->second); 3291 MinDistance = distance; 3292 Log() << Verbose(1) << "ACCEPT: Intersection in between endpoints, new closest line " << *LineRunner->second << " is " << *ClosestLines.begin() << " with projected distance " << MinDistance << "." << endl; 3293 } else { 3294 Log() << Verbose(2) << "REJECT: Point is further away from line " << *LineRunner->second << " than present closest line: " << distance << " >> " << MinDistance << "." << endl; 3295 } 3296 } 3297 } 3298 } 3299 delete(points); 3300 3301 // check whether closest line is "too close" :), then it's inside 3302 if (ClosestLines.empty()) { 2980 3303 Log() << Verbose(0) << "Is the only point, no one else is closeby." << endl; 2981 3304 return NULL; 2982 3305 } 2983 if (trianglePoints[0]->node->DistanceSquared(x) < MYEPSILON) { 2984 Log() << Verbose(1) << "Point is right on a tesselation point, no nearest triangle." << endl; 2985 PointMap::const_iterator PointRunner = PointsOnBoundary.find(trianglePoints[0]->nr); 2986 triangles = new list<BoundaryTriangleSet*>; 2987 if (PointRunner != PointsOnBoundary.end()) { 2988 for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++) 2989 for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++) 2990 triangles->push_back(TriangleRunner->second); 2991 triangles->sort(); 2992 triangles->unique(); 2993 } else { 2994 PointRunner = PointsOnBoundary.find(SecondPoint->nr); 2995 trianglePoints[0] = SecondPoint; 2996 if (PointRunner != PointsOnBoundary.end()) { 2997 for(LineMap::iterator LineRunner = PointRunner->second->lines.begin(); LineRunner != PointRunner->second->lines.end(); LineRunner++) 2998 for(TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++) 2999 triangles->push_back(TriangleRunner->second); 3000 triangles->sort(); 3001 triangles->unique(); 3002 } else { 3003 eLog() << Verbose(1) << "I cannot find a boundary point to the tessel point " << *trianglePoints[0] << "." << endl; 3004 return NULL; 3005 } 3006 } 3007 } else { 3008 set<TesselPoint*> *connectedPoints = GetAllConnectedPoints(trianglePoints[0]); 3009 TesselPointList *connectedClosestPoints = GetCircleOfSetOfPoints(connectedPoints, trianglePoints[0], x); 3010 delete(connectedPoints); 3011 if (connectedClosestPoints != NULL) { 3012 trianglePoints[1] = connectedClosestPoints->front(); 3013 trianglePoints[2] = connectedClosestPoints->back(); 3014 for (int i=0;i<3;i++) { 3015 if (trianglePoints[i] == NULL) { 3016 eLog() << Verbose(1) << "IsInnerPoint encounters serious error, point " << i << " not found." << endl; 3017 } 3018 //Log() << Verbose(1) << "List of triangle points:" << endl; 3019 //Log() << Verbose(2) << *trianglePoints[i] << endl; 3020 } 3021 3022 triangles = FindTriangles(trianglePoints); 3023 Log() << Verbose(1) << "List of possible triangles:" << endl; 3024 for(list<BoundaryTriangleSet*>::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) 3025 Log() << Verbose(2) << **Runner << endl; 3026 3027 delete(connectedClosestPoints); 3028 } else { 3029 triangles = NULL; 3030 eLog() << Verbose(2) << "There is no circle of connected points!" << endl; 3031 } 3032 } 3033 3034 if ((triangles == NULL) || (triangles->empty())) { 3035 eLog() << Verbose(1) << "There is no nearest triangle. Please check the tesselation structure."; 3036 delete(triangles); 3037 return NULL; 3038 } else 3039 return triangles; 3306 TriangleList * candidates = new TriangleList; 3307 for (LineSet::iterator LineRunner = ClosestLines.begin(); LineRunner != ClosestLines.end(); LineRunner++) 3308 for (TriangleMap::iterator Runner = (*LineRunner)->triangles.begin(); Runner != (*LineRunner)->triangles.end(); Runner++) { 3309 candidates->push_back(Runner->second); 3310 } 3311 return candidates; 3040 3312 }; 3041 3313 … … 3046 3318 * \return list of BoundaryTriangleSet of nearest triangles or NULL. 3047 3319 */ 3048 class BoundaryTriangleSet * Tesselation::FindClosestTriangleTo Point(const Vector *x, const LinkedCell* LC) const3320 class BoundaryTriangleSet * Tesselation::FindClosestTriangleToVector(const Vector *x, const LinkedCell* LC) const 3049 3321 { 3050 3322 Info FunctionInfo(__func__); 3051 3323 class BoundaryTriangleSet *result = NULL; 3052 list<BoundaryTriangleSet*> *triangles = FindClosestTrianglesToPoint(x, LC); 3324 TriangleList *triangles = FindClosestTrianglesToVector(x, LC); 3325 TriangleList candidates; 3053 3326 Vector Center; 3054 3055 if (triangles == NULL) 3327 Vector helper; 3328 3329 if ((triangles == NULL) || (triangles->empty())) 3056 3330 return NULL; 3057 3331 3058 if (triangles->size() == 1) { // there is no degenerate case 3059 result = triangles->front(); 3060 Log() << Verbose(1) << "Normal Vector of this triangle is " << result->NormalVector << "." << endl; 3061 } else { 3062 result = triangles->front(); 3063 result->GetCenter(&Center); 3064 Center.SubtractVector(x); 3065 Log() << Verbose(1) << "Normal Vector of this front side is " << result->NormalVector << "." << endl; 3066 if (Center.ScalarProduct(&result->NormalVector) < 0) { 3067 result = triangles->back(); 3068 Log() << Verbose(1) << "Normal Vector of this back side is " << result->NormalVector << "." << endl; 3069 if (Center.ScalarProduct(&result->NormalVector) < 0) { 3070 eLog() << Verbose(1) << "Front and back side yield NormalVector in wrong direction!" << endl; 3071 } 3332 // go through all and pick the one with the best alignment to x 3333 double MinAlignment = 2.*M_PI; 3334 for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) { 3335 (*Runner)->GetCenter(&Center); 3336 helper.CopyVector(x); 3337 helper.SubtractVector(&Center); 3338 const double Alignment = helper.Angle(&(*Runner)->NormalVector); 3339 if (Alignment < MinAlignment) { 3340 result = *Runner; 3341 MinAlignment = Alignment; 3342 Log() << Verbose(1) << "ACCEPT: Triangle " << *result << " is better aligned with " << MinAlignment << "." << endl; 3343 } else { 3344 Log() << Verbose(1) << "REJECT: Triangle " << *result << " is worse aligned with " << MinAlignment << "." << endl; 3072 3345 } 3073 3346 } 3074 3347 delete(triangles); 3348 3075 3349 return result; 3076 3350 }; 3077 3351 3078 /** Checks whether the provided Vector is within the tesselation structure. 3352 /** Checks whether the provided Vector is within the Tesselation structure. 3353 * Basically calls Tesselation::GetDistanceToSurface() and checks the sign of the return value. 3354 * @param point of which to check the position 3355 * @param *LC LinkedCell structure 3356 * 3357 * @return true if the point is inside the Tesselation structure, false otherwise 3358 */ 3359 bool Tesselation::IsInnerPoint(const Vector &Point, const LinkedCell* const LC) const 3360 { 3361 return (GetDistanceSquaredToSurface(Point, LC) < MYEPSILON); 3362 } 3363 3364 /** Returns the distance to the surface given by the tesselation. 3365 * Calls FindClosestTriangleToVector() and checks whether the resulting triangle's BoundaryTriangleSet#NormalVector points 3366 * towards or away from the given \a &Point. Additionally, we check whether it's normal to the normal vector, i.e. on the 3367 * closest triangle's plane. Then, we have to check whether \a Point is inside the triangle or not to determine whether it's 3368 * an inside or outside point. This is done by calling BoundaryTriangleSet::GetIntersectionInsideTriangle(). 3369 * In the end we additionally find the point on the triangle who was smallest distance to \a Point: 3370 * -# Separate distance from point to center in vector in NormalDirection and on the triangle plane. 3371 * -# Check whether vector on triangle plane points inside the triangle or crosses triangle bounds. 3372 * -# If inside, take it to calculate closest distance 3373 * -# If not, take intersection with BoundaryLine as distance 3374 * 3375 * @note distance is squared despite it still contains a sign to determine in-/outside! 3079 3376 * 3080 3377 * @param point of which to check the position 3081 3378 * @param *LC LinkedCell structure 3082 3379 * 3083 * @return true if the point is inside the tesselation structure, false otherwise3084 */ 3085 bool Tesselation::IsInnerPoint(const Vector &Point, const LinkedCell* const LC) const3086 { 3087 Info FunctionInfo(__func__);3088 class BoundaryTriangleSet *result = FindClosestTriangleTo Point(&Point, LC);3380 * @return >0 if outside, ==0 if on surface, <0 if inside (Note that distance can be at most LinkedCell::RADIUS.) 3381 */ 3382 double Tesselation::GetDistanceSquaredToSurface(const Vector &Point, const LinkedCell* const LC) const 3383 { 3384 Info FunctionInfo(__func__); 3385 class BoundaryTriangleSet *result = FindClosestTriangleToVector(&Point, LC); 3089 3386 Vector Center; 3387 Vector helper; 3388 Vector DistanceToCenter; 3389 Vector Intersection; 3390 double distance = 0.; 3090 3391 3091 3392 if (result == NULL) {// is boundary point or only point in point cloud? 3092 3393 Log() << Verbose(1) << Point << " is the only point in vicinity." << endl; 3093 return false; 3394 return LC->RADIUS; 3395 } else { 3396 Log() << Verbose(1) << "INFO: Closest triangle found is " << *result << " with normal vector " << result->NormalVector << "." << endl; 3094 3397 } 3095 3398 3096 3399 result->GetCenter(&Center); 3097 3400 Log() << Verbose(2) << "INFO: Central point of the triangle is " << Center << "." << endl; 3098 Center.SubtractVector(&Point); 3099 Log() << Verbose(2) << "INFO: Vector from center to point to test is " << Center << "." << endl; 3100 if (Center.ScalarProduct(&result->NormalVector) > -MYEPSILON) { 3101 Log() << Verbose(1) << Point << " is an inner point." << endl; 3102 return true; 3401 DistanceToCenter.CopyVector(&Center); 3402 DistanceToCenter.SubtractVector(&Point); 3403 Log() << Verbose(2) << "INFO: Vector from point to test to center is " << DistanceToCenter << "." << endl; 3404 3405 // check whether we are on boundary 3406 if (fabs(DistanceToCenter.ScalarProduct(&result->NormalVector)) < MYEPSILON) { 3407 // calculate whether inside of triangle 3408 DistanceToCenter.CopyVector(&Point); 3409 Center.CopyVector(&Point); 3410 Center.SubtractVector(&result->NormalVector); // points towards MolCenter 3411 DistanceToCenter.AddVector(&result->NormalVector); // points outside 3412 Log() << Verbose(1) << "INFO: Calling Intersection with " << Center << " and " << DistanceToCenter << "." << endl; 3413 if (result->GetIntersectionInsideTriangle(&Center, &DistanceToCenter, &Intersection)) { 3414 Log() << Verbose(1) << Point << " is inner point: sufficiently close to boundary, " << Intersection << "." << endl; 3415 return 0.; 3416 } else { 3417 Log() << Verbose(1) << Point << " is NOT an inner point: on triangle plane but outside of triangle bounds." << endl; 3418 return false; 3419 } 3103 3420 } else { 3104 Log() << Verbose(1) << Point << " is NOT an inner point." << endl; 3105 return false; 3106 } 3107 } 3108 3109 /** Checks whether the provided TesselPoint is within the tesselation structure. 3110 * 3111 * @param *Point of which to check the position 3112 * @param *LC Linked Cell structure 3113 * 3114 * @return true if the point is inside the tesselation structure, false otherwise 3115 */ 3116 bool Tesselation::IsInnerPoint(const TesselPoint * const Point, const LinkedCell* const LC) const 3117 { 3118 Info FunctionInfo(__func__); 3119 return IsInnerPoint(*(Point->node), LC); 3120 } 3421 // calculate smallest distance 3422 distance = result->GetClosestPointInsideTriangle(&Point, &Intersection); 3423 Log() << Verbose(1) << "Closest point on triangle is " << Intersection << "." << endl; 3424 distance = Min(distance, (LC->RADIUS*LC->RADIUS)); 3425 3426 // then check direction to boundary 3427 if (DistanceToCenter.ScalarProduct(&result->NormalVector) > MYEPSILON) { 3428 Log() << Verbose(1) << Point << " is an inner point, " << distance << " below surface." << endl; 3429 return -distance; 3430 } else { 3431 Log() << Verbose(1) << Point << " is NOT an inner point, " << distance << " above surface." << endl; 3432 return +distance; 3433 } 3434 } 3435 }; 3121 3436 3122 3437 /** Gets all points connected to the provided point by triangulation lines. … … 3126 3441 * @return set of the all points linked to the provided one 3127 3442 */ 3128 set<TesselPoint*>* Tesselation::GetAllConnectedPoints(const TesselPoint* const Point) const3129 { 3130 Info FunctionInfo(__func__); 3131 set<TesselPoint*> *connectedPoints = new set<TesselPoint*>;3443 TesselPointSet * Tesselation::GetAllConnectedPoints(const TesselPoint* const Point) const 3444 { 3445 Info FunctionInfo(__func__); 3446 TesselPointSet *connectedPoints = new TesselPointSet; 3132 3447 class BoundaryPointSet *ReferencePoint = NULL; 3133 3448 TesselPoint* current; … … 3170 3485 } 3171 3486 3172 if (connectedPoints-> size() == 0) { // if have not found any points3487 if (connectedPoints->empty()) { // if have not found any points 3173 3488 eLog() << Verbose(1) << "We have not found any connected points to " << *Point<< "." << endl; 3174 3489 return NULL; … … 3191 3506 * @return list of the all points linked to the provided one 3192 3507 */ 3193 list<TesselPoint*> * Tesselation::GetCircleOfSetOfPoints(set<TesselPoint*>*SetOfNeighbours, const TesselPoint* const Point, const Vector * const Reference) const3508 TesselPointList * Tesselation::GetCircleOfConnectedTriangles(TesselPointSet *SetOfNeighbours, const TesselPoint* const Point, const Vector * const Reference) const 3194 3509 { 3195 3510 Info FunctionInfo(__func__); 3196 3511 map<double, TesselPoint*> anglesOfPoints; 3197 list<TesselPoint*> *connectedCircle = new list<TesselPoint*>; 3198 Vector center; 3512 TesselPointList *connectedCircle = new TesselPointList; 3199 3513 Vector PlaneNormal; 3200 3514 Vector AngleZero; 3201 3515 Vector OrthogonalVector; 3202 3516 Vector helper; 3517 const TesselPoint * const TrianglePoints[3] = {Point, NULL, NULL}; 3518 TriangleList *triangles = NULL; 3203 3519 3204 3520 if (SetOfNeighbours == NULL) { … … 3209 3525 3210 3526 // calculate central point 3211 for (set<TesselPoint*>::const_iterator TesselRunner = SetOfNeighbours->begin(); TesselRunner != SetOfNeighbours->end(); TesselRunner++)3212 center.AddVector((*TesselRunner)->node);3213 //Log() << Verbose(0) << "Summed vectors " << center << "; number of points " << connectedPoints.size()3214 // << "; scale factor " << 1.0/connectedPoints.size();3215 center.Scale(1.0/SetOfNeighbours->size());3216 Log() << Verbose(1) << "INFO: Calculated center of all circle points is " << center<< "." << endl;3217 3218 // projection plane of the circle is at the closes Point and normal is pointing away from center of all circle points3219 PlaneNormal. CopyVector(Point->node);3220 PlaneNormal.SubtractVector(¢er);3527 triangles = FindTriangles(TrianglePoints); 3528 if ((triangles != NULL) && (!triangles->empty())) { 3529 for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) 3530 PlaneNormal.AddVector(&(*Runner)->NormalVector); 3531 } else { 3532 eLog() << Verbose(0) << "Could not find any triangles for point " << *Point << "." << endl; 3533 performCriticalExit(); 3534 } 3535 PlaneNormal.Scale(1.0/triangles->size()); 3536 Log() << Verbose(1) << "INFO: Calculated PlaneNormal of all circle points is " << PlaneNormal << "." << endl; 3221 3537 PlaneNormal.Normalize(); 3222 Log() << Verbose(1) << "INFO: Calculated plane normal of circle is " << PlaneNormal << "." << endl;3223 3538 3224 3539 // construct one orthogonal vector … … 3246 3561 3247 3562 // go through all connected points and calculate angle 3248 for ( set<TesselPoint*>::iterator listRunner = SetOfNeighbours->begin(); listRunner != SetOfNeighbours->end(); listRunner++) {3563 for (TesselPointSet::iterator listRunner = SetOfNeighbours->begin(); listRunner != SetOfNeighbours->end(); listRunner++) { 3249 3564 helper.CopyVector((*listRunner)->node); 3250 3565 helper.SubtractVector(Point->node); … … 3262 3577 } 3263 3578 3579 /** Gets all points connected to the provided point by triangulation lines, ordered such that we have the circle round the point. 3580 * Maps them down onto the plane designated by the axis \a *Point and \a *Reference. The center of all points 3581 * connected in the tesselation to \a *Point is mapped to spherical coordinates with the zero angle being given 3582 * by the mapped down \a *Reference. Hence, the biggest and the smallest angles are those of the two shanks of the 3583 * triangle we are looking for. 3584 * 3585 * @param *SetOfNeighbours all points for which the angle should be calculated 3586 * @param *Point of which get all connected points 3587 * @param *Reference Reference vector for zero angle or NULL for no preference 3588 * @return list of the all points linked to the provided one 3589 */ 3590 TesselPointList * Tesselation::GetCircleOfSetOfPoints(TesselPointSet *SetOfNeighbours, const TesselPoint* const Point, const Vector * const Reference) const 3591 { 3592 Info FunctionInfo(__func__); 3593 map<double, TesselPoint*> anglesOfPoints; 3594 TesselPointList *connectedCircle = new TesselPointList; 3595 Vector center; 3596 Vector PlaneNormal; 3597 Vector AngleZero; 3598 Vector OrthogonalVector; 3599 Vector helper; 3600 3601 if (SetOfNeighbours == NULL) { 3602 eLog() << Verbose(2) << "Could not find any connected points!" << endl; 3603 delete(connectedCircle); 3604 return NULL; 3605 } 3606 3607 // check whether there's something to do 3608 if (SetOfNeighbours->size() < 3) { 3609 for (TesselPointSet::iterator TesselRunner = SetOfNeighbours->begin(); TesselRunner != SetOfNeighbours->end(); TesselRunner++) 3610 connectedCircle->push_back(*TesselRunner); 3611 return connectedCircle; 3612 } 3613 3614 Log() << Verbose(1) << "INFO: Point is " << *Point << " and Reference is " << *Reference << "." << endl; 3615 // calculate central point 3616 3617 TesselPointSet::const_iterator TesselA = SetOfNeighbours->begin(); 3618 TesselPointSet::const_iterator TesselB = SetOfNeighbours->begin(); 3619 TesselPointSet::const_iterator TesselC = SetOfNeighbours->begin(); 3620 TesselB++; 3621 TesselC++; 3622 TesselC++; 3623 int counter = 0; 3624 while (TesselC != SetOfNeighbours->end()) { 3625 helper.MakeNormalVector((*TesselA)->node, (*TesselB)->node, (*TesselC)->node); 3626 Log() << Verbose(0) << "Making normal vector out of " << *(*TesselA) << ", " << *(*TesselB) << " and " << *(*TesselC) << ":" << helper << endl; 3627 counter++; 3628 TesselA++; 3629 TesselB++; 3630 TesselC++; 3631 PlaneNormal.AddVector(&helper); 3632 } 3633 //Log() << Verbose(0) << "Summed vectors " << center << "; number of points " << connectedPoints.size() 3634 // << "; scale factor " << counter; 3635 PlaneNormal.Scale(1.0/(double)counter); 3636 // Log() << Verbose(1) << "INFO: Calculated center of all circle points is " << center << "." << endl; 3637 // 3638 // // projection plane of the circle is at the closes Point and normal is pointing away from center of all circle points 3639 // PlaneNormal.CopyVector(Point->node); 3640 // PlaneNormal.SubtractVector(¢er); 3641 // PlaneNormal.Normalize(); 3642 Log() << Verbose(1) << "INFO: Calculated plane normal of circle is " << PlaneNormal << "." << endl; 3643 3644 // construct one orthogonal vector 3645 if (Reference != NULL) { 3646 AngleZero.CopyVector(Reference); 3647 AngleZero.SubtractVector(Point->node); 3648 AngleZero.ProjectOntoPlane(&PlaneNormal); 3649 } 3650 if ((Reference == NULL) || (AngleZero.NormSquared() < MYEPSILON )) { 3651 Log() << Verbose(1) << "Using alternatively " << *(*SetOfNeighbours->begin())->node << " as angle 0 referencer." << endl; 3652 AngleZero.CopyVector((*SetOfNeighbours->begin())->node); 3653 AngleZero.SubtractVector(Point->node); 3654 AngleZero.ProjectOntoPlane(&PlaneNormal); 3655 if (AngleZero.NormSquared() < MYEPSILON) { 3656 eLog() << Verbose(0) << "CRITIAL: AngleZero is 0 even with alternative reference. The algorithm has to be changed here!" << endl; 3657 performCriticalExit(); 3658 } 3659 } 3660 Log() << Verbose(1) << "INFO: Reference vector on this plane representing angle 0 is " << AngleZero << "." << endl; 3661 if (AngleZero.NormSquared() > MYEPSILON) 3662 OrthogonalVector.MakeNormalVector(&PlaneNormal, &AngleZero); 3663 else 3664 OrthogonalVector.MakeNormalVector(&PlaneNormal); 3665 Log() << Verbose(1) << "INFO: OrthogonalVector on plane is " << OrthogonalVector << "." << endl; 3666 3667 // go through all connected points and calculate angle 3668 pair <map<double, TesselPoint*>::iterator, bool > InserterTest; 3669 for (TesselPointSet::iterator listRunner = SetOfNeighbours->begin(); listRunner != SetOfNeighbours->end(); listRunner++) { 3670 helper.CopyVector((*listRunner)->node); 3671 helper.SubtractVector(Point->node); 3672 helper.ProjectOntoPlane(&PlaneNormal); 3673 double angle = GetAngle(helper, AngleZero, OrthogonalVector); 3674 if (angle > M_PI) // the correction is of no use here (and not desired) 3675 angle = 2.*M_PI - angle; 3676 Log() << Verbose(0) << "INFO: Calculated angle between " << helper << " and " << AngleZero << " is " << angle << " for point " << **listRunner << "." << endl; 3677 InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner))); 3678 if (!InserterTest.second) { 3679 eLog() << Verbose(0) << "GetCircleOfSetOfPoints() got two atoms with same angle: " << *((InserterTest.first)->second) << " and " << (*listRunner) << endl; 3680 performCriticalExit(); 3681 } 3682 } 3683 3684 for(map<double, TesselPoint*>::iterator AngleRunner = anglesOfPoints.begin(); AngleRunner != anglesOfPoints.end(); AngleRunner++) { 3685 connectedCircle->push_back(AngleRunner->second); 3686 } 3687 3688 return connectedCircle; 3689 } 3690 3264 3691 /** Gets all points connected to the provided point by triangulation lines, ordered such that we walk along a closed path. 3265 3692 * … … 3268 3695 * @return list of the all points linked to the provided one 3269 3696 */ 3270 list< list<TesselPoint*>*> * Tesselation::GetPathsOfConnectedPoints(const TesselPoint* const Point) const3697 list< TesselPointList *> * Tesselation::GetPathsOfConnectedPoints(const TesselPoint* const Point) const 3271 3698 { 3272 3699 Info FunctionInfo(__func__); 3273 3700 map<double, TesselPoint*> anglesOfPoints; 3274 list< list<TesselPoint*> *> *ListOfPaths = new list<list<TesselPoint*>*>;3275 list<TesselPoint*>*connectedPath = NULL;3701 list< TesselPointList *> *ListOfPaths = new list< TesselPointList *>; 3702 TesselPointList *connectedPath = NULL; 3276 3703 Vector center; 3277 3704 Vector PlaneNormal; … … 3310 3737 } else if (!LineRunner->second) { 3311 3738 LineRunner->second = true; 3312 connectedPath = new list<TesselPoint*>;3739 connectedPath = new TesselPointList; 3313 3740 triangle = NULL; 3314 3741 CurrentLine = runner->second; … … 3384 3811 * @return list of the closed paths 3385 3812 */ 3386 list< list<TesselPoint*>*> * Tesselation::GetClosedPathsOfConnectedPoints(const TesselPoint* const Point) const3387 { 3388 Info FunctionInfo(__func__); 3389 list< list<TesselPoint*>*> *ListofPaths = GetPathsOfConnectedPoints(Point);3390 list< list<TesselPoint*> *> *ListofClosedPaths = new list<list<TesselPoint*>*>;3391 list<TesselPoint*>*connectedPath = NULL;3392 list<TesselPoint*>*newPath = NULL;3813 list<TesselPointList *> * Tesselation::GetClosedPathsOfConnectedPoints(const TesselPoint* const Point) const 3814 { 3815 Info FunctionInfo(__func__); 3816 list<TesselPointList *> *ListofPaths = GetPathsOfConnectedPoints(Point); 3817 list<TesselPointList *> *ListofClosedPaths = new list<TesselPointList *>; 3818 TesselPointList *connectedPath = NULL; 3819 TesselPointList *newPath = NULL; 3393 3820 int count = 0; 3394 3821 3395 3822 3396 list<TesselPoint*>::iterator CircleRunner;3397 list<TesselPoint*>::iterator CircleStart;3398 3399 for(list< list<TesselPoint*>*>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) {3823 TesselPointList::iterator CircleRunner; 3824 TesselPointList::iterator CircleStart; 3825 3826 for(list<TesselPointList *>::iterator ListRunner = ListofPaths->begin(); ListRunner != ListofPaths->end(); ListRunner++) { 3400 3827 connectedPath = *ListRunner; 3401 3828 … … 3406 3833 3407 3834 // go through list, look for reappearance of starting Point and create list 3408 list<TesselPoint*>::iterator Marker = CircleStart;3835 TesselPointList::iterator Marker = CircleStart; 3409 3836 for (CircleRunner = CircleStart; CircleRunner != connectedPath->end(); CircleRunner++) { 3410 3837 if ((*CircleRunner == *CircleStart) && (CircleRunner != CircleStart)) { // is not the very first point 3411 3838 // we have a closed circle from Marker to new Marker 3412 3839 Log() << Verbose(1) << count+1 << ". closed path consists of: "; 3413 newPath = new list<TesselPoint*>;3414 list<TesselPoint*>::iterator CircleSprinter = Marker;3840 newPath = new TesselPointList; 3841 TesselPointList::iterator CircleSprinter = Marker; 3415 3842 for (; CircleSprinter != CircleRunner; CircleSprinter++) { 3416 3843 newPath->push_back(*CircleSprinter); … … 3446 3873 * \return pointer to allocated list of triangles 3447 3874 */ 3448 set<BoundaryTriangleSet*>*Tesselation::GetAllTriangles(const BoundaryPointSet * const Point) const3449 { 3450 Info FunctionInfo(__func__); 3451 set<BoundaryTriangleSet*> *connectedTriangles = new set<BoundaryTriangleSet*>;3875 TriangleSet *Tesselation::GetAllTriangles(const BoundaryPointSet * const Point) const 3876 { 3877 Info FunctionInfo(__func__); 3878 TriangleSet *connectedTriangles = new TriangleSet; 3452 3879 3453 3880 if (Point == NULL) { … … 3498 3925 } 3499 3926 3500 list< list<TesselPoint*>*> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node);3501 list<TesselPoint*>*connectedPath = NULL;3927 list<TesselPointList *> *ListOfClosedPaths = GetClosedPathsOfConnectedPoints(point->node); 3928 TesselPointList *connectedPath = NULL; 3502 3929 3503 3930 // gather all triangles 3504 3931 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) 3505 3932 count+=LineRunner->second->triangles.size(); 3506 map<class BoundaryTriangleSet *, int>Candidates;3933 TriangleMap Candidates; 3507 3934 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { 3508 3935 line = LineRunner->second; 3509 3936 for (TriangleMap::iterator TriangleRunner = line->triangles.begin(); TriangleRunner != line->triangles.end(); TriangleRunner++) { 3510 3937 triangle = TriangleRunner->second; 3511 Candidates.insert( pair<class BoundaryTriangleSet *, int> (triangle, triangle->Nr) );3938 Candidates.insert( TrianglePair (triangle->Nr, triangle) ); 3512 3939 } 3513 3940 } … … 3516 3943 count=0; 3517 3944 NormalVector.Zero(); 3518 for ( map<class BoundaryTriangleSet *, int>::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) {3519 Log() << Verbose(1) << "INFO: Removing triangle " << *(Runner-> first) << "." << endl;3520 NormalVector.SubtractVector(&Runner-> first->NormalVector); // has to point inward3521 RemoveTesselationTriangle(Runner-> first);3945 for (TriangleMap::iterator Runner = Candidates.begin(); Runner != Candidates.end(); Runner++) { 3946 Log() << Verbose(1) << "INFO: Removing triangle " << *(Runner->second) << "." << endl; 3947 NormalVector.SubtractVector(&Runner->second->NormalVector); // has to point inward 3948 RemoveTesselationTriangle(Runner->second); 3522 3949 count++; 3523 3950 } 3524 3951 Log() << Verbose(1) << count << " triangles were removed." << endl; 3525 3952 3526 list< list<TesselPoint*>*>::iterator ListAdvance = ListOfClosedPaths->begin();3527 list< list<TesselPoint*>*>::iterator ListRunner = ListAdvance;3528 map<class BoundaryTriangleSet *, int>::iterator NumberRunner = Candidates.begin();3529 list<TesselPoint*>::iterator StartNode, MiddleNode, EndNode;3953 list<TesselPointList *>::iterator ListAdvance = ListOfClosedPaths->begin(); 3954 list<TesselPointList *>::iterator ListRunner = ListAdvance; 3955 TriangleMap::iterator NumberRunner = Candidates.begin(); 3956 TesselPointList::iterator StartNode, MiddleNode, EndNode; 3530 3957 double angle; 3531 3958 double smallestangle; … … 3541 3968 3542 3969 // re-create all triangles by going through connected points list 3543 list<class BoundaryLineSet *>NewLines;3970 LineList NewLines; 3544 3971 for (;!connectedPath->empty();) { 3545 3972 // search middle node with widest angle to next neighbours … … 3647 4074 // maximize the inner lines (we preferentially created lines with a huge angle, which is for the tesselation not wanted though useful for the closing) 3648 4075 if (NewLines.size() > 1) { 3649 list<class BoundaryLineSet *>::iterator Candidate;4076 LineList::iterator Candidate; 3650 4077 class BoundaryLineSet *OtherBase = NULL; 3651 4078 double tmp, maxgain; 3652 4079 do { 3653 4080 maxgain = 0; 3654 for( list<class BoundaryLineSet *>::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) {4081 for(LineList::iterator Runner = NewLines.begin(); Runner != NewLines.end(); Runner++) { 3655 4082 tmp = PickFarthestofTwoBaselines(*Runner); 3656 4083 if (maxgain < tmp) { … … 3694 4121 * Finds triangles belonging to the three provided points. 3695 4122 * 3696 * @param *Points[3] list, is expected to contain three points 4123 * @param *Points[3] list, is expected to contain three points (NULL means wildcard) 3697 4124 * 3698 4125 * @return triangles which belong to the provided points, will be empty if there are none, 3699 4126 * will usually be one, in case of degeneration, there will be two 3700 4127 */ 3701 list<BoundaryTriangleSet*>*Tesselation::FindTriangles(const TesselPoint* const Points[3]) const3702 { 3703 Info FunctionInfo(__func__); 3704 list<BoundaryTriangleSet*> *result = new list<BoundaryTriangleSet*>;4128 TriangleList *Tesselation::FindTriangles(const TesselPoint* const Points[3]) const 4129 { 4130 Info FunctionInfo(__func__); 4131 TriangleList *result = new TriangleList; 3705 4132 LineMap::const_iterator FindLine; 3706 4133 TriangleMap::const_iterator FindTriangle; 3707 4134 class BoundaryPointSet *TrianglePoints[3]; 4135 size_t NoOfWildcards = 0; 3708 4136 3709 4137 for (int i = 0; i < 3; i++) { 3710 PointMap::const_iterator FindPoint = PointsOnBoundary.find(Points[i]->nr);3711 if (FindPoint != PointsOnBoundary.end()) {3712 TrianglePoints[i] = FindPoint->second;4138 if (Points[i] == NULL) { 4139 NoOfWildcards++; 4140 TrianglePoints[i] = NULL; 3713 4141 } else { 3714 TrianglePoints[i] = NULL; 3715 } 3716 } 3717 3718 // checks lines between the points in the Points for their adjacent triangles 3719 for (int i = 0; i < 3; i++) { 3720 if (TrianglePoints[i] != NULL) { 3721 for (int j = i+1; j < 3; j++) { 3722 if (TrianglePoints[j] != NULL) { 3723 for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr); // is a multimap! 3724 (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->nr); 3725 FindLine++) { 3726 for (FindTriangle = FindLine->second->triangles.begin(); 3727 FindTriangle != FindLine->second->triangles.end(); 3728 FindTriangle++) { 3729 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 3730 result->push_back(FindTriangle->second); 4142 PointMap::const_iterator FindPoint = PointsOnBoundary.find(Points[i]->nr); 4143 if (FindPoint != PointsOnBoundary.end()) { 4144 TrianglePoints[i] = FindPoint->second; 4145 } else { 4146 TrianglePoints[i] = NULL; 4147 } 4148 } 4149 } 4150 4151 switch (NoOfWildcards) { 4152 case 0: // checks lines between the points in the Points for their adjacent triangles 4153 for (int i = 0; i < 3; i++) { 4154 if (TrianglePoints[i] != NULL) { 4155 for (int j = i+1; j < 3; j++) { 4156 if (TrianglePoints[j] != NULL) { 4157 for (FindLine = TrianglePoints[i]->lines.find(TrianglePoints[j]->node->nr); // is a multimap! 4158 (FindLine != TrianglePoints[i]->lines.end()) && (FindLine->first == TrianglePoints[j]->node->nr); 4159 FindLine++) { 4160 for (FindTriangle = FindLine->second->triangles.begin(); 4161 FindTriangle != FindLine->second->triangles.end(); 4162 FindTriangle++) { 4163 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 4164 result->push_back(FindTriangle->second); 4165 } 4166 } 3731 4167 } 4168 // Is it sufficient to consider one of the triangle lines for this. 4169 return result; 3732 4170 } 3733 4171 } 3734 // Is it sufficient to consider one of the triangle lines for this.3735 return result;3736 4172 } 3737 4173 } 3738 } 4174 break; 4175 case 1: // copy all triangles of the respective line 4176 { 4177 int i=0; 4178 for (; i < 3; i++) 4179 if (TrianglePoints[i] == NULL) 4180 break; 4181 for (FindLine = TrianglePoints[(i+1)%3]->lines.find(TrianglePoints[(i+2)%3]->node->nr); // is a multimap! 4182 (FindLine != TrianglePoints[(i+1)%3]->lines.end()) && (FindLine->first == TrianglePoints[(i+2)%3]->node->nr); 4183 FindLine++) { 4184 for (FindTriangle = FindLine->second->triangles.begin(); 4185 FindTriangle != FindLine->second->triangles.end(); 4186 FindTriangle++) { 4187 if (FindTriangle->second->IsPresentTupel(TrianglePoints)) { 4188 result->push_back(FindTriangle->second); 4189 } 4190 } 4191 } 4192 break; 4193 } 4194 case 2: // copy all triangles of the respective point 4195 { 4196 int i=0; 4197 for (; i < 3; i++) 4198 if (TrianglePoints[i] != NULL) 4199 break; 4200 for (LineMap::const_iterator line = TrianglePoints[i]->lines.begin(); line != TrianglePoints[i]->lines.end(); line++) 4201 for (TriangleMap::const_iterator triangle = line->second->triangles.begin(); triangle != line->second->triangles.end(); triangle++) 4202 result->push_back(triangle->second); 4203 result->sort(); 4204 result->unique(); 4205 break; 4206 } 4207 case 3: // copy all triangles 4208 { 4209 for (TriangleMap::const_iterator triangle = TrianglesOnBoundary.begin(); triangle != TrianglesOnBoundary.end(); triangle++) 4210 result->push_back(triangle->second); 4211 break; 4212 } 4213 default: 4214 eLog() << Verbose(0) << "Number of wildcards is greater than 3, cannot happen!" << endl; 4215 performCriticalExit(); 4216 break; 3739 4217 } 3740 4218 … … 3779 4257 * in the list, once as key and once as value 3780 4258 */ 3781 map<int, int>* Tesselation::FindAllDegeneratedLines()4259 IndexToIndex * Tesselation::FindAllDegeneratedLines() 3782 4260 { 3783 4261 Info FunctionInfo(__func__); 3784 4262 UniqueLines AllLines; 3785 map<int, int> * DegeneratedLines = new map<int, int>;4263 IndexToIndex * DegeneratedLines = new IndexToIndex; 3786 4264 3787 4265 // sanity check … … 3804 4282 3805 4283 Log() << Verbose(0) << "FindAllDegeneratedLines() found " << DegeneratedLines->size() << " lines." << endl; 3806 map<int,int>::iterator it;4284 IndexToIndex::iterator it; 3807 4285 for (it = DegeneratedLines->begin(); it != DegeneratedLines->end(); it++) { 3808 4286 const LineMap::const_iterator Line1 = LinesOnBoundary.find((*it).first); … … 3823 4301 * in the list, once as key and once as value 3824 4302 */ 3825 map<int, int>* Tesselation::FindAllDegeneratedTriangles()3826 { 3827 Info FunctionInfo(__func__); 3828 map<int, int>* DegeneratedLines = FindAllDegeneratedLines();3829 map<int, int> * DegeneratedTriangles = new map<int, int>;4303 IndexToIndex * Tesselation::FindAllDegeneratedTriangles() 4304 { 4305 Info FunctionInfo(__func__); 4306 IndexToIndex * DegeneratedLines = FindAllDegeneratedLines(); 4307 IndexToIndex * DegeneratedTriangles = new IndexToIndex; 3830 4308 3831 4309 TriangleMap::iterator TriangleRunner1, TriangleRunner2; … … 3833 4311 class BoundaryLineSet *line1 = NULL, *line2 = NULL; 3834 4312 3835 for ( map<int, int>::iterator LineRunner = DegeneratedLines->begin(); LineRunner != DegeneratedLines->end(); ++LineRunner) {4313 for (IndexToIndex::iterator LineRunner = DegeneratedLines->begin(); LineRunner != DegeneratedLines->end(); ++LineRunner) { 3836 4314 // run over both lines' triangles 3837 4315 Liner = LinesOnBoundary.find(LineRunner->first); … … 3854 4332 3855 4333 Log() << Verbose(0) << "FindAllDegeneratedTriangles() found " << DegeneratedTriangles->size() << " triangles:" << endl; 3856 map<int,int>::iterator it;4334 IndexToIndex::iterator it; 3857 4335 for (it = DegeneratedTriangles->begin(); it != DegeneratedTriangles->end(); it++) 3858 4336 Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl; … … 3868 4346 { 3869 4347 Info FunctionInfo(__func__); 3870 map<int, int>* DegeneratedTriangles = FindAllDegeneratedTriangles();4348 IndexToIndex * DegeneratedTriangles = FindAllDegeneratedTriangles(); 3871 4349 TriangleMap::iterator finder; 3872 4350 BoundaryTriangleSet *triangle = NULL, *partnerTriangle = NULL; 3873 4351 int count = 0; 3874 4352 3875 for ( map<int, int>::iterator TriangleKeyRunner = DegeneratedTriangles->begin();4353 for (IndexToIndex::iterator TriangleKeyRunner = DegeneratedTriangles->begin(); 3876 4354 TriangleKeyRunner != DegeneratedTriangles->end(); ++TriangleKeyRunner 3877 4355 ) { … … 3961 4439 // find nearest boundary point 3962 4440 class TesselPoint *BackupPoint = NULL; 3963 class TesselPoint *NearestPoint = FindClosest Point(point->node, BackupPoint, LC);4441 class TesselPoint *NearestPoint = FindClosestTesselPoint(point->node, BackupPoint, LC); 3964 4442 class BoundaryPointSet *NearestBoundaryPoint = NULL; 3965 4443 PointMap::iterator PointRunner; … … 4128 4606 4129 4607 /// 2. Go through all BoundaryPointSet's, check their triangles' NormalVector 4608 IndexToIndex *DegeneratedTriangles = FindAllDegeneratedTriangles(); 4130 4609 set < BoundaryPointSet *> EndpointCandidateList; 4131 4610 pair < set < BoundaryPointSet *>::iterator, bool > InsertionTester; … … 4138 4617 for (LineMap::const_iterator LineRunner = (Runner->second)->lines.begin(); LineRunner != (Runner->second)->lines.end(); LineRunner++) 4139 4618 for (TriangleMap::const_iterator TriangleRunner = (LineRunner->second)->triangles.begin(); TriangleRunner != (LineRunner->second)->triangles.end(); TriangleRunner++) { 4140 TriangleInsertionTester = TriangleVectors.insert( pair< int, Vector *> ((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector)) ); 4141 if (TriangleInsertionTester.second) 4142 Log() << Verbose(1) << " Adding triangle " << *(TriangleRunner->second) << " to triangles to check-list." << endl; 4619 if (DegeneratedTriangles->find(TriangleRunner->second->Nr) == DegeneratedTriangles->end()) { 4620 TriangleInsertionTester = TriangleVectors.insert( pair< int, Vector *> ((TriangleRunner->second)->Nr, &((TriangleRunner->second)->NormalVector)) ); 4621 if (TriangleInsertionTester.second) 4622 Log() << Verbose(1) << " Adding triangle " << *(TriangleRunner->second) << " to triangles to check-list." << endl; 4623 } else { 4624 Log() << Verbose(1) << " NOT adding triangle " << *(TriangleRunner->second) << " as it's a simply degenerated one." << endl; 4625 } 4143 4626 } 4144 4627 // check whether there are two that are parallel … … 4213 4696 /// 4a. Gather all triangles of this polygon 4214 4697 TriangleSet *T = (*PolygonRunner)->GetAllContainedTrianglesFromEndpoints(); 4698 4699 // check whether number is bigger than 2, otherwise it's just a simply degenerated one and nothing to do. 4700 if (T->size() == 2) { 4701 Log() << Verbose(1) << " Skipping degenerated polygon, is just a (already simply degenerated) triangle." << endl; 4702 delete(T); 4703 continue; 4704 } 4705 4706 // check whether number is even 4707 // If this case occurs, we have to think about it! 4708 // The Problem is probably due to two degenerated polygons being connected by a bridging, non-degenerated polygon, as somehow one node has 4709 // connections to either polygon ... 4710 if (T->size() % 2 != 0) { 4711 eLog() << Verbose(0) << " degenerated polygon contains an odd number of triangles, probably contains bridging non-degenerated ones, too!" << endl; 4712 performCriticalExit(); 4713 } 4215 4714 4216 4715 TriangleSet::iterator TriangleWalker = T->begin(); // is the inner iterator … … 4259 4758 } 4260 4759 4261 map<int, int>* SimplyDegeneratedTriangles = FindAllDegeneratedTriangles();4760 IndexToIndex * SimplyDegeneratedTriangles = FindAllDegeneratedTriangles(); 4262 4761 Log() << Verbose(0) << "Final list of simply degenerated triangles found, containing " << SimplyDegeneratedTriangles->size() << " triangles:" << endl; 4263 map<int,int>::iterator it;4762 IndexToIndex::iterator it; 4264 4763 for (it = SimplyDegeneratedTriangles->begin(); it != SimplyDegeneratedTriangles->end(); it++) 4265 4764 Log() << Verbose(0) << (*it).first << " => " << (*it).second << endl;
Note:
See TracChangeset
for help on using the changeset viewer.
