surface_nurbs.hpp
Go to the documentation of this file.
00001 /*
00002  * surface_nurbs.hpp
00003  *
00004  *  Created on: 10.08.2012
00005  *      Author: josh
00006  */
00007 
00008 
00009 #include "../debug_interface.h"
00010 
00011 
00012 void SurfaceNurbs::init(const boost::array<float, 6> &params, const float min_x, const float max_x, const float min_y, const float max_y, const float weight)
00013 {
00014   //  ROS_ERROR("%f %f",min_x,max_x);
00015 
00016   ROS_ASSERT(min_x<=max_x);
00017   ROS_ASSERT(min_y<=max_y);
00018 
00019   //  float sx, sy;
00020   //  if(std::abs(params[5])<0.0001f) {
00021   //    sx=-params[1]/(2*params[2]);
00022   //    sy=-params[3]/(2*params[4]);
00023   //  }
00024   //  else {
00025   //    sy= ((2*params[2]*params[3])/params[5]-params[1]) /
00026   //        ( params[5]-(4*params[2]*params[4]/params[5]));
00027   //
00028   //    sx=-(params[1]+params[5]*sy)/(2*params[2]);
00029   //  }
00030 
00031   Matrix_Point3Df Pts(3,3);
00032   for(int i=0;i<3;++i){
00033     for(int j=0;j<3;++j){
00034       const float x = min_x + (max_x-min_x)*(i*0.5f);
00035       const float y = min_y + (max_y-min_y)*(j*0.5f);
00036       Pts(i,j) = PlPoint3Df(x, y,
00037                             params[0] + x*params[1] + x*x*params[2] + y*params[3] + y*y*params[4] + x*y*params[5]
00038       ) ;
00039     }
00040   }
00041   nurbs_.globalInterp(Pts,2,2);
00042 
00043   weights_.resize(3,3);
00044   weights_.reset(weight);
00045 
00046   c_x_m_ = 1/(max_x-min_x);
00047   c_x_o_ = -min_x;
00048   c_y_m_ = 1/(max_y-min_y);
00049   c_y_o_ = -min_y;
00050 
00051 #ifdef DEBUG_OUT_
00052   ROS_INFO("DEGREE %d %d",nurbs_.ctrlPnts().cols(),nurbs_.ctrlPnts().rows());
00053 #endif
00054 
00055   //validate
00056 //  for(int i=0;i<3;++i){
00057 //    for(int j=0;j<3;++j){
00058 //      Eigen::Vector2f p;
00059 //      p(0)=i*0.5f;
00060 //      p(1)=j*0.5f;
00061 //      const float x = min_x + (max_x-min_x)*(i*0.5f);
00062 //      const float y = min_y + (max_y-min_y)*(j*0.5f);
00063 //      Eigen::Vector3f v;
00064 //      v(0)=x;
00065 //      v(1)=y;
00066 //      v(2)=params[0] + x*params[1] + x*x*params[2] + y*params[3] + y*y*params[4] + x*y*params[5];
00067 //      if(v.norm()<20) {
00068 //      float d=(_project2world(p)-v).norm();
00069 //      std::cout<<"dist "<<d<<std::endl;
00070 //      std::cout<<"n\n"<<_project2world(p)<<std::endl;
00071 //      std::cout<<"p\n"<<v<<std::endl;
00072 //      std::cout<<"np\n"<<_nextPoint(v)<<std::endl;
00073 //      d=(_project2world(_nextPoint(v))-v).norm();
00074 //      std::cout<<"dist "<<d<<std::endl;
00075 //      ROS_ASSERT(d<0.05f);
00076 //      }
00077 //    }
00078 //  }
00079 
00080   //nurbs_.writeVRML97("torus.wrl");
00081 
00082   //  Eigen::Vector2f p1, p2;
00083   //
00084   //  p1(0) = min_x;
00085   //  p1(1) = min_y;
00086   //
00087   //  p2=p1;
00088   //  p2(0) = max_x;
00089   //  plane_x_ = project2world(p2)-project2world(p1);
00090   //
00091   //  p2=p1;
00092   //  p2(1) = max_y;
00093   //  plane_y_ = project2world(p2)-project2world(p1);
00094   //
00095   //  plane_x_ /= plane_x_.squaredNorm();
00096   //  plane_y_ /= plane_y_.squaredNorm();
00097 }
00098 
00099 Eigen::Vector2f SurfaceNurbs::correct(const Eigen::Vector2f &pt) const {
00100   Eigen::Vector2f r;
00101   r(0) = c_x_m_*(pt(0) + c_x_o_);
00102   r(1) = c_y_m_*(pt(1) + c_y_o_);
00103   return r;
00104 }
00105 
00106 Eigen::Vector3f SurfaceNurbs::project2world(const Eigen::Vector2f &pt) const {
00107   return _project2world(correct(pt));
00108 }
00109 
00110 Eigen::Vector3f SurfaceNurbs::_project2world(const Eigen::Vector2f &pt) const {
00111   Eigen::Vector3f r;
00112   PlPoint3Df p = nurbs_.pointAt(pt(0),pt(1));
00113   r(0) = p.x();
00114   r(1) = p.y();
00115   r(2) = p.z();
00116   return r;
00117 }
00118 
00119 Eigen::Vector3f SurfaceNurbs::normalAt(const Eigen::Vector2f &v) const {
00120   return _normalAt(correct(v));
00121 }
00122 
00123 Eigen::Vector3f SurfaceNurbs::_normalAt(const Eigen::Vector2f &v) const {
00124   Eigen::Vector3f r;
00125   PlMatrix_Point3Df ders;
00126   nurbs_.deriveAt(v(0),v(1),1,ders);
00127   PlPoint3Df p = crossProduct(ders(0,1),ders(1,0));
00128   r(0) = p.x();
00129   r(1) = p.y();
00130   r(2) = p.z();
00131   r.normalize();
00132   return -r;
00133 }
00134 
00135 void SurfaceNurbs::transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr)
00136 {
00137   PlMatrix_float M(4,4);
00138   for(int i=0; i<3; i++)
00139   {
00140     for(int j=0; j<3; j++)
00141       M(i,j) = rot(i,j);
00142     M(i,3) = tr(i);
00143   }
00144   M(3,0)=M(3,1)=M(3,2)=0;
00145   M(3,3)=1;
00146 
00147   MatrixRTf T(M);
00148   //  std::cout<<T<<"\n";
00149   //  nurbs_.writeVRML97("A.wrl");
00150   //  std::cout<<nurbs_.ctrlPnts()<<"\n\n";
00151   nurbs_.transform(T);
00152   //  nurbs_.writeVRML97("B.wrl");
00153   //  std::cout<<nurbs_.ctrlPnts()<<"\n\n";
00154 }
00155 
00156 bool SurfaceNurbs::fitsCurvature(const Surface &o, const float thr) const
00157 {
00158   ROS_ASSERT(getSurfaceType()==getSurfaceType());
00159 
00160   return false;//TODO: return param_.col(2).cross(((SurfaceNurbs*)&o)->param_.col(2)).squaredNorm() < thr*thr;
00161 }
00162 
00163 size_t ___CTR___ = 0;
00164 
00165 int SurfaceNurbs::myprojectOn(const SURFACE &s, const Eigen::Vector3f &p, float &u, float &v, const int maxIt) const
00166 {
00167   PlMatrix_Point3Df ders;
00168   Eigen::Vector3f dx, dy, dz, t, d2;
00169   Eigen::Vector3f v3, q;
00170   Eigen::Vector2f v2;
00171   Eigen::Matrix3f M = Eigen::Matrix3f::Identity();
00172   //  Eigen::Matrix<float,3,2> H, G;
00173   float du, dv;
00174   int it = 0;
00175 
00176   while(it < maxIt)
00177   {
00178     //project p to plane -> q
00179     s.deriveAt(u,v,2,ders) ;
00180     dy(0) = ders(0,1).x();
00181     dy(1) = ders(0,1).y();
00182     dy(2) = ders(0,1).z();
00183     dx(0) = ders(1,0).x();
00184     dx(1) = ders(1,0).y();
00185     dx(2) = ders(1,0).z();
00186     d2(0) = ders(1,1).x();
00187     d2(1) = ders(1,1).y();
00188     d2(2) = ders(1,1).z();
00189     t(0) = ders(0,0).x();
00190     t(1) = ders(0,0).y();
00191     t(2) = ders(0,0).z();
00192 
00193     dz = dx.cross(dy);
00194     if(dz.squaredNorm()) dz.normalize();
00195 
00196     q = dz.dot(t-p)*dz + p - t;
00197 
00198     //solve q = dx*du + dy*dv
00199     M.col(0) = dx;
00200     M.col(1) = dy;
00201     //    M.col(2) = dz;
00202 
00203     v3 = M.inverse()*q;//M.llt().solve(q);
00204 
00205     //    const float k = (dx(0)*v3(0)*v3(0) + dx(1)*v3(1)*v3(0) + dy(0)*v3(0)*v3(1) + dy(1)*v3(1)*v3(1)) /
00206     //        (d2(0)*v3(0)*v3(0) + d2(1)*v3(1)*v3(0) + dz(0)*v3(0)*v3(1) + dz(1)*v3(1)*v3(1));
00207     //    cs = v3(0)*dx + v3(1)*dy;
00208     //    const float dt = (c.cros(q-p))/(k*std::pow(cs.norm(),3));
00209 
00210     du = v3(0);
00211     dv = v3(1);
00212 
00213     //    std::cout<<ders<<"\n";
00214 
00215     //    dx/=dx.norm();
00216     //    dy/=dy.norm();
00217 
00218     //    M.col(0) = dx;
00219     //    M.col(1) = dy;
00220     //    M.col(2) = dx.cross(dy);
00221     //
00222     //    t = (p-t);
00223     //    //t = M.transpose()*t;
00224     //    du = t(0);
00225     //    dv = t(1);
00226 
00227     //        v2(0) = u;
00228     //        v2(1) = v;
00229     //        t = _project2world(v2);
00230     //
00231     //        t+=du*dx;
00232     //        t+=dv*dy;
00233 
00234 
00235     //    std::cout<<"SN M\n"<<dx.dot(dy)<<"\n";
00236     //        std::cout<<"SN M\n"<<M.transpose()<<"\n";
00237     //        std::cout<<"SN M\n"<<M.transpose()*t<<"\n";
00238     //    std::cout<<"SN dot\n"<<q.dot(dz)<<"\n";
00239     //    std::cout<<"SN v3\n"<<v3<<"\n";
00240     //    std::cout<<"SN t\n"<<t<<"\n";
00241     //    std::cout<<"SN p\n"<<p<<"\n";
00242     //    std::cout<<"SN q\n"<<q<<"\n";
00243     //    std::cout<<"SN dx\n"<<dx<<"\n";
00244     //    std::cout<<"SN dy\n"<<dy<<"\n";
00245     //    std::cout<<"SN delta "<<du<<" "<<dv<<"\n";
00246 
00247     //    ROS_ASSERT(std::abs(q.dot(dz))<0.1f);
00248 
00249     u+=du;
00250     v+=dv;
00251 
00252     if(std::abs(du)+std::abs(dv)<0.00001f) {
00253       break;
00254     }
00255 
00256     ++it;
00257   }
00258   return 0;
00259 }
00260 
00262 Eigen::Vector2f SurfaceNurbs::nextPoint(const Eigen::Vector3f &v) const
00263 {
00264   Eigen::Vector2f r = _nextPoint(v);
00265   r(0) = r(0)/c_x_m_ - c_x_o_;
00266   r(1) = r(1)/c_y_m_ - c_y_o_;
00267   return r;
00268 }
00269 
00271 Eigen::Vector2f SurfaceNurbs::_nextPoint(const Eigen::Vector3f &v) const
00272 {
00273   ++___CTR___;
00274 #if 0
00275   Eigen::VectorXf r(2);
00276   r(0) = 0.5f;
00277   r(1) = 0.5f;
00278 
00279   std::cout<<"___________START_____________\n";
00280 
00281   Functor f(nurbs_);
00282   f._pt_.x() = v(0);
00283   f._pt_.y() = v(1);
00284   f._pt_.z() = v(2);
00285   Eigen::LevenbergMarquardt<Functor, float> lm(f);
00286   lm.parameters.maxfev = 50; //not to often (performance)
00287   lm.minimize(r);
00288 
00289   return r;
00290 
00291 #else
00292   PlPoint3Df p(v(0),v(1),v(2));
00293   float Ub, Vb, dist;
00294   int res2;
00295 
00296   for(int i=0; i<nurbs_.ctrlPnts().rows()-1; i++)
00297     for(int j=0; j<nurbs_.ctrlPnts().cols()-1; j++)
00298     {
00299 #if 0
00300       float U=(i+0.5f)/(nurbs_.ctrlPnts().rows()-1),
00301           V=(j+0.5f)/(nurbs_.ctrlPnts().cols()-1);
00302       int res = myprojectOn(nurbs_, v, U, V, 4);
00303       //      float U1=vals[i],V1=vals[j];
00304       //      nurbs_.projectOn(p, U1, V1, 50, -100.f, 100.f, -100.f, 100.f);
00305       //        std::cout<<"SN GT "<<U1<<" "<<V1<<"\n";
00306       //        std::cout<<"SN NA "<<U<<" "<<V<<"\n";
00307 
00308       Eigen::Vector2f r;
00309       r(0) = U;
00310       r(1) = V;
00311       float d = (_project2world(r)-v).squaredNorm();
00312 #else
00313       float U=(i+0.5f)/(nurbs_.ctrlPnts().rows()-1),
00314           V=(j+0.5f)/(nurbs_.ctrlPnts().cols()-1);
00315       int res = 1;
00316       Eigen::Vector3f vCP;
00317       vCP(0) = (nurbs_.ctrlPnts()(i,j).x()+nurbs_.ctrlPnts()(i+1,j).x()+nurbs_.ctrlPnts()(i,j+1).x()+nurbs_.ctrlPnts()(i+1,j+1).x())/4;
00318       vCP(1) = (nurbs_.ctrlPnts()(i,j).y()+nurbs_.ctrlPnts()(i+1,j).y()+nurbs_.ctrlPnts()(i,j+1).y()+nurbs_.ctrlPnts()(i+1,j+1).y())/4;
00319       vCP(2) = (nurbs_.ctrlPnts()(i,j).z()+nurbs_.ctrlPnts()(i+1,j).z()+nurbs_.ctrlPnts()(i,j+1).z()+nurbs_.ctrlPnts()(i+1,j+1).z())/4;
00320       float d = (v-vCP).squaredNorm();
00321 #endif
00322 
00323       //      std::cout<<d<<" "<<U<<" "<<V<<"\n";
00324 
00325       if((!j&&!i) || d<dist)
00326       {
00327         Ub = U;
00328         Vb = V;
00329         dist = d;
00330         res2=res;
00331       }
00332     }
00333 
00334   //  float U=0.25f, V=0.75f;
00335   //  myprojectOn(nurbs_, v, U, V, 3);
00336 
00337   //  std::cout<<"SN GT "<<Ub<<" "<<Vb<<"\n";
00338   //  std::cout<<"SN NA "<<U<<" "<<V<<"\n";
00339 
00340   //  Ub=0.5f;
00341   //  Vb=0.5f;
00342   //  nurbs_.minDist2(p, Ub, Vb, 0.0001f, 2.f, 5, 50, -100.f, 100.f, -100.f, 100.f);//nurbs_.projectOn(p, U, V, 100, -10000.f, 10000.f, -10000.f, 10000.f);
00343 
00344   //  std::cout<<"p1: "<<p<<"\n";
00345   //  std::cout<<"res: "<<res2<<"\n";
00346   //  std::cout<<"guess x: "<<plane_x_.dot(v)<<"\n";
00347   //  std::cout<<"guess y: "<<plane_y_.dot(v)<<"\n";
00348 
00349   myprojectOn(nurbs_, v, Ub, Vb, 30);
00350 
00351   Eigen::Vector2f r;
00352   r(0) = Ub;
00353   r(1) = Vb;
00354   return r;
00355 #endif
00356 }
00357 
00359 float SurfaceNurbs::merge(const Surface &o, const float this_w, const float o_w, const SWINDOW &wind_t, const SWINDOW &wind_o) {
00360   ROS_ASSERT(getSurfaceType()==o.getSurfaceType());
00361   return _merge(*(const SurfaceNurbs*)&o, this_w, o_w, wind_t, wind_o);
00362 }
00363 
00364 #define _INSERT(Xs,X) \
00365 if(!Xs.size()||Xs.back()<=X) \
00366 Xs.push_back(X); \
00367 else \
00368   for(int i=Xs.size()-1; i>=0; i--) \
00369     if(i<1||Xs[i-1]<=X) \
00370       {Xs.insert(Xs.begin()+i,X);break;}
00371 
00372 float SurfaceNurbs::_merge(SurfaceNurbs o, const float this_w, const float o_w, const SWINDOW &wind_t, const SWINDOW &wind_o) {
00373   const int SAMPLING = 1;
00374 
00375   float err=0.f;
00376 #if 1
00377 
00378   // 1. find overlapping points within [0,1] (SVD)
00379 
00380   Eigen::Vector2f wind_t1, wind_t2;
00381   Eigen::Vector2f wind_o1, wind_o2;
00382 
00383   wind_t1(0) = wind_t.min_x;
00384   wind_t1(1) = wind_t.min_y;
00385   wind_t2(0) = wind_t.max_x;
00386   wind_t2(1) = wind_t.max_y;
00387 
00388   wind_o1(0) = wind_o.min_x;
00389   wind_o1(1) = wind_o.min_y;
00390   wind_o2(0) = wind_o.max_x;
00391   wind_o2(1) = wind_o.max_y;
00392 
00393   wind_t1 = correct(wind_t1);
00394   wind_t2 = correct(wind_t2);
00395   wind_o1 = o.correct(wind_o1);
00396   wind_o2 = o.correct(wind_o2);
00397 
00398 #ifdef USE_NURBS_TRANSFORM_
00399   DOF6::TFLinkvf magic_box;
00400 #endif
00401 
00402   std::vector<float> us1, vs1;
00403   std::vector<float> us2, vs2;
00404 
00405 #ifdef USE_NURBS_TRANSFORM_
00406   for(int i=0; i<nurbs_.ctrlPnts().rows(); i++) {
00407     for(int j=0; j<nurbs_.ctrlPnts().cols(); j++) {
00408       Eigen::Vector2f v2;
00409       v2(0)=i/(float)(nurbs_.ctrlPnts().rows()-1) * (wind_t2(0)-wind_t1(0)) + wind_t1(0);
00410       v2(1)=j/(float)(nurbs_.ctrlPnts().cols()-1) * (wind_t2(1)-wind_t1(1)) + wind_t1(1);
00411       Eigen::Vector3f v = _project2world(v2);
00412 
00413       Eigen::Vector2f np = o._nextPoint(v);
00414       PlPoint2Df NP;
00415       NP.x()=np(0);
00416       NP.y()=np(1);
00417 
00418 //      std::cout<<NP.x()<<" "<<NP.y()<<"\n";
00419       float _u2 = (NP.x()-wind_o1(0))/(wind_o2(0)-wind_o1(0));
00420       float _v2 = (NP.y()-wind_o1(1))/(wind_o2(1)-wind_o1(1));
00421 
00422       if(_u2<=1.f && _u2>=0.f && _v2<=1.f && _v2>=0.f)
00423       {
00424         magic_box(
00425             DOF6::TFLinkvf::TFLinkObj(v, false,false),
00426             DOF6::TFLinkvf::TFLinkObj(o._project2world(np),false,false));
00427 
00428         //float u = i/(float)nurbs_.degreeU();
00429         //float v = j/(float)nurbs_.degreeV();
00430       }
00431 
00432     }
00433   }
00434 #endif
00435   us2.resize(o.nurbs_.ctrlPnts().rows(),0);
00436   vs2.resize(o.nurbs_.ctrlPnts().cols(),0);
00437 
00438   float miU=10, miV=10, maU=-10, maV=-10;
00439   for(int i=0; i<o.nurbs_.ctrlPnts().rows(); i++) {
00440     for(int j=0; j<o.nurbs_.ctrlPnts().cols(); j++) {
00441       Eigen::Vector2f v2;
00442       v2(0)=i/(float)(o.nurbs_.ctrlPnts().rows()-1) * (wind_o2(0)-wind_o1(0)) + wind_o1(0);
00443       v2(1)=j/(float)(o.nurbs_.ctrlPnts().cols()-1) * (wind_o2(1)-wind_o1(1)) + wind_o1(1);
00444       Eigen::Vector3f v = o._project2world(v2);
00445 
00446       Eigen::Vector2f np = _nextPoint(v);
00447       PlPoint2Df NP;
00448       NP.x()=np(0);
00449       NP.y()=np(1);
00450 
00451 //      std::cerr<<"err1 "<<(_project2world(np)-v).norm()<<"\n";
00452 //      std::cerr<<"err2 "<<(o._project2world(o._nextPoint(_project2world(np)))-v).norm()<<"\n";
00453 
00454       us2[i] += np(0);
00455       vs2[j] += np(1);
00456 
00457       float _u1 = (NP.x()-wind_t1(0))/(wind_t2(0)-wind_t1(0));
00458       float _v1 = (NP.y()-wind_t1(1))/(wind_t2(1)-wind_t1(1));
00459 
00460       if(_u1<=1.f && _u1>=0.f && _v1<=1.f && _v1>=0.f)
00461       {
00462 
00463 #ifdef USE_NURBS_TRANSFORM_
00464         magic_box(
00465             DOF6::TFLinkvf::TFLinkObj(_project2world(np),false,false),
00466             DOF6::TFLinkvf::TFLinkObj(v, false,false));
00467 #endif
00468 
00469       }
00470       else if( o._normalAt(v2).dot(_normalAt(np)) < .97f /*(v-_project2world(np)).squaredNorm()>0.02f*std::min(v.squaredNorm(),_project2world(np).squaredNorm())*/ ){
00471         miU = std::min(miU, NP.x());
00472         miV = std::min(miV, NP.y());
00473         maU = std::max(maU, NP.x());
00474         maV = std::max(maV, NP.y());
00475       }
00476 
00477     }
00478   }
00479   
00480   for(int j=0; j<nurbs_.ctrlPnts().rows(); j++) {
00481   float u = j/(float)(nurbs_.ctrlPnts().rows()-1) * (wind_t2(0)-wind_t1(0)) + wind_t1(0);
00482   _INSERT(us1,u);
00483   }
00484   for(int i=0; i<nurbs_.ctrlPnts().cols(); i++) {
00485   float v = i/(float)(nurbs_.ctrlPnts().cols()-1) * (wind_t2(1)-wind_t1(1)) + wind_t1(1);
00486   _INSERT(vs1,v);
00487   }
00488 
00489   for(int j=0; j<us2.size(); j++) {
00490     float u = us2[j]/o.nurbs_.ctrlPnts().cols();
00491     //std::cerr<<"u "<<u<<"\n";
00492     _INSERT(us1,u);
00493   }
00494   for(int i=0; i<vs2.size(); i++) {
00495     float v = vs2[i]/o.nurbs_.ctrlPnts().rows();
00496     //std::cerr<<"v "<<v<<"\n";
00497     _INSERT(vs1,v);
00498   }
00499 
00500 #if DOME
00501   sorteed
00502   for(int j=0; j<o.nurbs_.ctrlPnts().rows(); j++) {
00503   float u = j/(float)(o.nurbs_.ctrlPnts().rows()-1) * (wind_o2(0)-wind_o1(0)) + wind_o1(0);
00504   _INSERT(us1,u);
00505   }
00506   for(int i=0; i<o.nurbs_.ctrlPnts().cols(); i++) {
00507   float v = i/(float)(o.nurbs_.ctrlPnts().cols()-1) * (wind_o2(1)-wind_o1(1)) + wind_o1(1);
00508   _INSERT(vs1,v);
00509   }
00510 #endif
00511 
00512   int nU = std::max(nurbs_.ctrlPnts().rows(),o.nurbs_.ctrlPnts().rows());
00513   int nV = std::max(nurbs_.ctrlPnts().cols(),o.nurbs_.ctrlPnts().cols());
00514 
00515   const float offU = 0.03f*nU;
00516   const float offV = 0.03f*nV;
00517 
00518 #ifdef USE_NURBS_TRANSFORM_
00519   // 2. find and apply transformation to register both surfaces
00520   magic_box.finish();
00521 
00522   {
00523     Eigen::AngleAxisf aa;
00524     aa.fromRotationMatrix(magic_box.getRotation());
00525     Eigen::AngleAxisf aa2(0.5f*o_w/(this_w+o_w)*aa.angle(),aa.axis());
00526     transform(aa2.toRotationMatrix(), 0.5f*o_w/(this_w+o_w)*magic_box.getTranslation());
00527   }
00528 
00529   magic_box = magic_box.transpose();
00530 
00531   {
00532     Eigen::AngleAxisf aa;
00533     aa.fromRotationMatrix(magic_box.getRotation());
00534     Eigen::AngleAxisf aa2(0.5f*this_w/(this_w+o_w)*aa.angle(),aa.axis());
00535 
00536     //o.transform(magic_box.getRotation(),magic_box.getTranslation());
00537     o.transform(aa2.toRotationMatrix(), 0.5f*this_w/(this_w+o_w)*magic_box.getTranslation());
00538   }
00539 
00540   std::cout<<"OPTIMIZED MERGE\n"<<magic_box<<"\n";
00541 #endif
00542 
00543   //insert new knots
00544 
00545 //  if(miU<-offU) {nU++; us1.insert(us1.begin(),miU);}
00546 //  if(miV<-offV) {nV++; vs1.insert(vs1.begin(),miV);}
00547 //  if(maU>1.f+offU) {nU++; us1.push_back(maU);}
00548 //  if(maV>1.f+offV) {nV++; vs1.push_back(maV);}
00549 
00550 #if 1
00551   {
00552     float _miU, _maU, _miV, _maV;
00553     _miU = (miU-wind_t1(0))/(wind_t2(0)-wind_t1(0));
00554     _miV = (miV-wind_t1(1))/(wind_t2(1)-wind_t1(1));
00555     _maU = (maU-wind_t1(0))/(wind_t2(0)-wind_t1(0));
00556     _maV = (maV-wind_t1(1))/(wind_t2(1)-wind_t1(1));
00557   if(
00558       (_miU>1&&_maU>1) ||
00559       (_miV>1&&_maV>1) ||
00560       (_miU<0&&_maU<0) ||
00561       (_miV<0&&_maV<0)<0
00562       )
00563     return 100000.f;
00564 
00565     if(_miU<-offU)
00566     {
00567       nU++;
00568       //_INSERT(us1,miU);
00569     }
00570     if(_miV<-offV)
00571     {
00572       nV++;
00573       //_INSERT(vs1,miV);
00574     }
00575     if(_maU>1.f+offU)
00576     {
00577       nU++;
00578       //_INSERT(us1,maU);
00579     }
00580     if(_maV>1.f+offV)
00581     {
00582       nV++;
00583       //_INSERT(vs1,maV);
00584     }
00585   }
00586 #endif
00587 
00588 #if 0
00589     for(size_t i=0; i<(us1.size()-1)*SAMPLING+1; i++) {
00590       if(!(i%SAMPLING)) {
00591         std::cerr<<"u "<< us1[i/SAMPLING]<<"\n";
00592       }
00593       else {
00594         std::cerr<<"u "<< (us1[i/SAMPLING]*(SAMPLING-i%SAMPLING)+us1[i/SAMPLING+1]*(i%SAMPLING))/SAMPLING<<"\n";
00595       }
00596     }
00597     for(size_t j=0; j<(vs1.size()-1)*SAMPLING+1; j++) {
00598       if(!(j%SAMPLING)) {
00599         std::cerr<<"v "<<  vs1[j/SAMPLING]<<"\n";
00600       }
00601       else {
00602         std::cerr<<"v "<<  (vs1[j/SAMPLING]*(SAMPLING-j%SAMPLING)+vs1[j/SAMPLING+1]*(j%SAMPLING))/SAMPLING<<"\n";
00603       }
00604     }
00605 #endif
00606 
00607 //    if(miU<-offU) {nU++;}
00608 //    if(miV<-offV) {nV++;}
00609 //    if(maU>1.f+offU) {nU++;}
00610 //    if(maV>1.f+offV) {nV++;}
00611 
00612 //  ROS_ASSERT(us1.size()==us2.size());
00613 //  ROS_ASSERT(vs1.size()==vs2.size());
00614 
00615   // 3. create point grid with (m+j)x(n+k) points (mxn from surf. 1 and jxk from surf. 2)
00616 
00617   Matrix_Point3Df Pts((us1.size()-1)*SAMPLING+1,(vs1.size()-1)*SAMPLING+1);
00618 
00619   float n=0;
00620   bool inv=false;
00621   for(size_t i=0; i<(us1.size()-1)*SAMPLING+1; i++) {
00622     for(size_t j=0; j<(vs1.size()-1)*SAMPLING+1; j++) {
00623 
00624       Eigen::Vector2f np1,np2;
00625       Eigen::Vector3f v, v2;
00626 
00627       if(!(i%SAMPLING))
00628         np1(0) = us1[i/SAMPLING];
00629       else
00630         np1(0) = (us1[i/SAMPLING]*(SAMPLING-i%SAMPLING)+us1[i/SAMPLING+1]*(i%SAMPLING))/SAMPLING;
00631 
00632       if(!(j%SAMPLING))
00633         np1(1) = vs1[j/SAMPLING];
00634       else
00635         np1(1) = (vs1[j/SAMPLING]*(SAMPLING-j%SAMPLING)+vs1[j/SAMPLING+1]*(j%SAMPLING))/SAMPLING;
00636 
00637       v=_project2world(np1);
00638       np2 = o._nextPoint(v);
00639       v2= o._project2world(np2);
00640 
00641       float _u1 = (np1(0)-wind_t1(0))/(wind_t2(0)-wind_t1(0));
00642       float _u2 = (np2(0)-wind_o1(0))/(wind_o2(0)-wind_o1(0));
00643       float _v1 = (np1(1)-wind_t1(1))/(wind_t2(1)-wind_t1(1));
00644       float _v2 = (np2(1)-wind_o1(1))/(wind_o2(1)-wind_o1(1));
00645 
00646 //      float _u1 = us1[i];
00647 //      float _u2 = np2(0);
00648 //      float _v1 = vs1[i];
00649 //      float _v2 = np2(1);
00650 
00651       bool b1In = _u1>=0.f && _u1<=1.f && _v1>=0.f && _v1<=1.f;
00652       bool b2In = _u2>=0.f && _u2<=1.f && _v2>=0.f && _v2<=1.f;
00653 
00654 //      float w1 = b1In ? 1.f : (0.25f/((0.5f-_u1)*(0.5f-_u1) + (0.5f-_v1)*(0.5f-_v1))),
00655 //            w2 = b2In ? 1.f : (0.25f/((0.5f-_u2)*(0.5f-_u2) + (0.5f-_v2)*(0.5f-_v2)));
00656       float w1 = (0.25f/((0.5f-_u1)*(0.5f-_u1) + (0.5f-_v1)*(0.5f-_v1)+0.25f)),
00657             w2 = (0.25f/((0.5f-_u2)*(0.5f-_u2) + (0.5f-_v2)*(0.5f-_v2)+0.25f));
00658 
00659       err += (v-v2).norm()*std::min(w1,w2);
00660       n   += std::min(w1,w2);
00661 
00662       //Debug::Interface::get().addArrow(v,v2,200,255,110);
00663 
00664       //if(!(b1In^b2In))
00665         v = (w1*this_w*v + w2*o_w*v2)/(w1*this_w+w2*o_w);
00666       //else if(b2In)
00667       //  v = v2;
00668         //std::cerr<<"w "<<w1<<" "<<w2<<"\n";
00669         //ROS_ASSERT(w1+w2>0.1f);
00670 
00671         /*
00672       //merge if it is both inside/both outside
00673       if(!(b1In^b2In))
00674       {
00675         v2= o._project2world(np2);
00676         err = std::max(err, (v-v2).norm());
00677         //if((v-v2).norm()<0.02f*std::min(v.squaredNorm(),v2.squaredNorm()))
00678           v = (this_w*v + o_w*v2)/(this_w+o_w);
00679       }
00680       else if(b2In)
00681       {
00682         v2= o._project2world(np2);
00683         //if((v-v2).norm()<0.05f*std::min(v.squaredNorm(),v2.squaredNorm()))
00684           v = v2;
00685       }*/
00686 
00687       if(!pcl_isfinite(v.sum())) {
00688         inv=true;
00689         break;
00690       }
00691 
00692       Pts(i,j).x() = v(0);
00693       Pts(i,j).y() = v(1);
00694       Pts(i,j).z() = v(2);
00695     }
00696   }
00697 
00698   err /= n;
00699 
00700   if(inv) {
00701     ROS_WARN("invalid");
00702     return 10000.f;
00703   }
00704 
00705   Eigen::Vector2f t2;
00706   t2(0) = 0.;
00707   t2(1) = 0.f;
00708   Eigen::Vector3f test = _project2world(t2);
00709 
00710 //  ROS_INFO("degree %d %d",Pts.cols(),Pts.rows());
00711 //  ROS_INFO("degree before %d %d",nurbs_.ctrlPnts().cols(),nurbs_.ctrlPnts().rows());
00712   //nurbs_.globalInterp(Pts,2,2);
00713   nurbs_.leastSquares(Pts,2,2, nU, nV);
00714   //PLib::globalSurfApprox(Pts, 2, 2, nurbs_, 0.05);
00715 //  ROS_INFO("degree after  %d %d",nurbs_.ctrlPnts().cols(),nurbs_.ctrlPnts().rows());
00716 //  ROS_INFO("nurbs error  %f",err);
00717 
00718 //  std::cout<<"2D\n"<<t2<<"\n";
00719 //  t2 = _nextPoint(test);
00720 //  std::cout<<"2D\n"<<t2<<"\n";
00721 //  std::cout<<"3D1\n"<<test<<"\n";
00722 //  std::cout<<"3D2\n"<<_project2world(t2)<<"\n";
00723 //  std::cout<<"3D3\n"<<Pts(0,0)<<"\n";
00724 
00725 #else
00726 
00727   Matrix_Point3Df Pts(3,3);
00728   for(int i=0;i<3;++i){
00729     for(int j=0;j<3;++j){
00730       const float x = (i*0.5f);
00731       const float y = (j*0.5f);
00732       Pts(i,j) = nurbs_.pointAt(x,y);
00733     }
00734   }
00735 
00736   for(int i=0;i<3;++i){
00737     for(int j=0;j<3;++j){
00738       float x = (i*0.5f);
00739       float y = (j*0.5f);
00740 
00741       o.nurbs_.minDist2(Pts(i,j), x, y, 0.00001f, 100.f, 20, 100, -10000.f, 10000.f, -10000.f, 10000.f); //perhaps check distance?
00742       Pts(i,j) = (this_w*Pts(i,j) + o_w*o.nurbs_.pointAt(x,y))/(this_w+o_w);
00743 
00744 
00745       //      Eigen::Vector3f v;
00746       //      v(0)=Pts(i,j).x();
00747       //      v(1)=Pts(i,j).y();
00748       //      v(2)=Pts(i,j).z();
00749       //      Eigen::Vector2f np = o.nextPoint(v);
00750       //      //o.nurbs_.minDist2(Pts(i,j), x, y, 0.00001f, 100.f, 20, 100, -10000.f, 10000.f, -10000.f, 10000.f); //perhaps check distance?
00751       //      v = (this_w*v + o_w*o.project2world(np))/(this_w+o_w);
00752       //      Pts(i,j).x() = v(0);
00753       //      Pts(i,j).y() = v(1);
00754       //      Pts(i,j).z() = v(2);
00755     }
00756   }
00757 
00758   nurbs_.globalInterp(Pts,2,2);
00759 #endif
00760   return err;
00761 }
00762 
00763 float SurfaceNurbs::_merge2(SurfaceNurbs o, const float this_w, const float o_w, const SWINDOW &wind_t, const SWINDOW &wind_o) {
00764   const int SAMPLING = 10;
00765 #if 0
00766   //generate grid
00767   PT_GRID ga(nurbs_,SAMPLING), gb(o.nurbs_,SAMPLING);
00768 
00769   pcl::PointCloud<pcl::PointXYZ> pc;
00770   pcl::PointXYZ pt;
00771   pcl::PCA<pcl::PointXYZ> pca;
00772 
00773   for(int x=0; x<ga.w; x++) {
00774     for(int y=0; y<ga.h; y++) {
00775       Eigen::Vector2f v;
00776       v(0) = x/(float)(ga.w-1);
00777       v(1) = y/(float)(ga.h-1);
00778       Eigen::Vector3f p = _project2world(v);
00779       ga(x,y) = p;
00780       pt.x=p(0);pt.y=p(1);pt.z=p(2);
00781       pc.push_back(pt);
00782     }
00783   }
00784 
00785   for(int x=0; x<gb.w; x++) {
00786     for(int y=0; y<gb.h; y++) {
00787       Eigen::Vector2f v;
00788       v(0) = x/(float)(gb.w-1);
00789       v(1) = y/(float)(gb.h-1);
00790       Eigen::Vector3f p = o._project2world(v);
00791       gb(x,y) = p;
00792       pt.x=p(0);pt.y=p(1);pt.z=p(2);
00793       pc.push_back(pt);
00794     }
00795   }
00796 
00797   pca.compute(pc);
00798   int c1=0;
00799   if(pca.getEigenValues()(c1)<pca.getEigenValues()(1)) c1=1;
00800   if(pca.getEigenValues()(c1)<pca.getEigenValues()(2)) c1=2;
00801 
00802   int found, pos_x, pos_y;
00803   Eigen::Vector3f n,m;
00804   n=pca.getEigenVectors().col(c1);
00805 
00806   std::vector< std::vector<Eigen::Vector3f> > lines1;
00807   m=pca.getMean();
00808   pos_y=pos_x=0;
00809   do {
00810     lines1.push_back(std::vector<Eigen::Vector3f>());
00811     found=0;
00812 
00813     for(int x=0; x<ga.w-1; x++) {
00814       float f=n.dot(p3-ga(x,pos_y))/n.dot(ga(x+1,pos_y)-ga(x,pos_y));
00815       if(f>=0&&f<1) {
00816         break;df
00817       }
00818     }
00819 
00820     m+=n/SAMPLING;
00821   } while(found>0);
00822 #endif
00823   float err=0.f;
00824   return err;
00825 }


cob_3d_mapping_slam
Author(s): Joshua Hampp
autogenerated on Wed Aug 26 2015 11:04:51