form.h
Go to the documentation of this file.
00001 /*
00002  * form.h
00003  *
00004  *  Created on: 18.07.2012
00005  *      Author: josh
00006  */
00007 
00008 #ifndef FORM_H_
00009 #define FORM_H_
00010 
00011 #include "polygon_merger.h"
00012 
00013 namespace Slam_CurvedPolygon
00014 {
00015 
00016   class Outline
00017   {
00018 
00019     static void debug_svg_text(FILE *fp, float x, float y, float e, const char *color) {
00020       char buffer[1024];
00021       sprintf(buffer,"<text x=\"%f\" y=\"%f\"  style=\"stroke:%s; stroke-width:2px;\">%.2f</text>",x,y,color,e);
00022       fputs(buffer,fp);
00023     }
00024     static void debug_svg_line(FILE *fp, float x, float y, float x2, float y2, float e, const char *color="black") {
00025       char buffer[1024];
00026       sprintf(buffer,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke:%s; stroke-width:2px;\" />",x,y,x2,y2,color);
00027       if(pcl_isfinite(e))
00028         debug_svg_text(fp,(x+x2)/2,(y+y2)/2,e,color);
00029       fputs(buffer,fp);
00030     }
00031     static void debug_svg_line(FILE *fp, float x, float y, float x2, float y2,  const char *color="black") {
00032       char buffer[1024];
00033       sprintf(buffer,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke:%s; stroke-width:2px;\" />",x,y,x2,y2,color);
00034       fputs(buffer,fp);
00035     }
00036 
00037   public:
00038     std::vector<Eigen::Vector3f> segments_;
00039     float weight_;
00040     bool open_;
00041 
00042     Outline(): weight_(1.f), open_(false)
00043     {}
00044 
00045     void operator+=(const Eigen::Vector3f &v) {
00046       segments_.push_back(v);
00047       if(!pcl_isfinite(segments_.back()(2)) ) {
00048         std::cout<<"v is not finite\n"<<segments_.back()<<std::endl;
00049         ROS_ERROR("v is not finite");
00050         segments_.back()(2) = 0.f;
00051       }
00052     }
00053 
00054     struct OUTPUTSVG {
00055       FILE *fp;
00056       std::string fn;
00057 
00058       OUTPUTSVG(const char *fn):fn(fn) {
00059         fp=fopen((std::string("/tmp/")+fn).c_str(),"w");
00060         fputs("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\" ?>",fp);
00061         fputs("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">",fp);
00062         fputs("<svg width=\"1640\" height=\"1480\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">",fp);
00063       }
00064 
00065       ~OUTPUTSVG()
00066       {
00067         fputs("</svg>",fp);
00068         fclose(fp);
00069       }
00070     };
00071 
00072     boost::shared_ptr<OUTPUTSVG> debug_svg(const char *fn, const float f=100, const float o=300, const char *color="black") const {
00073       boost::shared_ptr<OUTPUTSVG> out(new OUTPUTSVG(fn));
00074       return debug_svg(out,f,o, color);
00075     }
00076 
00077     boost::shared_ptr<OUTPUTSVG> debug_svg(boost::shared_ptr<OUTPUTSVG> out, const float f=100, const float o=300, const char *color="black") const {
00078       FILE *fp2=fopen((std::string("/tmp/data_")+out->fn+".txt").c_str(),"a");
00079 
00080       fprintf(fp2,"\n\n");
00081 
00082       for(size_t i=0; i<segments_.size(); i++)
00083       {
00084         Eigen::Vector2f p=segments_[(i+1)%segments_.size()].head<2>();
00085         Eigen::Vector2f p2=segments_[i].head<2>();
00086         Eigen::Vector2f d=p2-p;
00087         debug_svg_line(out->fp, segments_[i](0)*f+o, segments_[i](1)*f+o,
00088                        segments_[(i+1)%segments_.size()](0)*f+o, segments_[(i+1)%segments_.size()](1)*f+o
00089                        ,segments_[(i+1)%segments_.size()](2)/weight_
00090                        ,color
00091         );
00092         debug_svg_line(out->fp, p(0)*f+o,p(1)*f+o,
00093                        (p(0)+0.1*d(0)+0.1*d(1))*f+o,(p(1)+0.1*d(1)-0.1*d(0))*f+o,color);
00094         debug_svg_line(out->fp, p(0)*f+o,p(1)*f+o,
00095                        (p(0)+0.1*d(0)-0.1*d(1))*f+o,(p(1)+0.1*d(1)+0.1*d(0))*f+o,color);
00096         debug_svg_text(out->fp,p2(0)*f+o,p2(1)*f+o,i,color);
00097 
00098         fprintf(fp2,"ADD_POINT(OUTLINE, %f,%f, \t%f);\n",segments_[i](0),segments_[i](1),segments_[i](2));
00099       }
00100 
00101       fclose(fp2);
00102       return out;
00103     }
00104 
00105     struct COR
00106     {
00107       bool other;
00108       size_t ind;
00109       Eigen::Vector3f p;
00110     };
00111 
00112     template<typename T>
00113     static size_t nextLine(const std::vector<T> &segments_, const Eigen::Vector2f &p, const Eigen::Vector2f &n, T &r) {
00114       size_t ind = (size_t)-1;
00115       Eigen::Matrix2f M;
00116       M.col(0) = n;
00117       float mi = std::numeric_limits<float>::max();
00118       for(size_t i=0; i<segments_.size(); i++)
00119       {
00120         Eigen::Vector2f p3 = segments_[i].head(2);
00121         Eigen::Vector2f p4 = segments_[(i+1)%segments_.size()].head(2);
00122 
00123         M.col(1) = p3-p4;
00124 
00125         Eigen::Vector2f m = (M.inverse()*(p3-p));
00126         float d;
00127 
00128         if(m(1)>=0.f && m(1)<=1.f)
00129           d = (m(0)*n).squaredNorm();
00130         if(m(1)<0)
00131           d = (p3-p).squaredNorm();
00132         else
00133           d = (p4-p).squaredNorm();
00134 
00135         //        std::cout<<" "<<i<<"  "<<m(0)<<"  "<<m(1)<<"\n";
00136 
00137         if(d<mi)
00138         {
00139           mi = d;
00140           ind = (i+1)%segments_.size();
00141           if(m(1)>0.f && m(1)<1.f) {
00142             r.head(2) = m(0)*n+p;
00143             r(2) = segments_[ind](2);
00144             r(3) = segments_[ind](3);
00145           }
00146           else if(m(1)<=0) {
00147             r.head(2) = p3;
00148             r(2) = std::max(segments_[ind](2),segments_[i](2));
00149             if(segments_[ind](2)>segments_[i](2))
00150               r(3) = segments_[ind](3);
00151             else
00152               r(3) = segments_[i](3);
00153             ind = i;
00154           }
00155           else {
00156             r.head(2) = p4;
00157             r(2) = std::max(segments_[ind](2),segments_[(ind+1)%segments_.size()](2));
00158             if(segments_[ind](2)>segments_[(ind+1)%segments_.size()](2))
00159               r(3) = segments_[ind](3);
00160             else
00161               r(3) = segments_[(ind+1)%segments_.size()](3);
00162           }
00163         }
00164         //m(0) =
00165         //        (
00166         //  (p1(0)*p2(1)-p1(0)*p2(0))*(p3(0)-p4(0)) -
00167         //(p1(0)-p2(0))*(p3(0)*p4(1);
00168       }
00169       return ind;
00170     }
00171 
00172     size_t _nextPoint(const Eigen::Vector2f &p) const {
00173       size_t ind = (size_t)-1;
00174       float mi = std::numeric_limits<float>::max();
00175       for(size_t i=0; i<segments_.size(); i++)
00176       {
00177         const float d= (segments_[i].head<2>()-p).squaredNorm();
00178 
00179         if(d<mi)
00180         {
00181           mi = d;
00182           ind = i;
00183         }
00184       }
00185       return ind;
00186     }
00187 
00188     size_t _nextPoint2(const Eigen::Vector2f &p, Eigen::Vector2f &r) const {
00189       size_t ind = (size_t)-1;
00190       float mi = std::numeric_limits<float>::max();
00191       for(size_t i=0; i<segments_.size(); i++)
00192       {
00193         Eigen::Vector2f p1 = segments_[i].head<2>();
00194         Eigen::Vector2f p2 = segments_[(i+1)%segments_.size()].head<2>();
00195 
00196         Eigen::Vector2f d1 = (p-p1);
00197         Eigen::Vector2f d2 = p2-p1;
00198         float f = d1.dot(d2)/d2.squaredNorm();
00199         float d;
00200         Eigen::Vector2f n;
00201 
00202         size_t tmp = i+1;
00203         if(f>=1){
00204           d = (p-p2).norm();
00205           n = p2-p;
00206         }
00207         else if(f<=0) {
00208           d = (p-p1).norm();
00209           n = p1-p;
00210           tmp--;
00211         }
00212         else {
00213           d = (d1(0)*d2(1)-d1(1)*d2(0))/(d2).norm();
00214           n(0) = -(p2(1)-p1(1));
00215           n(1) = (p2(0)-p1(0));
00216         }
00217 
00218         if(d<mi)
00219         {
00220           mi = d;
00221           ind = tmp;
00222           r = n+p;
00223         }
00224       }
00225       return ind;
00226     }
00227 
00228     operator std::vector<Eigen::Vector4f>() const {
00229       std::vector<Eigen::Vector4f> r;
00230       for(size_t i=0; i<size(); i++)
00231       {
00232         Eigen::Vector4f v;
00233         v.head<3>() = (*this)[i];
00234         v(3) = weight_;
00235         r.push_back(v);
00236       }
00237       return r;
00238     }
00239 
00240     static size_t _hasIntersection(const std::vector<Eigen::Vector4f> &segments_, const Eigen::Vector2f &p1, const Eigen::Vector2f &p2, const bool open=false) {
00241       Eigen::Matrix2f M;
00242       M.col(0) = p2-p1;
00243       for(size_t i=0; i<segments_.size()-(open?1:0); i++)
00244       {
00245         Eigen::Vector2f p3 = segments_[i].head(2);
00246         Eigen::Vector2f p4 = segments_[(i+1)%segments_.size()].head(2);
00247         M.col(1) = p3-p4;
00248 
00249         Eigen::Vector2f m = (M.inverse()*(p3-p1));
00250 
00251         if(m(0)>0.001&&m(0)<0.99999 && m(1)>0.001&&m(1)<0.99999) {
00252 //          ROS_ERROR("intersection %f %f",m(0),m(1));
00253 //          std::cerr<<m(0)*M.col(0)+p1<<"\n";
00254 //          std::cerr<<m(1)*M.col(1)+p3<<"\n";
00255           return i+1;
00256         }
00257       }
00258       return 0;
00259     }
00260 
00261     static size_t _nextPoint3(const std::vector<Eigen::Vector4f> &segments_, const Eigen::Vector2f &p, Eigen::Vector4f &r, const bool open=false) {
00262       size_t ind = (size_t)-1;
00263       float mi = std::numeric_limits<float>::max();
00264       for(size_t i=0; i<segments_.size()-(open?1:0); i++)
00265       {
00266         Eigen::Vector2f p1 = segments_[i].head<2>();
00267         Eigen::Vector2f p2 = segments_[(i+1)%segments_.size()].head<2>();
00268 
00269         Eigen::Vector2f d1 = (p-p1);
00270         Eigen::Vector2f d2 = p2-p1;
00271         float f = d1.dot(d2)/(d2.squaredNorm());
00272         float d;
00273         Eigen::Vector2f n;
00274 
00275         size_t tmp = i+1;
00276         if(f>0&&f<1) {
00277           d = (d1(0)*d2(1)-d1(1)*d2(0))/(d2).norm();
00278           n = f*d2 + p1;
00279         }
00280         else if(f>=1){
00281           d = (p-p2).norm();
00282           n = p2;
00283         }
00284         else {
00285           d = (p-p1).norm();
00286           n = p1;
00287           tmp--;
00288         }
00289 
00290         if(d<mi)
00291         {
00292           //check if line intersects itself
00293           if(_hasIntersection(segments_,p,n))
00294             continue;
00295 
00296           mi = d;
00297           ind = tmp;
00298           r.head<2>() = n;
00299           if(f>0&&f<1) {
00300             r(2) = segments_[(i+1)%segments_.size()](2);
00301             r(3) = segments_[(i+1)%segments_.size()](3);
00302           }
00303           else if(f>=1){
00304             if( segments_[(i+1)%segments_.size()](2)/segments_[(i+1)%segments_.size()](3) >
00305             segments_[(i+2)%segments_.size()](2)/segments_[(i+2)%segments_.size()](3)) {
00306               r(2) = segments_[(i+1)%segments_.size()](2);
00307               r(3) = segments_[(i+1)%segments_.size()](3);
00308             } else {
00309               r(2) = segments_[(i+2)%segments_.size()](2);
00310               r(3) = segments_[(i+2)%segments_.size()](3); }
00311           }
00312           else{
00313             if( segments_[(i+1)%segments_.size()](2)/segments_[(i+1)%segments_.size()](3) >
00314             segments_[i](2)/segments_[i](3)) {
00315               r(2) = segments_[(i+1)%segments_.size()](2);
00316               r(3) = segments_[(i+1)%segments_.size()](3);
00317             } else {
00318               r(2) = segments_[i](2);
00319               r(3) = segments_[i](3); }
00320           }
00321         }
00322       }
00323       return ind;
00324     }
00325 
00326     static void run2(const std::vector<Eigen::Vector4f> &segments_, const std::vector<Eigen::Vector4f> &o, const size_t begin, const size_t end, Outline &res, const bool proc=true) {
00327       size_t last_ind, start_ind;
00328       bool start = true;
00329       Eigen::Vector3f r2;
00330 
00331       //      ROS_ERROR("%d %d",begin, end);
00332       for(size_t j=begin; j<(end>begin?end:end+segments_.size()); j++)
00333       {
00334         size_t i = j%segments_.size();
00335 
00336         Eigen::Vector2f n1,n2;
00337         Eigen::Vector4f r;
00338         n1=segments_[i].head<2>()-segments_[(i-1+segments_.size())%segments_.size()].head<2>();
00339         n1.normalize();
00340         n2=segments_[(i+1)%segments_.size()].head<2>()-segments_[i].head<2>();
00341         n2.normalize();
00342         n2+=n1;
00343         n1(0) = -n2(1);
00344         n1(1) =  n2(0);
00345         size_t ind = nextLine(o, segments_[i].head<2>(), n1, r);
00346         if(ind!=(size_t)-1) {
00347           //          ROS_ERROR("%d",ind);
00348           if(!start && ind!=last_ind && proc) {
00349             run2(o, segments_, last_ind, ind, res, false);
00350             //            if(ind<last_ind) return;
00351             //            ROS_ASSERT(ind>=last_ind);
00352           }
00353           else if(start) {
00354             start = false;
00355             start_ind = ind;
00356           }
00357           last_ind = ind;
00358 
00359           const float p1 = std::max(segments_[i](2), segments_[(i+1)%segments_.size()](2))+0.001f;
00360           float weight;
00361           if(segments_[i](2)>segments_[(i+1)%segments_.size()](2))
00362             weight = segments_[i](3);
00363           else
00364             weight = segments_[(i+1)%segments_.size()](3);
00365           const float p2 = r(2)+0.001f;
00366 
00367           const float ramp = std::max((p1-0.001f)/weight,r(2)/r(3));
00368           const bool out = n1.dot(r.head<2>()-segments_[i].head<2>())<0;
00369           const float w1 = (!out?1.f:ramp);
00370           const float w2 = (out?1.f:ramp);
00371           r2.head<2>() = w1*p2/(w2*p1+w1*p2)*(r.head<2>()-segments_[i].head<2>()) + segments_[i].head<2>();
00372           r2(2) = (p1+p2-0.002f)/(weight+r(3));
00373 
00374           res += r2;
00375 
00376           //          static int ctr=0;
00377           //          char buf[128];
00378           //          sprintf(buf,"%d.svg",ctr++);
00379           //          res.debug_svg(buf);
00380         }
00381         //        else
00382         //          ROS_ASSERT(0);
00383       }
00384       if(start_ind!=last_ind&&proc)
00385         run2(o, segments_, last_ind, start_ind, res, false);
00386     }
00387 
00388 #if 0
00389     void run(const Outline &o, const size_t begin, const size_t end, Outline &res, const bool proc=true) const {
00390       size_t last_ind, start_ind;
00391       bool start = true;
00392       Eigen::Vector3f r2;
00393 
00394       ROS_ERROR("%d %d",begin, end);
00395       for(size_t j=begin; j<(end>begin?end:end+segments_.size()); j++)
00396       {
00397         size_t i = j%segments_.size();
00398 
00399         Eigen::Vector2f n1,n2;
00400         Eigen::Vector3f r;
00401         n1=segments_[i].head<2>()-segments_[(i-1+segments_.size())%segments_.size()].head<2>();
00402         n1.normalize();
00403         n2=segments_[(i+1)%segments_.size()].head<2>()-segments_[i].head<2>();
00404         n2.normalize();
00405         n2+=n1;
00406         n1(0) = -n2(1);
00407         n1(1) =  n2(0);
00408         size_t ind = o.nextLine(segments_[i].head<2>(), n1, r);
00409         if(ind!=(size_t)-1) {
00410           ROS_ERROR("%d",ind);
00411           if(!start && ind!=last_ind && proc) {
00412             o.run(*this, last_ind, ind, res, false);
00413             //            if(ind<last_ind) return;
00414             //            ROS_ASSERT(ind>=last_ind);
00415           }
00416           else if(start) {
00417             start = false;
00418             start_ind = ind;
00419           }
00420           last_ind = ind;
00421 
00422           const float p1 = std::max(segments_[i](2), segments_[(i+1)%segments_.size()](2))+0.001f;
00423           const float p2 = r(2)+0.001f;
00424 
00425           const float ramp = std::max((p1-0.001f)/weight_,(p2-0.001f)/o.weight_);
00426           const bool out = n1.dot(r.head<2>()-segments_[i].head<2>())<0;
00427           const float w1 = (!out?1.f:ramp);
00428           const float w2 = (out?1.f:ramp);
00429           r2.head<2>() = w1*p2/(w2*p1+w1*p2)*(r.head<2>()-segments_[i].head<2>()) + segments_[i].head<2>();
00430           r2(2) = (p1+p2-0.002f)/(o.weight_+weight_);
00431 
00432           res += r2;
00433 
00434           //          static int ctr=0;
00435           //          char buf[128];
00436           //          sprintf(buf,"%d.svg",ctr++);
00437           //          res.debug_svg(buf);
00438         }
00439         //        else
00440         //          ROS_ASSERT(0);
00441       }
00442       if(start_ind!=last_ind&&proc)
00443         o.run(*this, last_ind, start_ind, res, false);
00444     }
00445 #endif
00446 
00447 #if 0
00448     void run(const Outline &o, const size_t begin, const size_t end, Outline &res, const bool proc=true) const {
00449       size_t last_ind, start_ind;
00450       bool start = true;
00451       Eigen::Vector3f r2;
00452 
00453       ROS_ERROR("%d %d",begin, end);
00454       for(size_t j=begin; j<(end>begin?end:end+segments_.size()); j++)
00455       {
00456         size_t i = j%segments_.size();
00457 
00458         size_t ind = o._nextPoint(segments_[i].head<2>());
00459         if(ind!=(size_t)-1) {
00460           ROS_ERROR("%d",ind);
00461           if(!start && ind!=last_ind && proc) {
00462             o.run(*this, last_ind+1, ind, res, false);
00463             //            if(ind<last_ind) return;
00464             //            ROS_ASSERT(ind>=last_ind);
00465           }
00466           else if(start) {
00467             start = false;
00468             start_ind = ind;
00469           }
00470           last_ind = ind;
00471 
00472           Eigen::Vector2f n = segments_[i].head<2>()-segments_[(i+1)%segments_.size()].head<2>();
00473           std::swap(n(0),n(1));
00474           n(0) = -n(0);
00475 
00476           const float p1 = std::max(segments_[i](2), segments_[(i+1)%segments_.size()](2))+0.001f;
00477           const float p2 = std::max(o.segments_[ind](2), o.segments_[(ind+1)%segments_.size()](2))+0.001f;
00478 
00479           const float ramp = std::max((p1-0.001f)/weight_,(p2-0.001f)/o.weight_);
00480           const bool out = n.dot(o.segments_[ind].head<2>()-segments_[i].head<2>())<0;
00481           const float w1 = (!out?1.f:ramp);
00482           const float w2 = (out?1.f:ramp);
00483           r2.head<2>() = w1*p2/(w2*p1+w1*p2)*(o.segments_[ind].head<2>()-segments_[i].head<2>()) + segments_[i].head<2>();
00484           r2(2) = (p1+p2-0.002f)/(o.weight_+weight_);
00485 
00486           res += r2;
00487 
00488           //          static int ctr=0;
00489           //          char buf[128];
00490           //          sprintf(buf,"%d.svg",ctr++);
00491           //          res.debug_svg(buf);
00492         }
00493         //        else
00494         //          ROS_ASSERT(0);
00495       }
00496       if(start_ind!=last_ind&&proc)
00497         o.run(*this, last_ind+1, start_ind, res, false);
00498     }
00499 #endif
00500 
00501 #if 0
00502     void run(const Outline &o, const size_t begin, const size_t end, Outline &res, const bool proc=true) const {
00503       size_t last_ind, start_ind;
00504       bool start = true;
00505       Eigen::Vector3f r2;
00506 
00507       ROS_ERROR("%d %d",begin, end);
00508       for(size_t j=begin; j<(end>begin?end:end+segments_.size()); j++)
00509       {
00510         size_t i = j%segments_.size();
00511 
00512         size_t ind = o._nextPoint2(segments_[i].head<2>());
00513         if(ind!=(size_t)-1) {
00514           ROS_ERROR("%d",ind);
00515           if(!start && ind!=last_ind && proc) {
00516             o.run(*this, last_ind+1, ind, res, false);
00517             //            if(ind<last_ind) return;
00518             //            ROS_ASSERT(ind>=last_ind);
00519           }
00520           else if(start) {
00521             start = false;
00522             start_ind = ind;
00523           }
00524           last_ind = ind;
00525 
00526           Eigen::Vector2f n = segments_[i].head<2>()-segments_[(i+1)%segments_.size()].head<2>();
00527           std::swap(n(0),n(1));
00528           n(0) = -n(0);
00529 
00530           const float p1 = std::max(segments_[i](2), segments_[(i+1)%segments_.size()](2))+0.001f;
00531           const float p2 = std::max(o.segments_[ind](2), o.segments_[(ind+1)%segments_.size()](2))+0.001f;
00532 
00533           const float ramp = std::max((p1-0.001f)/weight_,(p2-0.001f)/o.weight_);
00534           const bool out = n.dot(o.segments_[ind].head<2>()-segments_[i].head<2>())<0;
00535           const float w1 = (!out?1.f:ramp);
00536           const float w2 = (out?1.f:ramp);
00537           r2.head<2>() = w1*p2/(w2*p1+w1*p2)*(o.segments_[ind].head<2>()-segments_[i].head<2>()) + segments_[i].head<2>();
00538           r2(2) = (p1+p2-0.002f)/(o.weight_+weight_);
00539 
00540           res += r2;
00541 
00542           //          static int ctr=0;
00543           //          char buf[128];
00544           //          sprintf(buf,"%d.svg",ctr++);
00545           //          res.debug_svg(buf);
00546         }
00547         //        else
00548         //          ROS_ASSERT(0);
00549       }
00550       if(start_ind!=last_ind&&proc)
00551         o.run(*this, last_ind+1, start_ind, res, false);
00552     }
00553 #endif
00554 
00555     bool isPointIn(const Eigen::Vector2f &pt) const {
00556       bool c=false;
00557       size_t j=segments_.size()-1;
00558       for(size_t i=0; i<segments_.size(); i++)
00559       {
00560         if( (segments_[i](1)>pt(1))!=(segments_[j](1)>pt(1)) &&
00561             (pt(0)<(segments_[j](0)-segments_[i](0))*(pt(1)-segments_[i](1))/(segments_[j](1)-segments_[i](1))+segments_[i](0))
00562         )
00563           c=!c;
00564         j=i;
00565       }
00566       return c;
00567     }
00568 
00569     bool check() const {
00570       bool ASS=true;
00571 
00572       for(size_t i=0; i<size(); i++)
00573       {
00574         size_t id = _hasIntersection(*this, (*this)[i].head<2>(), (*this)[(i+1)%size()].head<2>());
00575         if(id && id-1!=i) {
00576           ROS_ERROR("err at %d (%d)",i,id-1);
00577           ASS=false;
00578           break;
00579         }
00580       }
00581 
00582       if(!ASS) {
00583         char buffer[128];
00584         static int n=0;
00585         sprintf(buffer, "error%d.svg",n++);
00586         debug_svg(buffer,300,600);
00587       }
00588 
00589       return ASS;
00590     }
00591 
00592     void run(const Outline &o, const size_t begin, const size_t end, Outline &res, const bool proc=true) const {
00593       std::vector<Eigen::Vector4f> inner, outer;
00594 
00595       std::vector<Eigen::Vector4f> l1, l2;
00596       int type = -1;
00597 
00598       //start with point inside
00599       bool found=false, found1;
00600       size_t i=0;
00601       for(; i<segments_.size(); i++)
00602       {
00603         if(o.isPointIn(segments_[i].head<2>())) {
00604           found=true;
00605           break;
00606         }
00607       }
00608       found1 = found;
00609 
00610       if(found==false)
00611       {
00612         for(size_t i=0; i<o.segments_.size(); i++)
00613         {
00614           if(isPointIn(o.segments_[i].head<2>())) {
00615             found=true;
00616             break;
00617           }
00618         }
00619       }
00620 
00621       if(found)
00622       {
00623 
00624         bool other=false;
00625         size_t j=0, last_j=0, start_j=0;
00626         for(size_t kk=0; kk<segments_.size(); kk++)
00627         {
00628           i%=segments_.size();
00629 
00630           Eigen::Matrix2f M;
00631           Eigen::Vector2f p1 = segments_[i].head<2>();
00632           Eigen::Vector2f p2 = segments_[(i+1)%segments_.size()].head<2>();
00633 
00634           Eigen::Vector4f p14;
00635           p14.head<3>() = segments_[i];
00636           p14(3) = weight_;
00637           l1.push_back(p14);
00638 
00639           M.col(0) = p2-p1;
00640 
00641           if(type==-1)
00642           {
00643             float mi=10;
00644             size_t mm=0;
00645             for(size_t k=0; k<o.segments_.size(); k++)
00646             {
00647               j%=o.segments_.size();
00648               Eigen::Vector2f p3 = o.segments_[j].head<2>();
00649               Eigen::Vector2f p4 = o.segments_[(j+1)%o.segments_.size()].head<2>();
00650 
00651               M.col(1) = p3-p4;
00652 
00653               Eigen::Vector2f m = (M.inverse()*(p3-p1));
00654 
00655               if(m(0)>=0.f && m(0)<1.f && m(1)>=0.f && m(1)<1.f)
00656               {
00657                 if(m(0)<mi) {
00658                   mi=m(0);
00659                   mm=j;
00660                 }
00661               }
00662 
00663               ++j;
00664             }
00665 
00666             if(mi<=1)
00667               j=mm;
00668           }
00669           for(size_t k=0; k<o.segments_.size(); k++)
00670           {
00671             j%=o.segments_.size();
00672             Eigen::Vector2f p3 = o.segments_[j].head<2>();
00673             Eigen::Vector2f p4 = o.segments_[(j+1)%o.segments_.size()].head<2>();
00674 
00675             M.col(1) = p3-p4;
00676 
00677             Eigen::Vector2f m = (M.inverse()*(p3-p1));
00678 
00679             if(m(0)>0.f && m(0)<1.f && m(1)>0.f && m(1)<1.f)
00680             {
00681               Eigen::Vector3f v1,v2;
00682               v1.head<2>() = M.col(0);
00683               v2.head<2>() = M.col(1);
00684               v1(2)=v2(2)=0;
00685               const bool out = v1.cross(v2)(2)<=0;
00686 
00687 //              ROS_INFO("INTERSECTION %f %f %d",m(0),v1.cross(v2)(2),type);
00688 
00689               if(type!=-1) {
00690                 size_t end = j;//(j+(out?0:1))%o.segments_.size();
00691                 //ROS_ERROR("j %d %d %d",last_j,end,j);
00692                 if(last_j!=end)
00693                   //              if((last_j+1)%o.segments_.size()==end)
00694                   //              {
00695                   //                for(size_t t=0; t<o.segments_.size(); t++) {
00696                   //                  Eigen::Vector4f p34;
00697                   //                  p34.head<3>() = o.segments_[t];
00698                   //                  p34(3) = o.weight_;
00699                   //                  l2.push_back(p34);
00700                   //                }
00701                   //              }
00702                   //              else
00703                   for(size_t t=(last_j+1)%o.segments_.size(); true; t=(t+1)%o.segments_.size()) {
00704                     Eigen::Vector4f p34;
00705                     p34.head<3>() = o.segments_[t];
00706                     p34(3) = o.weight_;
00707                     l2.push_back(p34);
00708 
00709                     if(t==end)
00710                       break;
00711                   }
00712               }
00713               else
00714                 start_j = j;
00715               //intersection
00716               Eigen::Vector4f p;
00717               p.head<2>() = m(0)*M.col(0) + p1;
00718 
00719               p(2) = segments_[i](2);
00720               p(3) = weight_;
00721               l1.push_back(p);
00722               p(2) = o.segments_[j](2);
00723               p(3) = o.weight_;
00724               l2.push_back(p);
00725 
00726               //add to outline, inline
00727               std::vector<Eigen::Vector4f> *pl1=&l1, *pl2=&l2;
00728               if(out) { //outer
00729                 std::swap(pl1,pl2);
00730                 type=0;
00731               }
00732               else
00733                 type=1;
00734 
00735               //ROS_ERROR("s %d %d",pl1->size(),pl2->size());
00736 
00737               for(size_t l=0; l<pl1->size(); l++)
00738                 inner.push_back( (*pl1)[l] );
00739               for(size_t l=0; l<pl2->size(); l++)
00740                 outer.push_back( (*pl2)[l] );
00741 
00742               //            res += p.head<3>();
00743 
00744               //remove them
00745               l1.clear();
00746               l2.clear();
00747 
00748               last_j=j;
00749 
00750               if(last_j!=start_j)
00751                 other=true;
00752             }
00753 
00754             ++j;
00755           }
00756           j=last_j;
00757 
00758           ++i;
00759         }
00760 
00761         std::vector<Eigen::Vector4f> *pl1=&l1, *pl2=&l2;
00762         if(type==1) {
00763           std::swap(pl1,pl2);
00764         }
00765         if(type==1 || type==0) {
00766           //ROS_ERROR("j %d %d",last_j,start_j);
00767           if(last_j!=start_j || !other)
00768           for(size_t t=(last_j+1)%o.segments_.size(); true; t=(t+1)%o.segments_.size()) {
00769             Eigen::Vector4f p34;
00770             p34.head<3>() = o.segments_[t];
00771             p34(3) = o.weight_;
00772             l2.push_back(p34);
00773 
00774             if(t==start_j)
00775               break;
00776           }
00777 //          for(size_t t=(last_j+1)%o.segments_.size(); t!=start_j; t=(t+1)%o.segments_.size()) {
00778 //            Eigen::Vector4f p34;
00779 //            p34.head<3>() = o.segments_[t];
00780 //            p34(3) = o.weight_;
00781 //            l2.push_back(p34);
00782 //          }
00783 
00784           //ROS_ERROR("s %d %d",pl1->size(),pl2->size());
00785 
00786           for(size_t l=0; l<pl1->size(); l++)
00787             inner.push_back( (*pl1)[l] );
00788           for(size_t l=0; l<pl2->size(); l++)
00789             outer.push_back( (*pl2)[l] );
00790         }
00791 
00792       }
00793 
00794       if(type==-1)
00795       {
00796         Eigen::Vector4f v;
00797         for(size_t l=0; l<segments_.size(); l++) {
00798           v.head<3>() = segments_[l];
00799           v(3) = weight_;
00800           outer.push_back( v );
00801         }
00802         for(size_t l=0; l<o.segments_.size(); l++) {
00803           v.head<3>() = o.segments_[l];
00804           v(3) = o.weight_;
00805           inner.push_back( v );
00806         }
00807 
00808         if(found1)
00809           std::swap(outer,inner);
00810       }
00811 
00812       //ROS_ERROR("size %d %d %d %d",outer.size(),inner.size(),size(),o.size());
00813 
00814       if(!(outer.size()<=2*(size()+o.size())) || !(inner.size()<=2*(size()+o.size())))
00815       {
00816         o.debug_svg(debug_svg("error.svg"),100,300,"red");
00817 
00818         Outline oi, oo;
00819         for(size_t i=0; i<inner.size(); i++)
00820         {
00821           Eigen::Vector3f r2;
00822           r2.head<2>() = inner[i].head<2>();
00823           r2(2) = inner[i](2)/inner[i](3);
00824           oi += r2;
00825         }
00826         for(size_t i=0; i<outer.size(); i++)
00827         {
00828           Eigen::Vector3f r2;
00829           r2.head<2>() = outer[i].head<2>();
00830           r2(2) = outer[i](2)/outer[i](3);
00831           oo += r2;
00832         }
00833         oo.debug_svg(oi.debug_svg("error_io.svg"),100,300,"red");
00834       }
00835 //      ROS_ASSERT(outer.size()<=2*(size()+o.size()));
00836 //      ROS_ASSERT(inner.size()<=2*(size()+o.size()));
00837 
00838       //run through outer
00839       //run2(inner, outer, 0, inner.size(), res);
00840 #if 1
00841       bool ASS=false;
00842 
00843       for(size_t i=0; i<outer.size(); i++)
00844       {
00845         Eigen::Vector3f r2;
00846         Eigen::Vector4f r;
00847 
00848         size_t ind = _nextPoint3(inner,outer[i].head<2>(),r);
00849 
00850         if(0&&ind<inner.size())
00851         {
00852 
00853           const float p1 = outer[i](2)+0.001f;
00854           float weight = outer[i](3);
00855           const float p2 = r(2)+0.001f;
00856 
00857           const float ramp = std::max((p1-0.001f)/weight,r(2)/r(3));
00858           const float w1 = ramp;
00859           const float w2 = 1.f;
00860           ROS_ERROR("%f %f",ramp,w1*p2/(w2*p1+w1*p2));
00861 
00862           r2.head<2>() = w1*p2/(w2*p1+w1*p2)*(r.head<2>()-outer[i].head<2>()) + outer[i].head<2>();
00863           r2(2) = (w2*p1+w1*p2-0.002f)/(w2*weight+w1*r(3));
00864         }
00865         else
00866         {
00867           r2.head<2>() = outer[i].head<2>();
00868           r2(2) = outer[i](2)/outer[i](3);
00869         }
00870 
00871         if(res.size() && _hasIntersection(res,res.segments_.back().head<2>(),r2.head<2>(), true)) {
00872           o.debug_svg(debug_svg("error.svg",300,600),300,600,"red");
00873 
00874           Outline oi, oo;
00875           for(size_t i=0; i<inner.size(); i++)
00876           {
00877             Eigen::Vector3f r2;
00878             r2.head<2>() = inner[i].head<2>();
00879             r2(2) = inner[i](2)/inner[i](3);
00880             oi += r2;
00881           }
00882           for(size_t i=0; i<outer.size(); i++)
00883           {
00884             Eigen::Vector3f r2;
00885             r2.head<2>() = outer[i].head<2>();
00886             r2(2) = outer[i](2)/outer[i](3);
00887             oo += r2;
00888           }
00889           oo.debug_svg(oi.debug_svg("error_io.svg",300,600),300,600,"red");
00890           ASS=true;
00891           break;
00892         }
00893 
00894         res += r2;
00895       }
00896 
00897       //            for(size_t i=0; i<inner.size(); i++)
00898       //            {
00899       //              Eigen::Vector3f r2;
00900       //              r2.head<2>() = inner[i].head<2>();
00901       //              r2(2) = inner[i](2)/inner[i](3);
00902       //              res += r2;
00903       //            }
00904 
00905       if(ASS) {
00906         res.debug_svg(o.debug_svg(debug_svg("error.svg",300,600),300,600,"red"),300,600,"green");
00907       }
00908       //ROS_ASSERT(!ASS);
00909 #endif
00910       if(!res.check()) {  //DEBUG
00911         res.debug_svg(o.debug_svg(debug_svg("error.svg",300,600),300,600,"red"),300,600,"green");
00912 
00913         Outline oi, oo;
00914         for(size_t i=0; i<inner.size(); i++)
00915         {
00916           Eigen::Vector3f r2;
00917           r2.head<2>() = inner[i].head<2>();
00918           r2(2) = inner[i](2)/inner[i](3);
00919           oi += r2;
00920         }
00921         for(size_t i=0; i<outer.size(); i++)
00922         {
00923           Eigen::Vector3f r2;
00924           r2.head<2>() = outer[i].head<2>();
00925           r2(2) = outer[i](2)/outer[i](3);
00926           oo += r2;
00927         }
00928         oo.debug_svg(oi.debug_svg("error_io.svg"),100,300,"red");
00929         //ROS_ASSERT(0);
00930       }
00931     }
00932 
00933     Outline operator+(const Outline &o) const
00934     {
00935       //      ROS_ERROR("start %d %d",segments_.size(),o.segments_.size());
00936 
00937       Outline res;
00938       run(o, 0, segments_.size(), res);
00939 
00940       //      ROS_ERROR("%d %d %d",res.size(),segments_.size(),o.segments_.size());
00941       //ROS_ASSERT(res.size() == (segments_.size()+o.segments_.size()) );
00942 
00943       return res;
00944     }
00945 
00946 #if 0
00947     Outline operator+(const Outline &o) const
00948     {
00949 
00950       std::vector<COR> cors;
00951 
00952       for(size_t i=0; i<o.segments_.size(); i++)
00953       {
00954         COR c;
00955         c.other = true;
00956         c.ind = i;
00957         cors.push_back(c);
00958       }
00959 
00960       for(size_t i=0; i<segments_.size(); i++)
00961       {
00962         bool out = false;
00963         float mi = std::numeric_limits<float>::max(), mi2 = std::numeric_limits<float>::max();
00964         Eigen::Vector2f nmi = Eigen::Vector2f::Zero();
00965         size_t ind=cors.size();
00966         for(size_t j=0; j<cors.size(); j++)
00967         {
00968           if(!cors[j].other) continue;
00969 
00970           Eigen::Vector2f n;
00971           Eigen::Vector2f p1,p2, x, x2, d1,d2;
00972           x = segments_[i].head<2>();
00973           x2 = segments_[(i+1)%segments_.size()].head<2>();
00974           p1 = o.segments_[cors[j].ind].head<2>();
00975           p2 = o.segments_[(cors[j].ind+1)%o.segments_.size()].head<2>();
00976 
00977           d1 = (x-p1);
00978           d2 = p2-p1;
00979           float f = d1.dot(d2)/d2.squaredNorm();
00980           float d;
00981           if(f>1){
00982             d = (x-p2).norm();
00983             n = p2-x;
00984           }
00985           else if(f<0) {
00986             d = d1.norm();
00987             n = p1-x;
00988           }
00989           else {
00990             d = (d1(0)*d2(1)-d1(1)*d2(0))/(d2).norm();
00991             n(0) = -(p2(1)-p1(1));
00992             n(1) = (p2(0)-p1(0));
00993           }
00994 
00995           const float dd = d / std::max(0.0001f, (x-x2).dot(p1-p2)/((x-x2).norm()*(p1-p2).norm()) );
00996 
00997           //          ROS_INFO("%f %f %f",f,d,mi);
00998 
00999           if(std::abs(dd)<std::abs(mi2))
01000           {
01001             nmi = n;
01002             mi = d;
01003             mi2 = dd;
01004             ind = j;
01005             out = d*(-d2(1)*n(0)+d2(0)*n(1))>-0.001f;
01006             //            ROS_INFO("out2 %f",d*(-d2(1)*n(0)+d2(0)*n(1)));
01007           }
01008         }
01009 
01010         if(cors.size()==ind)
01011           return Outline();
01012 
01013         ROS_ASSERT(cors.size()!=ind);
01014 
01015         //        ROS_INFO("-------------");
01016 
01017         for(size_t k=0; k<cors.size(); k++)
01018         {
01019           ind = (ind+1)%cors.size();
01020           //          ROS_INFO("cmp %d %d", (int)std::abs((int)cors[ind].ind-(int)i), (int)std::abs((int)cors[ind].ind+segments_.size()-(int)i));
01021           if(cors[ind].other || std::abs((int)cors[ind].ind-(int)i)>std::abs((int)cors[ind].ind+segments_.size()-(int)i))
01022             break;
01023         }
01024 
01025         COR c;
01026         c.other = false;
01027         c.ind = i;
01028         const float p1 = std::min(segments_[i](2), segments_[(i+1)%segments_.size()](2))+0.001f;
01029         const float p2 = o.segments_[(cors[ind].ind-1+o.segments_.size())%o.segments_.size()](2)+0.001f;
01030         nmi/=nmi.norm();
01031         const float ramp = std::max((p1-0.001f)/weight_,(p2-0.001f)/o.weight_);
01032         const float w1 = (!out?1.f:ramp);
01033         const float w2 = (out?1.f:ramp);
01034         c.p.head<2>() = w1*p2/(w2*p1+w1*p2)*mi*nmi + segments_[i].head<2>();
01035         //c.p(2) = (w2*p1+w1*p2-0.002f)/(w1*o.weight_+w2*weight_);
01036         c.p(2) = (p1+p2-0.002f)/(o.weight_+weight_);
01037         cors.insert(cors.begin()+ind, c);
01038 
01039         std::cout<<"p1 "<<p1/weight_<<" p2 "<<p2/o.weight_<<" --> "<<c.p(2)<<"\n";
01040       }
01041 
01042       //      for(size_t i=0; i<segments_.size(); i++)
01043       //      {
01044       //        ROS_INFO("%f %f",segments_[i](0),segments_[i](1));
01045       //      }
01046 
01047       for(size_t j=0; j<cors.size(); j++)
01048       {
01049         if(!cors[j].other) {
01050           //          ROS_INFO("%d", (int)cors[j].ind);
01051           continue;
01052         }
01053 
01054         size_t next = j+1, bef = j-1;
01055         for(size_t i=0; i<cors.size(); i++)
01056         {
01057           ROS_ASSERT(i+1!=cors.size());
01058 
01059           next %= cors.size();
01060           bef += cors.size();
01061           bef %= cors.size();
01062 
01063           if(!cors[next].other && !cors[bef].other) break;
01064 
01065           if(cors[next].other) next++;
01066           if(cors[bef].other) bef--;
01067         }
01068 
01069         ROS_ASSERT(!cors[next].other);
01070         ROS_ASSERT(!cors[bef].other);
01071 
01072         bef = cors[bef].ind;
01073         next= cors[next].ind;
01074 
01075         float d;
01076         Eigen::Vector2f n,x;
01077         bool out;
01078         {
01079           Eigen::Vector2f p1,p2, d1,d2;
01080           x = o.segments_[cors[j].ind].head<2>();
01081           p1 = segments_[bef].head<2>();
01082           p2 = segments_[next].head<2>();
01083 
01084           d1 = (x-p1);
01085           d2 = p2-p1;
01086           float f = d1.dot(d2)/d2.squaredNorm();
01087           if(f>1){
01088             d = (x-p2).norm();
01089             n = p2-x;
01090           }
01091           else if(f<0) {
01092             d = d1.norm();
01093             n = p1-x;
01094           }
01095           else {
01096             d = (d1(0)*d2(1)-d1(1)*d2(0))/(d2).norm();
01097             n(0) = -(p2(1)-p1(1));
01098             n(1) = (p2(0)-p1(0));
01099           }
01100           //          ROS_INFO("out2 %f",d*(-d2(1)*n(0)+d2(0)*n(1)));
01101           out = d*(-d2(1)*n(0)+d2(0)*n(1))>-0.001f;
01102         }
01103 
01104         //        std::cout<<segments_[bef].head<2>()<<"\n";
01105         //        std::cout<<segments_[next].head<2>()<<"\n";
01106 
01107         const float p1 = std::min(o.segments_[cors[j].ind](2), o.segments_[(cors[j].ind+1)%o.segments_.size()](2))+0.001f;
01108         const float p2 = segments_[next](2)+0.001f;
01109         n/=n.norm();
01110         const float ramp = std::max((p1-0.001f)/o.weight_,(p2-0.001f)/weight_);
01111         const float w1 = (!out?1.f:ramp);
01112         const float w2 = (out?1.f:ramp);
01113         cors[j].p.head<2>() = w1*p2/(w2*p1+w1*p2)*d*n + x;
01114         //cors[j].p(2) = (w2*p1+w1*p2-0.002f)/(w2*o.weight_+w1*weight_);
01115         cors[j].p(2) = (p1+p2-0.002f)/(o.weight_+weight_);
01116         //cors[j].p = o.segments_[cors[j].ind];
01117 
01118         std::cout<<"p1 "<<p1/o.weight_<<" p2 "<<p2/weight_<<" --> "<<cors[j].p(2)<<"\n";
01119         //        std::cout<<o.segments_[cors[j].ind]<<"\n\n";
01120         //        std::cout<<n<<"\n\n";
01121         //        std::cout<<cors[j].p<<"\n\n";
01122       }
01123 
01124       ROS_ASSERT(cors.size() == (segments_.size()+o.segments_.size()) );
01125 
01126       Outline res;
01127 
01128       for(size_t j=0; j<cors.size(); j++)
01129       {
01130         res += cors[j].p;
01131       }
01132 
01133       return res;
01134     }
01135 #endif
01136 
01137     Outline operator|(const Outline &o) const
01138     {
01139 
01140       std::vector<COR> cors;
01141 
01142       for(size_t i=0; i<o.segments_.size(); i++)
01143       {
01144         COR c;
01145         c.other = true;
01146         c.ind = i;
01147         cors.push_back(c);
01148       }
01149 
01150       if(cors.size()<2)
01151         return *this;
01152 
01153       size_t num_last = cors.size();
01154 
01155       for(size_t i=0; i<segments_.size(); i++)
01156       {
01157         bool out = false;
01158         float mi = std::numeric_limits<float>::max();
01159         Eigen::Vector2f nmi = Eigen::Vector2f::Zero();
01160         size_t ind=cors.size();
01161         for(size_t j=0; j<cors.size(); j++)
01162         {
01163           if(!cors[j].other) continue;
01164 
01165           Eigen::Vector2f n;
01166           Eigen::Vector2f p1,p2, x, d1,d2;
01167           x = segments_[i].head<2>();
01168           p1 = o.segments_[cors[j].ind].head<2>();
01169           p2 = o.segments_[(cors[j].ind+1)%o.segments_.size()].head<2>();
01170 
01171           d1 = (x-p1);
01172           d2 = p2-p1;
01173           float f = d1.dot(d2)/d2.squaredNorm();
01174           float d;
01175           if(f>1){
01176             d = (x-p2).norm();
01177             n = p2-x;
01178           }
01179           else if(f<0) {
01180             d = d1.norm();
01181             n = p1-x;
01182           }
01183           else {
01184             d = (d1(0)*d2(1)-d1(1)*d2(0))/(d2).norm();
01185             n(0) = -(p2(1)-p1(1));
01186             n(1) = (p2(0)-p1(0));
01187           }
01188 
01189           ROS_INFO("%f %f %f",f,d,mi);
01190 
01191           if(std::abs(d)<std::abs(mi))
01192           {
01193             nmi = n;
01194             mi = d;
01195             ind = j;
01196             out = d*(-d2(1)*n(0)+d2(0)*n(1))>0.001f;
01197             ROS_INFO("out2 %f",d*(-d2(1)*n(0)+d2(0)*n(1)));
01198           }
01199         }
01200 
01201         if(out) continue;
01202 
01203         if(cors.size()==ind)
01204           return Outline();
01205 
01206         ROS_ASSERT(cors.size()!=ind);
01207 
01208         ROS_INFO("-------------");
01209 
01210         for(size_t k=0; k<cors.size(); k++)
01211         {
01212           ind = (ind+1)%cors.size();
01213           ROS_INFO("cmp %d %d", (int)std::abs((int)cors[ind].ind-(int)i), (int)std::abs((int)cors[ind].ind+segments_.size()-(int)i));
01214           if(cors[ind].other || std::abs((int)cors[ind].ind-(int)i)>std::abs((int)cors[ind].ind+segments_.size()-(int)i))
01215             break;
01216         }
01217 
01218         COR c;
01219         c.other = false;
01220         c.ind = i;
01221         const float p1 = std::max(segments_[i](2), segments_[(i+1)%segments_.size()](2))+0.001f;
01222         const float p2 = o.segments_[(cors[ind].ind-1+o.segments_.size())%o.segments_.size()](2)+0.001f;
01223         nmi/=nmi.norm();
01224         c.p.head<2>() = p2*mi*nmi + segments_[i].head<2>();
01225         c.p(2) = std::max(p1,p2)-0.001f;
01226         cors.insert(cors.begin()+ind, c);
01227       }
01228 
01229       if(cors.size()-num_last<2)
01230         return o;
01231 
01232       for(size_t j=0; j<cors.size(); j++)
01233       {
01234         if(!cors[j].other) {
01235           ROS_INFO("%d", (int)cors[j].ind);
01236           continue;
01237         }
01238 
01239         size_t next = j+1, bef = j-1;
01240         for(size_t i=0; i<cors.size(); i++)
01241         {
01242           ROS_ASSERT(i+1!=cors.size());
01243 
01244           next %= cors.size();
01245           bef += cors.size();
01246           bef %= cors.size();
01247 
01248           if(!cors[next].other && !cors[bef].other) break;
01249 
01250           if(cors[next].other) next++;
01251           if(cors[bef].other) bef--;
01252         }
01253 
01254         ROS_ASSERT(!cors[next].other);
01255         ROS_ASSERT(!cors[bef].other);
01256 
01257         bef = cors[bef].ind;
01258         next= cors[next].ind;
01259 
01260         float d;
01261         Eigen::Vector2f n,x;
01262         bool out;
01263         {
01264           Eigen::Vector2f p1,p2, d1,d2;
01265           x = o.segments_[cors[j].ind].head<2>();
01266           p1 = segments_[bef].head<2>();
01267           p2 = segments_[next].head<2>();
01268 
01269           d1 = (x-p1);
01270           d2 = p2-p1;
01271           float f = d1.dot(d2)/d2.squaredNorm();
01272           if(f>1){
01273             d = (x-p2).norm();
01274             n = p2-x;
01275           }
01276           else if(f<0) {
01277             d = d1.norm();
01278             n = p1-x;
01279           }
01280           else {
01281             d = (d1(0)*d2(1)-d1(1)*d2(0))/(d2).norm();
01282             n(0) = -(p2(1)-p1(1));
01283             n(1) = (p2(0)-p1(0));
01284           }
01285           //          ROS_INFO("out2 %f",d*(-d2(1)*n(0)+d2(0)*n(1)));
01286           out = d*(-d2(1)*n(0)+d2(0)*n(1))>0.001f;
01287 
01288           //          ROS_INFO("%f %f",f,d);
01289         }
01290 
01291         if(out) continue;
01292 
01293         std::cout<<segments_[bef].head<2>()<<"\n";
01294         std::cout<<segments_[next].head<2>()<<"\n";
01295 
01296         const float p1 = std::max(o.segments_[cors[j].ind](2), o.segments_[(cors[j].ind+1)%o.segments_.size()](2))+0.001f;
01297         const float p2 = segments_[next](2)+0.001f;
01298         n/=n.norm();
01299         cors[j].p.head<2>() = p2*d*n + x;
01300         cors[j].p(2) = std::max(p1,p2)-0.001f;
01301         //cors[j].p = o.segments_[cors[j].ind];
01302 
01303         std::cout<<o.segments_[cors[j].ind]<<"\n\n";
01304         std::cout<<n<<"\n\n";
01305         std::cout<<cors[j].p<<"\n\n";
01306       }
01307 
01308       Outline res;
01309 
01310       for(size_t j=0; j<cors.size(); j++)
01311       {
01312         res += cors[j].p;
01313       }
01314 
01315       return res;
01316     }
01317 
01318     void reverse(const bool fw=true)
01319     {
01320       if(segments_.size()<2) return;
01321 
01322       if(fw)
01323       {
01324         float t = segments_[segments_.size()-1](2);
01325         for(size_t i=0; i<segments_.size()-1; i++)
01326         {
01327           segments_[(i-1+segments_.size())%segments_.size()](2) = segments_[i](2);
01328           ROS_INFO("gets %f", segments_[i](2));
01329         }
01330         segments_[(segments_.size()-2)%segments_.size()](2) = t;
01331       }
01332       else
01333       {
01334         float t = segments_[0](2);
01335         for(size_t i=segments_.size()-1; i>0; i--)
01336         {
01337           segments_[(i+1)%segments_.size()](2) = segments_[i](2);
01338         }
01339         segments_[1](2) = t;
01340       }
01341 
01342       std::reverse(segments_.begin(), segments_.end());
01343     }
01344 
01345     inline size_t size() const {return segments_.size();}
01346     inline Eigen::Vector3f &operator[](const size_t ind) {return segments_[ind];}
01347     inline Eigen::Vector3f operator[](const size_t ind) const {return segments_[ind];}
01348     inline const std::vector<Eigen::Vector3f> &get() const {return segments_;}
01349 
01350     Eigen::Vector3f nextPoint(const Eigen::Vector3f &search) const {
01351       bool out = false;
01352       float mi = std::numeric_limits<float>::max();
01353       Eigen::Vector2f nmi = Eigen::Vector2f::Zero();
01354       size_t ind=segments_.size();
01355       for(size_t j=0; j<segments_.size(); j++)
01356       {
01357         Eigen::Vector2f n;
01358         Eigen::Vector2f p1,p2, x, d1,d2;
01359         x = search.head<2>();
01360         p1 = segments_[j].head<2>();
01361         p2 = segments_[(j+1)%segments_.size()].head<2>();
01362 
01363         d1 = (x-p1);
01364         d2 = p2-p1;
01365         float f = d1.dot(d2)/d2.squaredNorm();
01366         float d;
01367         if(f>1){
01368           d = (x-p2).norm();
01369           n = p2-x;
01370         }
01371         else if(f<0) {
01372           d = d1.norm();
01373           n = p1-x;
01374         }
01375         else {
01376           d = (d1(0)*d2(1)-d1(1)*d2(0))/(d2).norm();
01377           n(0) = -(p2(1)-p1(1));
01378           n(1) = (p2(0)-p1(0));
01379         }
01380 
01381         if(std::abs(d)<std::abs(mi))
01382         {
01383           nmi = n;
01384           mi = d;
01385           ind = j;
01386           out = d*(-d2(1)*n(0)+d2(0)*n(1))>-0.001f;
01387         }
01388       }
01389 
01390       if(segments_.size()==ind) {
01391         ROS_ERROR("err X7Z");
01392         return search;
01393       }
01394 
01395       Eigen::Vector3f r;
01396       r(2) = segments_[(ind+segments_.size())%segments_.size()](2);
01397       nmi/=nmi.norm();
01398       r.head<2>() = r(2)*mi*nmi + search.head<2>();
01399 
01400       return r;
01401     }
01402   };
01403 
01404 
01405 }
01406 
01407 
01408 #endif /* FORM_H_ */


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