Changeset a1acc5 for molecuilder/src/tesselation.cpp
- Timestamp:
- Jan 8, 2010, 2:04:22 PM (16 years ago)
- Children:
- 22b47e
- Parents:
- eda56a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
molecuilder/src/tesselation.cpp
reda56a ra1acc5 388 388 }; 389 389 390 /** Finds the point on the triangle \a *BTS th e line defined by \a *MolCenter and \a *x crosses through.390 /** Finds the point on the triangle \a *BTS through which the line defined by \a *MolCenter and \a *x crosses. 391 391 * We call Vector::GetIntersectionWithPlane() to receive the intersection point with the plane 392 392 * This we test if it's really on the plane and whether it's inside the triangle on the plane or not. … … 411 411 } 412 412 413 Log() << Verbose(1) << "INFO: Triangle is " << *this << "." << endl; 414 Log() << Verbose(1) << "INFO: Line is from " << *MolCenter << " to " << *x << "." << endl; 415 Log() << Verbose(1) << "INFO: Intersection is " << *Intersection << "." << endl; 416 413 417 // Calculate cross point between one baseline and the line from the third endpoint to intersection 414 418 int i=0; 415 419 do { 416 420 if (CrossPoint.GetIntersectionOfTwoLinesOnPlane(endpoints[i%3]->node->node, endpoints[(i+1)%3]->node->node, endpoints[(i+2)%3]->node->node, Intersection, &NormalVector)) { 421 CrossPoint.SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector 417 422 helper.CopyVector(endpoints[(i+1)%3]->node->node); 418 423 helper.SubtractVector(endpoints[i%3]->node->node); 424 break; 419 425 } else 420 426 i++; 421 if (i>2) 422 break; 423 } while (CrossPoint.NormSquared() < MYEPSILON); 427 } while (i<3); 424 428 if (i==3) { 425 429 eLog() << Verbose(0) << "Could not find any cross points, something's utterly wrong here!" << endl; 426 430 } 427 CrossPoint.SubtractVector(endpoints[i%3]->node->node); // cross point was returned as absolute vector431 Log() << Verbose(1) << "INFO: Crosspoint is " << CrossPoint << "." << endl; 428 432 429 433 // check whether intersection is inside or not by comparing length of intersection and length of cross point … … 2987 2991 * \return map of BoundaryPointSet of closest points sorted by squared distance or NULL. 2988 2992 */ 2989 Distance Map * Tesselation::FindClosestBoundaryPointsToVector(const Vector *x, const LinkedCell* LC) const2993 DistanceToPointMap * Tesselation::FindClosestBoundaryPointsToVector(const Vector *x, const LinkedCell* LC) const 2990 2994 { 2991 2995 Info FunctionInfo(__func__); … … 3004 3008 Log() << Verbose(1) << "INFO: Center cell is " << N[0] << ", " << N[1] << ", " << N[2] << " with No. " << LC->index << "." << endl; 3005 3009 3006 Distance Map * points = new DistanceMap;3010 DistanceToPointMap * points = new DistanceToPointMap; 3007 3011 LC->GetNeighbourBounds(Nlower, Nupper); 3008 3012 //Log() << Verbose(1) << endl; … … 3015 3019 for (LinkedNodes::const_iterator Runner = List->begin(); Runner != List->end(); Runner++) { 3016 3020 FindPoint = PointsOnBoundary.find((*Runner)->nr); 3017 if (FindPoint != PointsOnBoundary.end()) 3018 points->insert(DistancePair (FindPoint->second->node->node->DistanceSquared(x), FindPoint->second) ); 3021 if (FindPoint != PointsOnBoundary.end()) { 3022 points->insert(DistanceToPointPair (FindPoint->second->node->node->DistanceSquared(x), FindPoint->second) ); 3023 Log() << Verbose(1) << "INFO: Putting " << *FindPoint->second << " into the list." << endl; 3024 } 3019 3025 } 3020 3026 } else { … … 3042 3048 3043 3049 // get closest points 3044 Distance Map * points = FindClosestBoundaryPointsToVector(x,LC);3050 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x,LC); 3045 3051 if (points == NULL) { 3046 3052 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl; … … 3055 3061 Vector Center; 3056 3062 Vector BaseLine; 3057 for (Distance Map::iterator Runner = points->begin(); Runner != points->end(); Runner++) {3063 for (DistanceToPointMap::iterator Runner = points->begin(); Runner != points->end(); Runner++) { 3058 3064 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 3059 3065 // calculate closest point on line to desired point … … 3109 3115 3110 3116 // get closest points 3111 Distance Map * points = FindClosestBoundaryPointsToVector(x,LC);3117 DistanceToPointMap * points = FindClosestBoundaryPointsToVector(x,LC); 3112 3118 if (points == NULL) { 3113 3119 eLog() << Verbose(1) << "There is no nearest point: too far away from the surface." << endl; … … 3118 3124 Log() << Verbose(1) << "Finding closest BoundaryTriangle to " << *x << " ... " << endl; 3119 3125 BoundaryLineSet *ClosestLine = NULL; 3120 double MinDistance = -1.;3121 Vector helper;3126 double MinDistance = 1e+16; 3127 Vector BaseLineIntersection; 3122 3128 Vector Center; 3123 3129 Vector BaseLine; 3124 for (DistanceMap::iterator Runner = points->begin(); Runner != points->end(); Runner++) { 3130 Vector BaseLineCenter; 3131 for (DistanceToPointMap::iterator Runner = points->begin(); Runner != points->end(); Runner++) { 3125 3132 for (LineMap::iterator LineRunner = Runner->second->lines.begin(); LineRunner != Runner->second->lines.end(); LineRunner++) { 3126 for (TriangleMap::iterator TriangleRunner = LineRunner->second->triangles.begin(); TriangleRunner != LineRunner->second->triangles.end(); TriangleRunner++) { 3133 3134 BaseLine.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3135 BaseLine.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3136 const double lengthBase = BaseLine.NormSquared(); 3137 3138 BaseLineIntersection.CopyVector(x); 3139 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[0]->node->node); 3140 const double lengthEndA = BaseLineIntersection.NormSquared(); 3141 3142 BaseLineIntersection.CopyVector(x); 3143 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3144 const double lengthEndB = BaseLineIntersection.NormSquared(); 3145 3146 if ((lengthEndA > lengthBase) || (lengthEndB > lengthBase) || ((lengthEndA < MYEPSILON) || (lengthEndB < MYEPSILON))) { // intersection would be outside, take closer endpoint 3147 if ((lengthEndA < MinDistance) && (lengthEndA < lengthEndB)) { 3148 ClosestLine = LineRunner->second; 3149 MinDistance = lengthEndA; 3150 Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[0]->node << " is closer with " << lengthEndA << "." << endl; 3151 } else if (lengthEndB < MinDistance) { 3152 ClosestLine = LineRunner->second; 3153 MinDistance = lengthEndB; 3154 Log() << Verbose(1) << "ACCEPT: Line " << *LineRunner->second << " to endpoint " << *LineRunner->second->endpoints[1]->node << " is closer with " << lengthEndB << "." << endl; 3155 } else { 3156 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; 3157 } 3158 } else { // intersection is closer, calculate 3127 3159 // calculate closest point on line to desired point 3128 helper.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3129 helper.AddVector((LineRunner->second)->endpoints[1]->node->node); 3130 helper.Scale(0.5); 3131 Center.CopyVector(x); 3132 Center.SubtractVector(&helper); 3133 BaseLine.CopyVector((LineRunner->second)->endpoints[0]->node->node); 3134 BaseLine.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3160 BaseLineIntersection.CopyVector(x); 3161 BaseLineIntersection.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3162 Center.CopyVector(&BaseLineIntersection); 3135 3163 Center.ProjectOntoPlane(&BaseLine); 3136 const double distance = Center.NormSquared(); 3164 BaseLineIntersection.SubtractVector(&Center); 3165 const double distance = BaseLineIntersection.NormSquared(); 3166 if (Center.NormSquared() > BaseLine.NormSquared()) { 3167 eLog() << Verbose(0) << "Algorithmic error: In second case we have intersection outside of baseline!" << endl; 3168 } 3137 3169 if ((ClosestLine == NULL) || (distance < MinDistance)) { 3138 // additionally calculate intersection on line (whether it's on the line section or not) 3139 helper.CopyVector(x); 3140 helper.SubtractVector((LineRunner->second)->endpoints[0]->node->node); 3141 helper.SubtractVector(&Center); 3142 const double lengthA = helper.ScalarProduct(&BaseLine); 3143 helper.CopyVector(x); 3144 helper.SubtractVector((LineRunner->second)->endpoints[1]->node->node); 3145 helper.SubtractVector(&Center); 3146 const double lengthB = helper.ScalarProduct(&BaseLine); 3147 if (lengthB*lengthA < 0) { // if have different sign 3148 ClosestLine = LineRunner->second; 3149 MinDistance = distance; 3150 Log() << Verbose(1) << "ACCEPT: New closest line is " << *ClosestLine << " with projected distance " << MinDistance << "." << endl; 3151 } else { 3152 Log() << Verbose(1) << "REJECT: Intersection is outside of the line section: " << lengthA << " and " << lengthB << "." << endl; 3153 } 3170 ClosestLine = LineRunner->second; 3171 MinDistance = distance; 3172 Log() << Verbose(1) << "ACCEPT: Intersection in between endpoints, new closest line " << *LineRunner->second << " is " << *ClosestLine << " with projected distance " << MinDistance << "." << endl; 3154 3173 } else { 3155 Log() << Verbose( 1) << "REJECT: Point is too further away than present line: " << distance << " >> " << MinDistance << "." << endl;3174 Log() << Verbose(2) << "REJECT: Point is further away from line " << *LineRunner->second << " than present closest line: " << distance << " >> " << MinDistance << "." << endl; 3156 3175 } 3157 3176 } … … 3190 3209 return NULL; 3191 3210 3192 // reject all which are not closest3193 double Min Distance = -1.;3211 // go through all and pick the one with the best alignment to x 3212 double MinAlignment = 2.*M_PI; 3194 3213 for (TriangleList::iterator Runner = triangles->begin(); Runner != triangles->end(); Runner++) { 3195 3214 (*Runner)->GetCenter(&Center); 3196 3215 helper.CopyVector(x); 3197 3216 helper.SubtractVector(&Center); 3198 helper.ProjectOntoPlane(&(*Runner)->NormalVector); 3199 const double distance = helper.NormSquared(); 3200 if (fabs(distance - MinDistance) < MYEPSILON) { // degenerate case, keep both 3201 candidates.push_back(*Runner); 3202 } else if (distance < MinDistance) { 3203 candidates.clear(); 3204 candidates.push_back(*Runner); 3205 MinDistance = distance; 3217 const double Alignment = helper.Angle(&(*Runner)->NormalVector); 3218 if (Alignment < MinAlignment) { 3219 result = *Runner; 3220 MinAlignment = Alignment; 3221 Log() << Verbose(1) << "ACCEPT: Triangle " << *result << " is better aligned with " << MinAlignment << "." << endl; 3222 } else { 3223 Log() << Verbose(1) << "REJECT: Triangle " << *result << " is worse aligned with " << MinAlignment << "." << endl; 3206 3224 } 3207 3225 } 3208 3226 delete(triangles); 3209 if (!candidates.empty()) { 3210 if (candidates.size() == 1) { // there is no degenerate case 3211 result = candidates.front(); 3212 Log() << Verbose(1) << "Normal Vector of this triangle is " << result->NormalVector << "." << endl; 3213 } else { 3214 result = candidates.front(); 3215 result->GetCenter(&Center); 3216 Center.SubtractVector(x); 3217 Log() << Verbose(1) << "Normal Vector of this front side is " << result->NormalVector << "." << endl; 3218 if (Center.ScalarProduct(&result->NormalVector) < 0) { 3219 result = candidates.back(); 3220 Log() << Verbose(1) << "Normal Vector of this back side is " << result->NormalVector << "." << endl; 3221 if (Center.ScalarProduct(&result->NormalVector) < 0) { 3222 eLog() << Verbose(1) << "Front and back side yield NormalVector in wrong direction!" << endl; 3223 } 3224 } 3225 } 3226 } else { 3227 result = NULL; 3228 Log() << Verbose(0) << "No closest triangle found." << endl; 3229 } 3227 3230 3228 return result; 3231 3229 }; 3232 3230 3233 3231 /** Checks whether the provided Vector is within the tesselation structure. 3232 * Calls FindClosestTriangleToVector() and checks whether the resulting triangle's BoundaryTriangleSet#NormalVector points 3233 * towards or away from the given \a &Point. 3234 3234 * 3235 3235 * @param point of which to check the position … … 3245 3245 Vector Center; 3246 3246 Vector helper; 3247 Vector DistanceToCenter; 3248 Vector Intersection; 3247 3249 3248 3250 if (result == NULL) {// is boundary point or only point in point cloud? … … 3255 3257 result->GetCenter(&Center); 3256 3258 Log() << Verbose(2) << "INFO: Central point of the triangle is " << Center << "." << endl; 3257 Center.SubtractVector(&Point); 3259 DistanceToCenter.CopyVector(&Center); 3260 DistanceToCenter.SubtractVector(&Point); 3258 3261 Log() << Verbose(2) << "INFO: Vector from point to test to center is " << Center << "." << endl; 3259 if (Center.ScalarProduct(&result->NormalVector) > -MYEPSILON) { 3262 3263 // check whether we are on boundary 3264 if (fabs(DistanceToCenter.ScalarProduct(&result->NormalVector)) < MYEPSILON) { 3265 // calculate whether inside of triangle 3266 DistanceToCenter.ProjectOntoPlane(&result->NormalVector); 3267 DistanceToCenter.AddVector(&Center); 3268 Center.CopyVector(&DistanceToCenter); 3269 Center.SubtractVector(&result->NormalVector); // points towards MolCenter 3270 DistanceToCenter.AddVector(&result->NormalVector); // points outside 3271 Log() << Verbose(1) << "INFO: Calling Intersection with " << Center << " and " << DistanceToCenter << "." << endl; 3272 if (result->GetIntersectionInsideTriangle(&Center, &DistanceToCenter, &Intersection)) { 3273 Log() << Verbose(1) << Point << " is inner point: sufficiently close to boundary, " << Intersection << "." << endl; 3274 return true; 3275 } else { 3276 Log() << Verbose(1) << Point << " is NOT an inner point: on triangle plane but outside of triangle bounds." << endl; 3277 return false; 3278 } 3279 } 3280 3281 // then check direction to boundary 3282 if (DistanceToCenter.ScalarProduct(&result->NormalVector) > MYEPSILON) { 3260 3283 Log() << Verbose(1) << Point << " is an inner point." << endl; 3261 3284 return true; 3262 3285 } else { 3263 for (int i=0;i<3;i++) {3264 helper.CopyVector(result->endpoints[i]->node->node);3265 helper.SubtractVector(&Point);3266 if (Center.NormSquared() > helper.NormSquared())3267 Center.CopyVector(&helper);3268 }3269 if (Center.NormSquared() < epsilon*epsilon) {3270 Log() << Verbose(1) << Point << " is inner point, being sufficiently close (wrt " << epsilon << ") to boundary." << endl;3271 return true;3272 }3273 3286 Log() << Verbose(1) << Point << " is NOT an inner point." << endl; 3274 3287 return false; 3275 3288 } 3276 }3277 3278 /** Checks whether the provided TesselPoint is within the tesselation structure.3279 *3280 * @param *Point of which to check the position3281 * @param *LC Linked Cell structure3282 * @param epsilon Distance of \a &Point to Center of triangle is tested greater against this value (standard: -MYEPSILON)3283 *3284 * @return true if the point is inside the tesselation structure, false otherwise3285 */3286 bool Tesselation::IsInnerPoint(const TesselPoint * const Point, const LinkedCell* const LC, const double epsilon) const3287 {3288 Info FunctionInfo(__func__);3289 return IsInnerPoint(*(Point->node), LC, epsilon);3290 3289 } 3291 3290 … … 3460 3459 } 3461 3460 3461 // check whether there's something to do 3462 if (SetOfNeighbours->size() < 3) { 3463 for (TesselPointSet::iterator TesselRunner = SetOfNeighbours->begin(); TesselRunner != SetOfNeighbours->end(); TesselRunner++) 3464 connectedCircle->push_back(*TesselRunner); 3465 return connectedCircle; 3466 } 3467 3468 Log() << Verbose(1) << "INFO: Point is " << *Point << " and Reference is " << *Reference << "." << endl; 3462 3469 // calculate central point 3463 for (TesselPointSet::const_iterator TesselRunner = SetOfNeighbours->begin(); TesselRunner != SetOfNeighbours->end(); TesselRunner++) 3464 center.AddVector((*TesselRunner)->node); 3470 3471 TesselPointSet::const_iterator TesselA = SetOfNeighbours->begin(); 3472 TesselPointSet::const_iterator TesselB = SetOfNeighbours->begin(); 3473 TesselPointSet::const_iterator TesselC = SetOfNeighbours->begin(); 3474 TesselB++; 3475 TesselC++; 3476 TesselC++; 3477 int counter = 0; 3478 while (TesselC != SetOfNeighbours->end()) { 3479 helper.MakeNormalVector((*TesselA)->node, (*TesselB)->node, (*TesselC)->node); 3480 Log() << Verbose(0) << "Making normal vector out of " << *(*TesselA) << ", " << *(*TesselB) << " and " << *(*TesselC) << ":" << helper << endl; 3481 counter++; 3482 TesselA++; 3483 TesselB++; 3484 TesselC++; 3485 PlaneNormal.AddVector(&helper); 3486 } 3465 3487 //Log() << Verbose(0) << "Summed vectors " << center << "; number of points " << connectedPoints.size() 3466 // << "; scale factor " << 1.0/connectedPoints.size();3467 center.Scale(1.0/SetOfNeighbours->size());3468 Log() << Verbose(1) << "INFO: Calculated center of all circle points is " << center << "." << endl;3469 3470 // projection plane of the circle is at the closes Point and normal is pointing away from center of all circle points3471 PlaneNormal.CopyVector(Point->node);3472 PlaneNormal.SubtractVector(¢er);3473 PlaneNormal.Normalize();3488 // << "; scale factor " << counter; 3489 PlaneNormal.Scale(1.0/(double)counter); 3490 // Log() << Verbose(1) << "INFO: Calculated center of all circle points is " << center << "." << endl; 3491 // 3492 // // projection plane of the circle is at the closes Point and normal is pointing away from center of all circle points 3493 // PlaneNormal.CopyVector(Point->node); 3494 // PlaneNormal.SubtractVector(¢er); 3495 // PlaneNormal.Normalize(); 3474 3496 Log() << Verbose(1) << "INFO: Calculated plane normal of circle is " << PlaneNormal << "." << endl; 3475 3497 … … 3504 3526 helper.ProjectOntoPlane(&PlaneNormal); 3505 3527 double angle = GetAngle(helper, AngleZero, OrthogonalVector); 3528 if (angle > M_PI) // the correction is of no use here (and not desired) 3529 angle = 2.*M_PI - angle; 3506 3530 Log() << Verbose(0) << "INFO: Calculated angle between " << helper << " and " << AngleZero << " is " << angle << " for point " << **listRunner << "." << endl; 3507 3531 InserterTest = anglesOfPoints.insert(pair<double, TesselPoint*>(angle, (*listRunner)));
Note:
See TracChangeset
for help on using the changeset viewer.