- Timestamp:
- May 25, 2016, 7:13:59 AM (9 years ago)
- Children:
- 66700f2
- Parents:
- 4d611d
- git-author:
- Frederik Heber <heber@…> (07/09/14 21:14:53)
- git-committer:
- Frederik Heber <heber@…> (05/25/16 07:13:59)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/SphericalPointDistribution.cpp
r4d611d r4b96da 99 99 } 100 100 101 /** Calculate the center of a given set of points in \a _positions but only 102 * for those indicated by \a _indices. 103 * 104 */ 105 inline 106 Vector calculateCenter( 107 const SphericalPointDistribution::PolygonWithIndices &_polygon) 108 { 109 return calculateCenter(_polygon.polygon, _polygon.indices); 110 } 111 101 112 inline 102 113 DistanceArray_t calculatePairwiseDistances( … … 177 188 Vector &_oldCenter, 178 189 Vector &_newCenter, 179 const SphericalPointDistribution::VectorArray_t &_referencepositions, 180 const SphericalPointDistribution::VectorArray_t &_currentpositions, 181 const SphericalPointDistribution::IndexList_t &_bestmatching) 182 { 183 const size_t NumberIds = std::min(_bestmatching.size(), (size_t)3); 184 SphericalPointDistribution::IndexList_t continuousIds(NumberIds, -1); 185 std::generate(continuousIds.begin(), continuousIds.end(), UniqueNumber); 186 _oldCenter = calculateCenter(_referencepositions, continuousIds); 190 const SphericalPointDistribution::PolygonWithIndices &_referencepositions, 191 const SphericalPointDistribution::PolygonWithIndices &_currentpositions) 192 { 193 _oldCenter = calculateCenter(_referencepositions.polygon, _referencepositions.indices); 187 194 // C++11 defines a copy_n function ... 188 SphericalPointDistribution::IndexList_t::const_iterator enditer = _bestmatching.begin(); 189 std::advance(enditer, NumberIds); 190 SphericalPointDistribution::IndexList_t firstbestmatchingIds(NumberIds, -1); 191 std::copy(_bestmatching.begin(), enditer, firstbestmatchingIds.begin()); 192 _newCenter = calculateCenter( _currentpositions, firstbestmatchingIds); 195 _newCenter = calculateCenter( _currentpositions.polygon, _currentpositions.indices); 193 196 } 194 197 /** Returns squared L2 error of the given \a _Matching. … … 251 254 252 255 SphericalPointDistribution::Polygon_t SphericalPointDistribution::removeMatchingPoints( 253 const VectorArray_t &_points, 254 const IndexList_t &_matchingindices 256 const PolygonWithIndices &_points 255 257 ) 256 258 { 257 SphericalPointDistribution::Polygon_t remaining returnpolygon;258 IndexArray_t indices(_ matchingindices.begin(), _matchingindices.end());259 SphericalPointDistribution::Polygon_t remainingpoints; 260 IndexArray_t indices(_points.indices.begin(), _points.indices.end()); 259 261 std::sort(indices.begin(), indices.end()); 260 262 LOG(4, "DEBUG: sorted matching is " << indices); 261 IndexArray_t remainingindices(_points. size(), -1);263 IndexArray_t remainingindices(_points.polygon.size(), -1); 262 264 std::generate(remainingindices.begin(), remainingindices.end(), UniqueNumber); 263 265 IndexArray_t::iterator remainiter = std::set_difference( … … 269 271 for (IndexArray_t::const_iterator iter = remainingindices.begin(); 270 272 iter != remainingindices.end(); ++iter) { 271 remainingreturnpolygon.push_back(_points[*iter]);272 } 273 274 return remaining returnpolygon;273 remainingpoints.push_back(_points.polygon[*iter]); 274 } 275 276 return remainingpoints; 275 277 } 276 278 … … 501 503 502 504 SphericalPointDistribution::Rotation_t SphericalPointDistribution::findPlaneAligningRotation( 503 const VectorArray_t &_referencepositions, 504 const VectorArray_t &_currentpositions, 505 const IndexList_t &_bestmatching 505 const PolygonWithIndices &_referencepositions, 506 const PolygonWithIndices &_currentpositions 506 507 ) 507 508 { … … 518 519 calculateOldAndNewCenters( 519 520 oldCenter, newCenter, 520 _referencepositions, _currentpositions , _bestmatching);521 _referencepositions, _currentpositions); 521 522 522 523 if ((!oldCenter.IsZero()) && (!newCenter.IsZero())) { … … 536 537 if ((oldCenter.IsZero()) && (newCenter.IsZero())) { 537 538 // either oldCenter or newCenter (or both) is directly at origin 538 if (_ bestmatching.size() == 2) {539 if (_currentpositions.indices.size() == 2) { 539 540 // line case 540 Vector oldPosition = _currentpositions [*_bestmatching.begin()];541 Vector newPosition = _referencepositions [0];541 Vector oldPosition = _currentpositions.polygon[*_currentpositions.indices.begin()]; 542 Vector newPosition = _referencepositions.polygon[0]; 542 543 // check whether we need to rotate at all 543 544 if (!oldPosition.IsEqualTo(newPosition)) { … … 553 554 // both triangles/planes have same center, hence get axis by 554 555 // VectorProduct of Normals 555 Plane newplane(_referencepositions [0], _referencepositions[1], _referencepositions[2]);556 Plane newplane(_referencepositions.polygon[0], _referencepositions.polygon[1], _referencepositions.polygon[2]); 556 557 VectorArray_t vectors; 557 for (IndexList_t::const_iterator iter = _ bestmatching.begin();558 iter != _ bestmatching.end(); ++iter)559 vectors.push_back(_currentpositions [*iter]);558 for (IndexList_t::const_iterator iter = _currentpositions.indices.begin(); 559 iter != _currentpositions.indices.end(); ++iter) 560 vectors.push_back(_currentpositions.polygon[*iter]); 560 561 Plane oldplane(vectors[0], vectors[1], vectors[2]); 561 562 Vector oldPosition = oldplane.getNormal(); … … 603 604 604 605 SphericalPointDistribution::Rotation_t SphericalPointDistribution::findPointAligningRotation( 605 const VectorArray_t &remainingold, 606 const VectorArray_t &remainingnew, 607 const IndexList_t &_bestmatching) 606 const PolygonWithIndices &remainingold, 607 const PolygonWithIndices &remainingnew) 608 608 { 609 609 // initialize rotation to zero … … 618 618 calculateOldAndNewCenters( 619 619 oldCenter, newCenter, 620 remainingold, remainingnew, _bestmatching); 621 622 Vector oldPosition = remainingnew[*_bestmatching.begin()]; 623 Vector newPosition = remainingold[0]; 624 LOG(6, "DEBUG: oldPosition is " << oldPosition << " and newPosition is " << newPosition); 620 remainingold, remainingnew); 621 622 Vector oldPosition = remainingnew.polygon[*remainingnew.indices.begin()]; 623 Vector newPosition = remainingold.polygon[0]; 624 LOG(6, "DEBUG: oldPosition is " << oldPosition << " (length: " 625 << oldPosition.Norm() << ") and newPosition is " << newPosition << " length(: " 626 << newPosition.Norm() << ")"); 625 627 if (!oldPosition.IsEqualTo(newPosition)) { 626 628 if ((!oldCenter.IsZero()) && (!newCenter.IsZero())) { 627 oldCenter.Normalize(); // note weighted sum of normalized weight is not normalized 629 // we rotate at oldCenter and around the radial direction, which is again given 630 // by oldCenter. 628 631 Rotation.first = oldCenter; 629 LOG(6, "DEBUG: Picking normalized oldCenter as Rotation.first " << oldCenter); 630 oldPosition.ProjectOntoPlane(Rotation.first); 631 newPosition.ProjectOntoPlane(Rotation.first); 632 Rotation.first.Normalize(); // note weighted sum of normalized weight is not normalized 633 LOG(6, "DEBUG: Using oldCenter " << oldCenter << " as rotation center and " 634 << Rotation.first << " as axis."); 635 oldPosition -= oldCenter; 636 newPosition -= oldCenter; 637 oldPosition = (oldPosition - oldPosition.Projection(Rotation.first)); 638 newPosition = (newPosition - newPosition.Projection(Rotation.first)); 632 639 LOG(6, "DEBUG: Positions after projection are " << oldPosition << " and " << newPosition); 633 640 } else { 634 if ( _bestmatching.size() == 2) {641 if (remainingnew.indices.size() == 2) { 635 642 // line situation 636 643 try { … … 653 660 } else { 654 661 // triangle situation 655 Plane oldplane(remainingold [0], remainingold[1], remainingold[2]);662 Plane oldplane(remainingold.polygon[0], remainingold.polygon[1], remainingold.polygon[2]); 656 663 Rotation.first = oldplane.getNormal(); 657 664 LOG(6, "DEBUG: oldPlane is " << oldplane << " and normal is " << Rotation.first); … … 678 685 { 679 686 SphericalPointDistribution::Polygon_t remainingpoints; 680 VectorArray_t remainingold; 681 for (WeightedPolygon_t::const_iterator iter = _polygon.begin(); 682 iter != _polygon.end(); ++iter) 683 remainingold.push_back(iter->first); 687 684 688 LOG(2, "INFO: Matching old polygon " << _polygon 685 689 << " with new polygon " << _newpolygon); … … 695 699 LOG(2, "INFO: Best matching is " << bestmatching); 696 700 697 // _newpolygon has changed, so now convert to array 698 VectorArray_t remainingnew(_newpolygon.begin(), _newpolygon.end()); 701 const size_t NumberIds = std::min(bestmatching.size(), (size_t)3); 702 // create old set 703 PolygonWithIndices oldSet; 704 oldSet.indices.resize(NumberIds, -1); 705 std::generate(oldSet.indices.begin(), oldSet.indices.end(), UniqueNumber); 706 for (WeightedPolygon_t::const_iterator iter = _polygon.begin(); 707 iter != _polygon.end(); ++iter) 708 oldSet.polygon.push_back(iter->first); 709 710 // _newpolygon has changed, so now convert to array with matched indices 711 PolygonWithIndices newSet; 712 SphericalPointDistribution::IndexList_t::const_iterator beginiter = bestmatching.begin(); 713 SphericalPointDistribution::IndexList_t::const_iterator enditer = bestmatching.begin(); 714 std::advance(enditer, NumberIds); 715 newSet.indices.resize(NumberIds, -1); 716 std::copy(beginiter, enditer, newSet.indices.begin()); 717 std::copy(_newpolygon.begin(),_newpolygon.end(), std::back_inserter(newSet.polygon)); 699 718 700 719 // determine rotation angles to align the two point distributions with … … 702 721 // we use the center between the three first matching points 703 722 /// the first rotation brings these two centers to coincide 704 VectorArray_t rotated_newpolygon = remainingnew;723 PolygonWithIndices rotatednewSet = newSet; 705 724 { 706 Rotation_t Rotation = findPlaneAligningRotation( 707 remainingold, 708 remainingnew, 709 bestmatching); 725 Rotation_t Rotation = findPlaneAligningRotation(oldSet, newSet); 710 726 LOG(5, "DEBUG: Rotating coordinate system by " << Rotation.second 711 727 << " around axis " << Rotation.first); … … 713 729 714 730 // apply rotation angle to bring newCenter to oldCenter 715 for (VectorArray_t::iterator iter = rotated _newpolygon.begin();716 iter != rotated _newpolygon.end(); ++iter) {731 for (VectorArray_t::iterator iter = rotatednewSet.polygon.begin(); 732 iter != rotatednewSet.polygon.end(); ++iter) { 717 733 Vector ¤t = *iter; 718 734 LOG(6, "DEBUG: Original point is " << current); … … 728 744 calculateOldAndNewCenters( 729 745 oldCenter, rotatednewCenter, 730 remainingold, rotated_newpolygon, bestmatching);746 oldSet, rotatednewSet); 731 747 // NOTE: Center must not necessarily lie on the sphere with norm 1, hence, we 732 748 // have to normalize it just as before, as oldCenter and newCenter lengths may differ. … … 736 752 LOG(4, "CHECK: rotatednewCenter is " << rotatednewCenter 737 753 << ", oldCenter is " << oldCenter); 738 ASSERT( (rotatednewCenter - oldCenter).NormSquared() < std::numeric_limits<double>::epsilon()*1e4, 754 const double difference = (rotatednewCenter - oldCenter).NormSquared(); 755 ASSERT( difference < std::numeric_limits<double>::epsilon()*1e4, 739 756 "matchSphericalPointDistributions() - rotation does not work as expected by " 740 +toString( (rotatednewCenter - oldCenter).NormSquared())+".");757 +toString(difference)+"."); 741 758 } 742 759 } … … 746 763 /// points themselves coincide 747 764 if (bestmatching.size() > 1) { 748 Rotation_t Rotation = findPointAligningRotation( 749 remainingold, 750 rotated_newpolygon, 751 bestmatching); 765 Rotation_t Rotation = findPointAligningRotation(oldSet, rotatednewSet); 752 766 753 767 // construct RotationAxis and two points on its plane, defining the angle … … 763 777 { 764 778 const IndexList_t::const_iterator iter = bestmatching.begin(); 779 780 // check whether both old and newPosition are at same distance to oldCenter 781 Vector oldCenter = calculateCenter(oldSet); 782 const double distance = fabs( 783 (oldSet.polygon[0] - oldCenter).NormSquared() 784 - (rotatednewSet.polygon[*iter] - oldCenter).NormSquared() 785 ); 786 LOG(4, "CHECK: Squared distance between oldPosition and newPosition " 787 << " with respect to oldCenter " << oldCenter << " is " << distance); 788 // ASSERT( distance < warn_amplitude, 789 // "matchSphericalPointDistributions() - old and newPosition's squared distance to oldCenter differs by " 790 // +toString(distance)); 791 765 792 Vector rotatednew = RotationAxis.rotateVector( 766 rotated _newpolygon[*iter],793 rotatednewSet.polygon[*iter], 767 794 Rotation.second); 768 795 LOG(4, "CHECK: rotated first new bestmatching is " << rotatednew 769 << " while old was " << remainingold[0]); 770 ASSERT( (rotatednew - remainingold[0]).Norm() < warn_amplitude, 771 "matchSphericalPointDistributions() - orientation rotation ends up off by more than " 772 +toString(warn_amplitude)+"."); 796 << " while old was " << oldSet.polygon[0]); 797 const double difference = (rotatednew - oldSet.polygon[0]).NormSquared(); 798 ASSERT( difference < distance+1e-8, 799 "matchSphericalPointDistributions() - orientation rotation ends up off by " 800 +toString(difference)+", more than " 801 +toString(distance+1e-8)+"."); 773 802 } 774 803 #endif 775 804 776 for (VectorArray_t::iterator iter = rotated _newpolygon.begin();777 iter != rotated _newpolygon.end(); ++iter) {805 for (VectorArray_t::iterator iter = rotatednewSet.polygon.begin(); 806 iter != rotatednewSet.polygon.end(); ++iter) { 778 807 Vector ¤t = *iter; 779 808 LOG(6, "DEBUG: Original point is " << current); … … 785 814 // remove all points in matching and return remaining ones 786 815 SphericalPointDistribution::Polygon_t remainingpoints = 787 removeMatchingPoints(rotated _newpolygon, bestmatching);816 removeMatchingPoints(rotatednewSet); 788 817 LOG(2, "INFO: Remaining points are " << remainingpoints); 789 818 return remainingpoints;
Note:
See TracChangeset
for help on using the changeset viewer.
