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