- Timestamp:
- Aug 20, 2014, 1:04:08 PM (11 years ago)
- Children:
- 23c605
- Parents:
- 260540
- git-author:
- Frederik Heber <heber@…> (06/29/14 21:20:49)
- git-committer:
- Frederik Heber <heber@…> (08/20/14 13:04:08)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/SphericalPointDistribution.cpp
r260540 r1ae9aa 62 62 typedef std::vector<double> DistanceArray_t; 63 63 64 // class generator: taken from www.cplusplus.com example std::generate 65 struct c_unique { 66 int current; 67 c_unique() {current=0;} 68 int operator()() {return current++;} 69 } UniqueNumber; 70 64 71 inline 65 72 DistanceArray_t calculatePairwiseDistances( … … 82 89 } 83 90 84 // class generator: taken from www.cplusplus.com example std::generate 85 struct c_unique { 86 int current; 87 c_unique() {current=0;} 88 int operator()() {return current++;} 89 } UniqueNumber; 90 91 /** Calculate the center of a given set of points in \a _positions but only 92 * for those indicated by \a _indices. 93 * 94 */ 95 inline 96 Vector calculateCenter( 97 const SphericalPointDistribution::VectorArray_t &_positions, 98 const SphericalPointDistribution::IndexList_t &_indices) 99 { 100 Vector Center; 101 Center.Zero(); 102 for (SphericalPointDistribution::IndexList_t::const_iterator iter = _indices.begin(); 103 iter != _indices.end(); ++iter) 104 Center += _positions[*iter]; 105 if (!_indices.empty()) 106 Center *= 1./(double)_indices.size(); 107 108 return Center; 109 } 110 111 /** Decides by an orthonormal third vector whether the sign of the rotation 112 * angle should be negative or positive. 113 * 114 * \return -1 or 1 115 */ 116 inline 117 double determineSignOfRotation( 118 const Vector &_oldPosition, 119 const Vector &_newPosition, 120 const Vector &_RotationAxis 121 ) 122 { 123 Vector dreiBein(_oldPosition); 124 dreiBein.VectorProduct(_RotationAxis); 125 dreiBein.Normalize(); 126 const double sign = 127 (dreiBein.ScalarProduct(_newPosition) < 0.) ? -1. : +1.; 128 LOG(6, "DEBUG: oldCenter on plane is " << _oldPosition 129 << ", newCenter in plane is " << _newPosition 130 << ", and dreiBein is " << dreiBein); 131 return sign; 132 } 133 134 /** Convenience function to recalculate old and new center for determining plane 135 * rotation. 136 */ 137 inline 138 void calculateOldAndNewCenters( 139 Vector &_oldCenter, 140 Vector &_newCenter, 141 const SphericalPointDistribution::VectorArray_t &_referencepositions, 142 const SphericalPointDistribution::VectorArray_t &_currentpositions, 143 const SphericalPointDistribution::IndexList_t &_bestmatching) 144 { 145 const size_t NumberIds = std::min(_bestmatching.size(), (size_t)3); 146 SphericalPointDistribution::IndexList_t continuousIds(NumberIds, -1); 147 std::generate(continuousIds.begin(), continuousIds.end(), UniqueNumber); 148 _oldCenter = calculateCenter(_referencepositions, continuousIds); 149 // C++11 defines a copy_n function ... 150 SphericalPointDistribution::IndexList_t::const_iterator enditer = _bestmatching.begin(); 151 std::advance(enditer, NumberIds); 152 SphericalPointDistribution::IndexList_t firstbestmatchingIds(NumberIds, -1); 153 std::copy(_bestmatching.begin(), enditer, firstbestmatchingIds.begin()); 154 _newCenter = calculateCenter( _currentpositions, firstbestmatchingIds); 155 } 91 156 /** Returns squared L2 error of the given \a _Matching. 92 157 * … … 218 283 } 219 284 220 /** Decides by an orthonormal third vector whether the sign of the rotation221 * angle should be negative or positive.222 *223 * \return -1 or 1224 */225 inline226 double determineSignOfRotation(227 const Vector &_oldPosition,228 const Vector &_newPosition,229 const Vector &_RotationAxis230 )231 {232 Vector dreiBein(_oldPosition);233 dreiBein.VectorProduct(_RotationAxis);234 dreiBein.Normalize();235 const double sign =236 (dreiBein.ScalarProduct(_newPosition) < 0.) ? -1. : +1.;237 LOG(6, "DEBUG: oldCenter on plane is " << _oldPosition238 << ", newCenter in plane is " << _newPosition239 << ", and dreiBein is " << dreiBein);240 return sign;241 }242 243 285 /** Finds combinatorially the best matching between points in \a _polygon 244 286 * and \a _newpolygon. … … 246 288 * We find the matching with the smallest L2 error, where we break when we stumble 247 289 * upon a matching with zero error. 290 * 291 * As points in \a _polygon may be have a weight greater 1 we have to match it to 292 * multiple points in \a _newpolygon. Eventually, these multiple points are combined 293 * for their center of weight, which is the only thing follow-up function see of 294 * these multiple points. Hence, we actually modify \a _newpolygon in the process 295 * such that the returned IndexList_t indicates a bijective mapping in the end. 248 296 * 249 297 * \sa recurseMatchings() for going through all matchings … … 254 302 */ 255 303 SphericalPointDistribution::IndexList_t SphericalPointDistribution::findBestMatching( 256 const SphericalPointDistribution::WeightedPolygon_t &_polygon,257 const SphericalPointDistribution::Polygon_t &_newpolygon304 const WeightedPolygon_t &_polygon, 305 Polygon_t &_newpolygon 258 306 ) 259 307 { … … 279 327 recurseMatchings(MCS, matching, indices, matchingsize); 280 328 } 281 return MCS.bestmatching; 282 } 283 284 inline 285 Vector calculateCenter( 286 const SphericalPointDistribution::VectorArray_t &_positions, 287 const SphericalPointDistribution::IndexList_t &_indices) 288 { 289 Vector Center; 290 Center.Zero(); 291 for (SphericalPointDistribution::IndexList_t::const_iterator iter = _indices.begin(); 292 iter != _indices.end(); ++iter) 293 Center += _positions[*iter]; 294 if (!_indices.empty()) 295 Center *= 1./(double)_indices.size(); 296 297 return Center; 298 } 299 300 inline 301 void calculateOldAndNewCenters( 302 Vector &_oldCenter, 303 Vector &_newCenter, 304 const SphericalPointDistribution::VectorArray_t &_referencepositions, 305 const SphericalPointDistribution::VectorArray_t &_currentpositions, 306 const SphericalPointDistribution::IndexList_t &_bestmatching) 307 { 308 const size_t NumberIds = std::min(_bestmatching.size(), (size_t)3); 309 SphericalPointDistribution::IndexList_t continuousIds(NumberIds, -1); 310 std::generate(continuousIds.begin(), continuousIds.end(), UniqueNumber); 311 _oldCenter = calculateCenter(_referencepositions, continuousIds); 312 // C++11 defines a copy_n function ... 313 SphericalPointDistribution::IndexList_t::const_iterator enditer = _bestmatching.begin(); 314 std::advance(enditer, NumberIds); 315 SphericalPointDistribution::IndexList_t firstbestmatchingIds(NumberIds, -1); 316 std::copy(_bestmatching.begin(), enditer, firstbestmatchingIds.begin()); 317 _newCenter = calculateCenter( _currentpositions, firstbestmatchingIds); 329 330 // combine multiple points and create simple IndexList from IndexTupleList 331 IndexTupleList_t bestmatching; 332 for (IndexList_t::const_iterator iter = MCS.bestmatching.begin(); 333 iter != MCS.bestmatching.end(); ++iter) 334 bestmatching.push_back(IndexList_t(1, *iter)); 335 const SphericalPointDistribution::IndexList_t IndexList = 336 joinPoints(_newpolygon, MCS.newpoints, bestmatching); 337 338 return IndexList; 339 } 340 341 SphericalPointDistribution::IndexList_t SphericalPointDistribution::joinPoints( 342 Polygon_t &_newpolygon, 343 const VectorArray_t &_newpoints, 344 const IndexTupleList_t &_bestmatching 345 ) 346 { 347 // combine all multiple points 348 IndexList_t IndexList; 349 IndexArray_t removalpoints; 350 unsigned int UniqueIndex = _newpolygon.size(); // all indices up to size are used right now 351 VectorArray_t newCenters; 352 newCenters.reserve(_bestmatching.size()); 353 for (IndexTupleList_t::const_iterator tupleiter = _bestmatching.begin(); 354 tupleiter != _bestmatching.end(); ++tupleiter) { 355 ASSERT (tupleiter->size() > 0, 356 "findBestMatching() - encountered tuple in bestmatching with size 0."); 357 if (tupleiter->size() == 1) { 358 // add point and index 359 IndexList.push_back(*tupleiter->begin()); 360 } else { 361 // combine into weighted and normalized center 362 Vector Center = calculateCenter(_newpoints, *tupleiter); 363 Center.Normalize(); 364 _newpolygon.push_back(Center); 365 LOG(5, "DEBUG: Combining " << tupleiter->size() << "points to weighted center " 366 << Center << " with new index " << UniqueIndex); 367 // mark for removal 368 removalpoints.insert(removalpoints.end(), tupleiter->begin(), tupleiter->end()); 369 // add new index 370 IndexList.push_back(UniqueIndex++); 371 } 372 } 373 // IndexList is now our new bestmatching (that is bijective) 374 LOG(4, "DEBUG: Our new bijective IndexList reads as " << IndexList); 375 376 // modifying _newpolygon: remove all points in removalpoints, add those in newCenters 377 Polygon_t allnewpoints = _newpolygon; 378 { 379 _newpolygon.clear(); 380 std::sort(removalpoints.begin(), removalpoints.end()); 381 size_t i = 0; 382 IndexArray_t::const_iterator removeiter = removalpoints.begin(); 383 for (Polygon_t::iterator iter = allnewpoints.begin(); 384 iter != allnewpoints.end(); ++iter, ++i) { 385 if ((removeiter != removalpoints.end()) && (i == *removeiter)) { 386 // don't add, go to next remove index 387 ++removeiter; 388 } else { 389 // otherwise add points 390 _newpolygon.push_back(*iter); 391 } 392 } 393 } 394 LOG(4, "DEBUG: The polygon with recentered points removed is " << _newpolygon); 395 396 // map IndexList to new shrinked _newpolygon 397 typedef std::set<unsigned int> IndexSet_t; 398 IndexSet_t SortedIndexList(IndexList.begin(), IndexList.end()); 399 IndexList.clear(); 400 { 401 size_t offset = 0; 402 IndexSet_t::const_iterator listiter = SortedIndexList.begin(); 403 IndexArray_t::const_iterator removeiter = removalpoints.begin(); 404 for (size_t i = 0; i < allnewpoints.size(); ++i) { 405 if ((removeiter != removalpoints.end()) && (i == *removeiter)) { 406 ++offset; 407 ++removeiter; 408 } else if ((listiter != SortedIndexList.end()) && (i == *listiter)) { 409 IndexList.push_back(*listiter - offset); 410 ++listiter; 411 } 412 } 413 } 414 LOG(4, "DEBUG: Our new bijective IndexList corrected for removed points reads as " 415 << IndexList); 416 417 return IndexList; 318 418 } 319 419 … … 492 592 SphericalPointDistribution::matchSphericalPointDistributions( 493 593 const SphericalPointDistribution::WeightedPolygon_t &_polygon, 494 constSphericalPointDistribution::Polygon_t &_newpolygon594 SphericalPointDistribution::Polygon_t &_newpolygon 495 595 ) 496 596 {
Note:
See TracChangeset
for help on using the changeset viewer.
