⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 align_points.out.h

📁 很多二维 三维几何计算算法 C++ 类库
💻 H
字号:
#ifndef CGAL_DSR_ALIGN_POINTS_H_#define CGAL_DSR_ALIGN_POINTS_H_#include <CGAL/PDB/basic.h>#include <tnt/tnt_cmat.h>#include <CGAL/PDB/Point.h>#include <CGAL/PDB/Transform.h>#include <CGAL/PDB/internal/tnt/tnt_array2d.h>#include <CGAL/PDB/internal/tnt/tnt_array2d_utils.h>#include <CGAL/PDB/internal/tnt/jama_svd.h>#include <cassert>#include <vector>#include <iterator>CGAL_PDB_BEGIN_INTERNAL_NAMESPACE  template <class T>  T det(const CGAL_TNT_NS::Array2D<T>& m) {    assert(m.dim1() == 3);    assert(m.dim2() == 3);    return (m[0][0]*(m[1][1]*m[2][2] - m[1][2]*m[2][1]) -            m[0][1]*(m[1][0]*m[2][2] - m[1][2]*m[2][0]) +            m[0][2]*(m[1][0]*m[2][1] - m[1][1]*m[2][0]));  }  // Transpose a matrix  template <class T>  CGAL_TNT_NS::Array2D<T> transpose(const CGAL_TNT_NS::Array2D<T>& m) {    CGAL_TNT_NS::Array2D<T> mt(m.dim2(), m.dim1());    for (int i = 0; i < m.dim1(); i++) {      for (int j = 0; j < m.dim2(); j++) {        mt[j][i] = m[i][j];      }    }    return mt;  }  template <class InputIterator>  CGAL_PDB_NS::Transform transform_taking_first_to_second(InputIterator pBegin, InputIterator pEnd,						     InputIterator qBegin, InputIterator qEnd) {        // compute the centroid of the points and transform    // pointsets so that their centroids coinside          typedef typename InputIterator::value_type Point;    typedef double RT;    CGAL_PDB_NS::Vector center_p(0,0,0), center_q(0,0,0);    int num_p = 0;    int num_q = 0;    for (InputIterator p_it = pBegin; p_it != pEnd; ++p_it) {      //double x= p_it->x();      center_p = center_p+CGAL_PDB_NS::Vector(p_it->x(), p_it->y(), p_it->z());//((*p_it)-CGAL::ORIGIN);      num_p++;    }    center_p = center_p/num_p;          for (InputIterator q_it = qBegin; q_it != qEnd; ++q_it) {      center_q = center_q + CGAL_PDB_NS::Vector(q_it->x(), q_it->y(), q_it->z()); //((*q_it)-CGAL::ORIGIN);      num_q++;    }    center_q = center_q/num_q;          assert(num_p == num_q);          std::vector<Point> p_shifted, q_shifted;    p_shifted.reserve(num_p);    q_shifted.reserve(num_q);    for (InputIterator p_it = pBegin; p_it != pEnd; ++p_it) {      p_shifted.push_back((*p_it) - center_p);    }    for (InputIterator q_it = qBegin; q_it != qEnd; ++q_it) {      q_shifted.push_back((*q_it) - center_q);    }                // covariance matrix    CGAL_TNT_NS::Array2D<RT> H(3, 3);    for (int i = 0; i < 3; i++) {      for (int j = 0; j < 3; j++) {	H[i][j] = 0;      }    }    for (int i = 0; i < num_p; i++) {      for (int j = 0; j < 3; j++) {	for (int k = 0; k < 3; k++) {	  H[j][k] += p_shifted[i][j]*q_shifted[i][k];	}      }    }    CGAL_JAMA_NS::SVD<RT> svd(H);    CGAL_TNT_NS::Array2D<RT> U(3, 3), V(3, 3);    svd.getU(U);    svd.getV(V);    // the rotation matrix is R = VU^T    CGAL_TNT_NS::Array2D<RT> UT = transpose(U);    CGAL_TNT_NS::Array2D<RT> rot(3, 3);    rot = matmult(V, UT);    // check for reflection    if (det(rot) < 0) {      CGAL_TNT_NS::Array2D<RT> VT = transpose(V);      CGAL_TNT_NS::Array2D<RT> UVT = matmult(U, VT);      CGAL_TNT_NS::Array2D<RT> S(3, 3);      S[0][0] = S[1][1] = 1;      S[2][2] = det(UVT);      S[0][1] = S[0][2] = S[1][0] = S[1][2] = S[2][0] = S[2][1] = 0;      rot = matmult(matmult(U, S), VT);    }    CGAL_PDB_NS::Transform xf(rot, Point(0,0,0));       xf.set_translation(center_q - xf(center_p));       return xf;  }  inline double structal_score(const dsrpdb::Point& a, const dsrpdb::Point& b) {    dsrpdb::Squared_distance sd;    return 20.0/(1.0+sd(a,b)/5.0);  }  inline double gap_score() {    return -10.0;  }  struct DpP {    double first;    int second;    DpP(double d, int s): first(d), second(s){}    DpP(): first(-1), second(-3){}  };  inline std::ostream &operator<<(std::ostream &o, DpP p){    return o << "(" << p.first << " " << p.second << ")";  }  template <class ItP, class ItM>  void greedy_matching(ItP b_0, ItP e_0,		       ItP b_1, ItP e_1,		       ItM b_m, ItM e_m) {    const double gap_cost=10.0;    unsigned int d_0= std::distance(b_0, e_0);    unsigned int d_1= std::distance(b_1, e_1);    //typedef std::pair<double, int> DpP;    CGAL_TNT_NS::Array2D<DpP> dp_matrix(d_0+2, d_1+2);    std::vector<int> best_i(d_1+2);    int best_j(0);    for (unsigned int i=0; i< d_0+1; ++i){      dp_matrix[i][0]=DpP(-gap_cost*i,0);      best_i[i]= 0;    }    best_i.back()= 0;    for (unsigned int i=0; i< d_1+1; ++i){      dp_matrix[0][i]=DpP(-gap_cost*i,0);    }    dp_matrix[0][d_1+1]=DpP(-gap_cost*d_1, 0);    dp_matrix[d_0+1][0]=DpP(-gap_cost*d_0, 0);        {      ItP c_0=b_0;      for (unsigned int i=1; i< d_0+2; ++i, ++c_0){	ItP c_1= b_1;	best_j= 0;	for (unsigned int j=1; j< d_1+2; ++j, ++c_1){	  double ss;	  if (c_0== e_0 || c_1==e_1) {	    ss= 0;	  } else {	    ss= structal_score(*c_0, *c_1);	  }	  	  	  double v_d=  dp_matrix[i-1][j-1].first;	  double v_i= -gap_cost*best_i[j-1] + dp_matrix[i-best_i[j-1]-1][j-1].first;	  double v_j= -gap_cost*best_j + dp_matrix[i-1][j-best_j-1].first;	  if (v_d >= v_i && v_d >= v_j){	    dp_matrix[i][j]= DpP(ss+v_d, 0);	    best_i[j-1]=0;	    best_j=0;	  } else if (v_i >= v_j){	    dp_matrix[i][j] = DpP(ss+v_i, best_i[j-1]);	    assert(v_i > v_d);	    if (v_d >= v_j) best_j=0;	  } else {	    dp_matrix[i][j] = DpP(ss+v_j, -best_j);	    if (v_d >= v_i) best_i[j-1]=0;	  }	  const double eps=.00001;	  	  for (unsigned int k=0; k< i; ++k){	    assert(dp_matrix[i-k-1][j-1].first -gap_cost*k +ss <= dp_matrix[i][j].first + eps);	    if (dp_matrix[i][j].second == static_cast<int>(k)) {	      assert(std::abs(dp_matrix[i-k-1][j-1].first - gap_cost*k + ss - dp_matrix[i][j].first) < eps);	    }	  }	  for (unsigned int k=0; k< j; ++k){	    assert(dp_matrix[i-1][j-k-1].first -gap_cost*k + ss <= dp_matrix[i][j].first + eps);	    if (dp_matrix[i][j].second == -static_cast<int>(k)) {	      assert( std::abs(ss - gap_cost*k + dp_matrix[i-1][j-k-1].first - dp_matrix[i][j].first) < eps);	    }	  }	  ++best_i[j-1];	  ++best_j;	}      }    }    /*std::cout.precision(2);      std::cout << dp_matrix << std::endl;*/    // backtrace    {      unsigned int i=d_0+1, j= d_1+1;           ItM c_m= e_m; //--c_m;      //bool set=false;      while (i >0 && j > 0) {	if (dp_matrix[i][j].second ==0){	} else if (dp_matrix[i][j].second < 0) {	  j-= std::abs(dp_matrix[i][j].second);	} else {	  for (int k =0; k< dp_matrix[i][j].second; ++k){	    --c_m;	    *c_m=-1;	  }	  i-= dp_matrix[i][j].second;	}	--i;	--j;	if (i==0 || j==0) break;	assert(c_m != b_m);	--c_m;	assert(j < d_1+1);	assert(i < d_0+1);	*c_m=j-1;	//std::cout << i << " " << j << std::endl;      }    }  }  template <class ItP, class OItM>  CGAL_PDB_NS::Transform refine_alignment(ItP b_0, ItP e_0,				     ItP b_1, ItP e_1,				     double motion,				     OItM m) {        std::vector<CGAL_PDB_NS::Point> p_0(b_0, e_0), p_1(b_1, e_1);    double dist= std::numeric_limits<double>::infinity();    CGAL_PDB_NS::Squared_distance sd;    typedef std::vector<int>::const_iterator ItM;    std::vector<int> cur_matching(std::distance(b_0, e_0), -1);    CGAL_PDB_NS::Transform tr;    do {      greedy_matching(p_0.begin(), p_0.end(),		      p_1.begin(), p_1.end(),		      cur_matching.begin(), cur_matching.end());      /*std::copy(cur_matching.begin(), cur_matching.end(), std::ostream_iterator<int>(std::cout, " "));	std::cout << std::endl;*/      std::vector<CGAL_PDB_NS::Point> cp_0, cp_1;      {	ItP c_0= b_0;	for (ItM c_m= cur_matching.begin(); c_m != cur_matching.end(); ++c_m, ++c_0 ){	  if (*c_m != -1){	    cp_0.push_back(*c_0);	    cp_1.push_back(p_1[*c_m]);	  }	}      }            tr = transform_taking_first_to_second(cp_0.begin(),cp_0.end(),					cp_1.begin(), cp_1.end());      //std::cout << tr << std::endl;      double sum_dist=0;      unsigned int i=0;      for (ItP c_0=b_0; c_0 != e_0; ++c_0, ++i){	dsrpdb::Point pn= tr(*c_0);	sum_dist+= sd(pn, p_0[i]);	p_0[i]=pn;      }      dist=std::sqrt(sum_dist)/std::distance(b_0, e_0);      std::cout << "Moved " << dist << std::endl;    } while (dist > motion);    std::copy(cur_matching.begin(), cur_matching.end(), m);    return tr;  }CGAL_PDB_END_INTERNAL_NAMESPACE#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -