trispline.h
Go to the documentation of this file.
00001 /*
00002  * trispline.h
00003  *
00004  *  Created on: 25.10.2012
00005  *      Author: josh
00006  */
00007 
00008 #ifndef TRISPLINE_H_
00009 #define TRISPLINE_H_
00010 
00011 #include <Eigen/Core>
00012 
00013 #define BIG_V_ 0
00014 
00015 namespace ParametricSurface {
00016 
00017   template<size_t IndexA, size_t IndexB, size_t IndexC>
00018   class TriangleInst
00019   {
00020   protected:
00021     Eigen::Vector3f* pts_;
00022 
00023   public:
00024     TriangleInst(Eigen::Vector3f* pts_):
00025       pts_(pts_)
00026     {}
00027 
00028     inline Eigen::Vector3f tri(const Eigen::Vector3f &bc) {
00029       return ptA()*bc(0) + ptB()*bc(1) + ptC()*bc(2);
00030     }
00031 
00032     inline Eigen::Vector3f normal() {
00033       Eigen::Vector3f r = (ptB()-ptA()).cross(ptC()-ptA());
00034       r.normalize();
00035       return r;
00036     }
00037 
00038     inline Eigen::Vector3f &ptA() {return pts_[IndexA];}
00039     inline Eigen::Vector3f &ptB() {return pts_[IndexB];}
00040     inline Eigen::Vector3f &ptC() {return pts_[IndexC];}
00041 
00042   };
00043 
00044   template<int RowSize, int Index>
00045   class TriangleIndex {
00046   public:
00047     enum {a=(Index-1), b=(Index), c=(Index+RowSize)};
00048   };
00049 
00050   template<int RowSize, int Index>
00051   class Triangle
00052   {
00053 
00054     TriangleInst<TriangleIndex<RowSize,Index>::a, TriangleIndex<RowSize,Index>::b, TriangleIndex<RowSize,Index>::c > b;
00055     Triangle<RowSize, Index-1> tri_;
00056     Triangle<RowSize-1, Index-1> tri2_;
00057 
00058   public:
00059 
00060     Triangle(Eigen::Vector3f* pts_):
00061       b(pts_), tri_(pts_), tri2_(pts_+RowSize) {}
00062 
00063   };
00064 
00065   template<int RowSize>
00066   class Triangle<RowSize,0>
00067   {
00068     TriangleInst<TriangleIndex<RowSize,0>::a, TriangleIndex<RowSize,0>::b, TriangleIndex<RowSize,0>::c > b;
00069 
00070   public:
00071 
00072     Triangle(Eigen::Vector3f* pts_):
00073       b(pts_) {}
00074 
00075   };
00076 
00077 
00078 
00079   template<int X, int Y>
00080   class TriangleCoord {
00081   public:
00082     enum {x=X, y=Y, ind=y*(y+1)/2+x};
00083   };
00084 
00085   template<typename Ca, typename Cb, typename Cc, int Round, int Depth>
00086   class TriangleC {
00087     TriangleC<
00088     Ca,
00089     TriangleCoord<Cb::x-1,Cb::y>,
00090     TriangleCoord<Cc::x,Cc::y+1>,
00091     0,
00092     Depth-1
00093     > tri_a_;
00094     TriangleC<
00095     TriangleCoord<Ca::x+1,Ca::y>,
00096     Cb,
00097     TriangleCoord<Cc::x+1,Cc::y+1>,
00098     0,//1,
00099     Depth-1
00100     > tri_b_;
00101     TriangleC<
00102     TriangleCoord<Ca::x,Ca::y-1>,
00103     TriangleCoord<Cb::x-1,Cb::y-1>,
00104     Cc,
00105     0,//2,
00106     Depth-1
00107     > tri_c_;
00108   public:
00109 
00110     inline Eigen::Vector4f operator()(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00111       return tri_a_(bc, pts_)*bc( (0+Round)%3 ) + tri_b_(bc, pts_)*bc( (1+Round)%3 ) + tri_c_(bc, pts_)*bc( (2+Round)%3 );
00112     }
00113 
00114     inline Eigen::Vector3f normalAt(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00115       const Eigen::Vector3f a = tri_a_(bc, pts_).head(3), b=tri_b_(bc, pts_).head(3), c=tri_c_(bc, pts_).head(3);
00116       return (b-a).cross(c-a);
00117     }
00118 
00119     inline Eigen::Vector3f normalAt2(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00120       const Eigen::Vector3f a = normalAt(bc, pts_).head(3), b=normalAt(bc, pts_).head(3), c=normalAt(bc, pts_).head(3);
00121       return (b-a).cross(c-a);
00122     }
00123 
00124     inline Eigen::Matrix4f normalAtUV(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_, const Eigen::Vector2f *_uv) const {
00125       const Eigen::Vector3f a = tri_a_(bc, pts_).head(3), b=tri_b_(bc, pts_).head(3), c=tri_c_(bc, pts_).head(3);
00126       Eigen::Matrix4f M;
00127 
00128       Eigen::Vector2f uv[3] =
00129       {
00130        _uv[0]*bc(0) + (_uv[1]+_uv[0])*0.5f*bc(1) + (_uv[2]+_uv[0])*0.5f*bc(2),
00131        _uv[1]*bc(1) + (_uv[0]+_uv[1])*0.5f*bc(0) + (_uv[2]+_uv[1])*0.5f*bc(2),
00132        _uv[2]*bc(2) + (_uv[1]+_uv[2])*0.5f*bc(1) + (_uv[0]+_uv[2])*0.5f*bc(0)
00133       };
00134 
00135       std::cout<<"uv\n";
00136       for(int i=0; i<3; i++) std::cout<<uv[i]<<"\n";
00137 
00138       std::cout<<"bc\n"<<bc<<"\n";
00139       std::cout<<"a\n"<<a<<"\n";
00140       std::cout<<"b\n"<<b<<"\n";
00141       std::cout<<"c\n"<<c<<"\n";
00142 
00143       float f = (uv[2](1)-uv[1](1));
00144       std::cout<<"f1 "<<f<<"\n";
00145       if(std::abs(f)>0.00001f)
00146         M.col(1).head<3>() = (uv[2](1)-uv[0](1))/f*(b-c) + c - a;
00147       else
00148         M.col(1).head<3>() = b-c;
00149       f = (uv[2](0)-uv[1](0));
00150       if(std::abs(f)>0.00001f)
00151         M.col(2).head<3>() = (uv[2](0)-uv[0](0))/f*(b-c) + c - a;
00152       else
00153         M.col(2).head<3>() = b-c;
00154 
00155       {
00156         const Eigen::Vector3f a = pts_[Ca::ind].head(3), b=pts_[Cb::ind].head(3), c=pts_[Cc::ind].head(3);
00157         std::cout<<"a\n"<<a<<"\n";
00158         std::cout<<"b\n"<<b<<"\n";
00159         std::cout<<"c\n"<<c<<"\n";
00160         M.col(3).head<3>() = (b-a).cross(c-a);
00161         M.col(3).head<3>().normalize();
00162       }
00163       M.col(1)(3) = M.col(1).head<3>().dot(M.col(3).head<3>());
00164       M.col(2)(3) = M.col(2).head<3>().dot(M.col(3).head<3>());
00165       M.col(3).head<3>() = (b-a).cross(c-a);
00166 
00167       return M;
00168     }
00169 
00170     inline size_t getIndA() const {return Ca::ind;}
00171     inline size_t getIndB() const {return Cb::ind;}
00172     inline size_t getIndC() const {return Cc::ind;}
00173 
00174     void print(const Eigen::Vector4f* pts_) const {
00175       tri_a_.print(pts_);
00176       tri_b_.print(pts_);
00177       tri_c_.print(pts_);
00178     }
00179 
00180   };
00181 
00182   template<typename Ca, typename Cb, typename Cc, int Round>
00183   class TriangleC<Ca,Cb,Cc,Round,0> {
00184   public:
00185 
00186     inline Eigen::Vector4f operator()(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00187       return pts_[Ca::ind]*bc( (0+Round)%3 ) + pts_[Cb::ind]*bc( (1+Round)%3 ) + pts_[Cc::ind]*bc( (2+Round)%3 );
00188     }
00189 
00190     inline Eigen::Vector4f normalAt(const Eigen::Vector3f &bc, const Eigen::Vector4f* pts_) const {
00191       const Eigen::Vector4f a = pts_[Ca::ind], b=pts_[Cb::ind], c=pts_[Cc::ind];
00192       return (b-a).cross(c-a);
00193     }
00194 
00195 
00196     void print(const Eigen::Vector4f* pts_) const {
00197 #if 0
00198       printf("x y (%d, %d)\n", Ca::x, Ca::y);
00199       printf("x y (%d, %d)\n", Cb::x, Cb::y);
00200       printf("x y (%d, %d)\n", Cc::x, Cc::y);
00201 #endif
00202       printf("adding (%d, %d, %d):\n", Ca::ind, Cb::ind, Cc::ind);
00203       std::cout<<"  "<<pts_[Ca::ind]<<"\n";
00204       std::cout<<"  "<<pts_[Cb::ind]<<"\n";
00205       std::cout<<"  "<<pts_[Cc::ind]<<"\n";
00206     }
00207   };
00208 
00209 
00210   class _Line {
00211   public:
00212     Eigen::Vector3f u, o;
00213 
00214     _Line() {}
00215     _Line(const Eigen::Vector3f &u, const Eigen::Vector3f &o):u(u),o(o) {}
00216 
00217     inline Eigen::Vector3f at(const float f) const {
00218       return f*u+o;
00219     }
00220 
00221     inline Eigen::Vector3f intersection(const Eigen::Vector3f &n, const Eigen::Vector3f &o2, const Eigen::Vector3f &ip) {
00222       const float d = u.dot(n);
00223 #if DEBUG_OUT_
00224       std::cout<<"n\n"<<n<<"\n";
00225       std::cout<<"u\n"<<u<<"\n";
00226 #endif
00227       if( std::abs(d)< 0.0001f )
00228         return ip;
00229       const float f = (o2).dot(n)/(2*d);
00230 #if DEBUG_OUT_
00231       std::cout<<"f "<<f<<"   "<<u.dot(n)<<"\n";
00232 #endif
00233       return at( f );
00234     }
00235   };
00236 
00237   class _Plane {
00238   public:
00239     Eigen::Vector3f n, o;
00240 
00241     _Plane(const Eigen::Vector3f &n, const Eigen::Vector3f &o):n(n),o(o) {}
00242 
00243     inline Eigen::Vector3f intersection(const _Line &l, float &x) {
00244 #if DEBUG_OUT_
00245       std::cout<<"np\n"<<n<<"\n";
00246 #endif
00247       const float d=l.u.dot(n);
00248       if( std::abs(d)< 0.0001f )
00249         return 0.5f*(o+l.o);
00250       return l.at( x=(o-l.o).dot(n)/d );
00251     }
00252 
00253     inline _Line intersection(const _Plane &p) {
00254       _Line lr( n.cross( p.n ), Eigen::Vector3f::Zero() );
00255 #if 0
00256       const float dot = n.dot( p.n );
00257       const float h2 = p.n.dot( p.o-o );
00258       const float dot2 = (1-dot*dot);
00259       if(dot2) {
00260         lr.o =
00261             ( (-h2*dot)*n + (h2)*p.n )/dot2 + o;
00262       }
00263       else
00264         ROS_ASSERT(0);
00265 #else
00266 
00267       if(lr.u.squaredNorm()<0.0001f) {
00268         lr.o = o;
00269         lr.u = p.o-o;
00270         return lr;
00271       }
00272       //ROS_ASSERT_MSG( lr.u.squaredNorm()>0.00001f, "parrallel planes" );
00273 
00274       const float d1 = -n.dot(o);
00275       const float d2 = -p.n.dot(p.o);
00276 
00277       int m = 0;
00278       if( std::abs(lr.u(1))>std::abs(lr.u(m)) ) m=1;
00279       if( std::abs(lr.u(2))>std::abs(lr.u(m)) ) m=2;
00280 
00281       switch (m) {
00282         case 0:
00283           lr.o(1) = (d2*n(2) - d1*p.n(2))/ lr.u(0);
00284           lr.o(2) = (d1*p.n(1) - d2*n(1))/ lr.u(0);
00285           break;
00286         case 1:
00287           lr.o(0) = (d1*p.n(2) - d2*n(2))/ lr.u(1);
00288           lr.o(2) = (d2*n(0) - d1*p.n(0))/ lr.u(1);
00289           break;
00290         case 2:
00291           lr.o(0) = (d2*n(1) - d1*p.n(1))/ lr.u(2);
00292           lr.o(1) = (d1*p.n(0) - d2*n(0))/ lr.u(2);
00293           break;
00294       }
00295 #endif
00296 
00297 #if DEBUG_OUT_
00298       std::cout<<"PLANE INTERSECTION\n";
00299       std::cout<<"o\n"<<lr.o<<"\n";
00300       std::cout<<"u\n"<<lr.u<<"\n";
00301       std::cout<<"n1\n"<<n<<"\n";
00302       std::cout<<"n2\n"<<p.n<<"\n";
00303 #endif
00304 
00305       return lr;
00306     }
00307   };
00308 
00309   class SplineFade
00310   {
00311   public:
00312     Eigen::Vector4f pts_[2];
00313 
00314     inline Eigen::Vector3f delta() const {return (pts_[0]-pts_[1]).head<3>();}
00315 
00316     void test_setup(const Eigen::Vector3f &a, const Eigen::Vector3f &b,
00317                     const Eigen::Vector3f &na, const Eigen::Vector3f &nb,
00318                     const Eigen::Vector3f &na2, const Eigen::Vector3f &nb2,
00319                     _Line &l1, _Line &l2)
00320     {
00321       _Plane p1(na,a);
00322       _Plane p2(nb,b);
00323 
00324       _Plane p1x(na2,0.5f*(a+b));
00325       _Plane p2x(nb2,0.5f*(a+b));
00326 
00327       l1 = p1x.intersection(p1);
00328       l2 = p2x.intersection(p2);
00329 
00330       l1 = _Line(na2,0.5f*(a+b));
00331       l2 = _Line(nb2,0.5f*(a+b));
00332     }
00333 
00334     void setup(const Eigen::Vector3f &a, const Eigen::Vector3f &b,
00335                const Eigen::Vector3f &na, const Eigen::Vector3f &nb,
00336                const Eigen::Vector3f &na2, const Eigen::Vector3f &nb2,
00337                const float max_curvature)
00338     {
00339       _Plane p1(na,a);
00340       _Plane p2(nb,b);
00341 
00342 #if 0
00343       Eigen::Vector3f i1 = p1.intersection( _Line(na,b) );
00344       Eigen::Vector3f i2 = p2.intersection( _Line(nb,a) );
00345 #endif
00346 
00347 #if DEBUG_OUT_
00348       //std::cout<<"i1\n"<<i1<<"\n";
00349       std::cout<<"a\n"<<a<<"\n";
00350       //std::cout<<"i2\n"<<i2<<"\n";
00351       std::cout<<"b\n"<<b<<"\n";
00352 #endif
00353 
00354 #if 0
00355       pts_[0] = _Line( (i1-a), a ).intersection( na2, b-a, i1 );
00356       pts_[1] = _Line( (i2-b), b ).intersection( nb2, a-b, i2 );
00357 #elif 0
00358       _Plane p1x(na.cross(a-b),a);
00359       _Plane p2x(nb.cross(b-a),b);
00360 
00361       pts_[0] = p1x.intersection(p1).intersection( na2, b-a, i1 );
00362       pts_[1] = p2x.intersection(p2).intersection( nb2, a-b, i2 );
00363 #else
00364 
00365 #if 0
00366       _Plane p1x(na2,0.5f*(a+b));
00367       _Plane p2x(nb2,0.5f*(a+b));
00368 
00369       _Line l1 = p1x.intersection(p1);
00370       _Line l2 = p2x.intersection(p2);
00371 
00372       Eigen::Matrix3f M;
00373 
00374 #if 0
00375       M.col(0) = -l1.u;
00376       M.col(1) = l2.u;
00377       M.col(2) = l1.u.cross(l2.u);
00378 
00379 #if DEBUG_OUT_
00380       std::cout<<"M\n"<<M<<"\n";
00381       std::cout<<"r\n"<<(l1.o-l2.o)<<"\n";
00382       std::cout<<"M-1\n"<<M.inverse()<<"\n";
00383 #endif
00384 
00385       Eigen::Vector3f v=M.inverse()*(l1.o-l2.o);
00386 
00387 #if DEBUG_OUT_
00388       std::cout<<"v\n"<<v<<"\n";
00389 #endif
00390 
00391       if(pcl_isfinite(v.sum())) {
00392         pts_[0] = l1.at(v(0));
00393         pts_[1] = l2.at(v(1));
00394       }
00395       else {
00396         pts_[0] = l1.o;
00397         pts_[1] = l2.o;
00398       }
00399 #else
00400       M.col(0) = -l1.u;
00401       M.col(1) = a-b;
00402       M.col(2) = l1.u.cross(M.col(1));
00403 
00404       Eigen::Vector3f v=M.inverse()*(l1.o-b);
00405       std::cout<<"vA\n"<<v<<"\n";
00406       std::cout<<"u\n"<<l1.u<<"\n";
00407       std::cout<<"o\n"<<l1.o<<"\n";
00408 
00409       if(pcl_isfinite(v(0)) && std::abs(v(0))<100000.f) {
00410         pts_[0] = l1.at(v(0));
00411       }
00412       else {
00413         pts_[0] = (a+b)*0.5f;
00414       }
00415 
00416       M.col(0) = -l2.u;
00417       M.col(1) = a-b;
00418       M.col(2) = l2.u.cross(M.col(1));
00419 
00420       v=M.inverse()*(l2.o-b);
00421       std::cout<<"vB\n"<<v<<"\n";
00422       std::cout<<"u\n"<<l2.u<<"\n";
00423       std::cout<<"o\n"<<l2.o<<"\n";
00424 
00425       if(pcl_isfinite(v(0)) && std::abs(v(0))<10000.f) {
00426         pts_[1] = l2.at(v(0));
00427       }
00428       else {
00429         pts_[1] = (a+b)*0.5f;
00430       }
00431 #endif
00432 
00433 #else
00434 
00435       float x, l;
00436       pts_[0].head<3>() = p1.intersection(_Line(na2,0.5f*(a+b)),x);
00437       l = 2*x*x*na2.squaredNorm() / (a-b).squaredNorm();
00438       if(l>max_curvature*max_curvature){
00439         pts_[0].head<3>() = (pts_[0].head<3>()-a)*max_curvature/std::sqrt(l) + a;
00440         //std::cout<<"curv1 "<<l<<" ["<<max_curvature<<std::endl;
00441       }
00442       pts_[1].head<3>() = p2.intersection(_Line(nb2,0.5f*(a+b)),x);
00443       l = 2*x*x*nb2.squaredNorm() / (a-b).squaredNorm();
00444       if(l>max_curvature*max_curvature) {
00445         pts_[1].head<3>() = (pts_[1].head<3>()-b)*max_curvature/std::sqrt(l) + b;
00446         //std::cout<<"curv2 "<<l<<" ["<<max_curvature<<std::endl;
00447       }
00448 
00449       //      std::cout<<"a   "<<a<<std::endl;
00450       //      std::cout<<"na  "<<na<<std::endl;
00451       //      std::cout<<"na2 "<<na2<<std::endl;
00452       //      std::cout<<"b   "<<b<<std::endl;
00453       //      std::cout<<"nb  "<<nb<<std::endl;
00454       //      std::cout<<"nb2 "<<nb2<<std::endl;
00455 
00456       ROS_ASSERT(pcl_isfinite(pts_[0].head<3>().sum()));
00457       ROS_ASSERT(pcl_isfinite(pts_[1].head<3>().sum()));
00458 #endif
00459 
00460 #endif
00461 
00462 #if DEBUG_OUT_
00463       print();
00464 #endif
00465     }
00466 
00467     void transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr) {
00468       pts_[0].head<3>() = rot*pts_[0].head<3>()+tr;
00469       pts_[1].head<3>() = rot*pts_[1].head<3>()+tr;
00470     }
00471 
00472     inline Eigen::Vector4f operator()(const float a, const float b) {
00473       float f = a/(a+b);
00474       if(!pcl_isfinite(f)||f<0) f=0.f;
00475       if(f>1) f=1;
00476       return f*pts_[0] + (1.f-f)*pts_[1];
00477     }
00478 
00479     void print() const {
00480       std::cout<<"SF1\n"<<pts_[0]<<"\n";
00481       std::cout<<"SF2\n"<<pts_[1]<<"\n";
00482     }
00483 
00484   };
00485 
00486   template<int Order>
00487   class TriSpline
00488   {
00489   protected:
00490     enum {PT_SIZE=(Order+1)*(Order+2)/2, ORDER=Order};
00491 
00492     Eigen::Vector4f pts_[PT_SIZE];
00493 
00494     //Triangle<Order,Order-1> tris_;
00495 
00496     TriangleC<
00497     TriangleCoord<0,Order>,
00498     TriangleCoord<Order,Order>,
00499     TriangleCoord<0,0>,
00500     0,
00501     Order-1
00502     > tri_;
00503 
00504     /*inline Eigen::Vector3f tri(const Eigen::Vector3f &bc) {
00505       return ptA()*bc(0) + ptB()*bc(1) + ptC()*bc(2);
00506     }*/
00507 
00508     inline static size_t indAB(const size_t x, const size_t y) {
00509       return y*(y+1)/2+x;
00510     }
00511 
00512   public:
00513     TriSpline()//:tris_(pts_)
00514     {
00515       for(int i=0; i<PT_SIZE; i++)
00516         pts_[i].fill(1);
00517     }
00518 
00519     virtual ~TriSpline() {}
00520 
00521     virtual Eigen::Vector3f operator()(const Eigen::Vector3f &bc) const {
00522       return tri_(bc, pts_).head(3);
00523     }
00524 
00525     virtual Eigen::Vector3f normalAt(const Eigen::Vector3f &bc) const {
00526       return tri_.normalAt(bc, pts_).head(3);
00527     }
00528 
00529     virtual Eigen::Vector3f normalAt2(const Eigen::Vector3f &bc) const {
00530       return tri_.normalAt2(bc, pts_).head(3);
00531     }
00532 
00533     virtual void transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr) {
00534       for(int i=0; i<PT_SIZE; i++)
00535         pts_[i].head(3) = rot*pts_[i].head(3)+tr;
00536     }
00537 
00538   };
00539 
00540   class TriSpline2_Fade : public TriSpline<2> {
00541     Eigen::Vector3f n_[3], n2_[3];
00542     Eigen::Vector2f uv_[3];
00543     SplineFade sf_[3];
00544     Eigen::Matrix2f _T_;
00545 
00546     Eigen::Vector3f m_, weight_;
00547 
00548     void setup(const float max_curvature) {
00549       size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00550 
00551       for(int i=0; i<3; i++) {
00552         sf_[i].setup( pts_[ind[i]].head<3>(), pts_[ind[(i+1)%3]].head<3>(),
00553                       n_[i], n_[(i+1)%3],
00554                       n2_[i], n2_[(i+1)%3], max_curvature);
00555         m_ += pts_[ind[i]].head<3>();
00556       }
00557 
00558       m_/=3;
00559     }
00560 
00561   public:
00562 
00563     void test_setup(_Line *l) {
00564       size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00565 
00566       for(int i=0; i<3; i++) {
00567         sf_[i].test_setup( pts_[ind[i]].head<3>(), pts_[ind[(i+1)%3]].head<3>(),
00568                            n_[i], n_[(i+1)%3],
00569                            n2_[i], n2_[(i+1)%3],
00570                            l[i*2+0],l[i*2+1]);
00571       }
00572     }
00573 
00574     inline Eigen::Vector3f getEdge(const int i) {
00575       static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00576       return pts_[ind[i]].head<3>();
00577     }
00578 
00579     inline SplineFade getFade(const int i) {return sf_[i];}
00580     inline Eigen::Vector3f getNormal(const int i) {return n_[i];}
00581     inline Eigen::Vector2f getUV(const int i) {return uv_[i];}
00582     inline Eigen::Vector3f getNormal2(const int i) {return n2_[i];}
00583 
00584     TriSpline2_Fade(const Eigen::Vector3f &a, const Eigen::Vector3f &b, const Eigen::Vector3f &c,
00585                     const Eigen::Vector3f &na, const Eigen::Vector3f &nb, const Eigen::Vector3f &nc,
00586                     const Eigen::Vector3f &na2, const Eigen::Vector3f &nb2, const Eigen::Vector3f &nc2,
00587                     const Eigen::Vector2f &uva, const Eigen::Vector2f &uvb, const Eigen::Vector2f &uvc,
00588                     const Eigen::Vector3f &w, const float max_curvature = 10000.f
00589     ): weight_(w)
00590     {
00591       pts_[indAB(0,ORDER)].head<3>()     = a;
00592       pts_[indAB(ORDER,ORDER)].head<3>() = b;
00593       pts_[indAB(0,0)].head<3>()         = c;
00594 
00595       n_[0] = na;
00596       n_[1] = nb;
00597       n_[2] = nc;
00598 
00599       n2_[0] = na2;
00600       n2_[1] = nb2;
00601       n2_[2] = nc2;
00602 
00603       uv_[0] = uva;
00604       uv_[1] = uvb;
00605       uv_[2] = uvc;
00606 
00607       //update barycentric coordinates transformation
00608       _T_.col(0) = uva-uvc;
00609       _T_.col(1) = uvb-uvc;
00610       _T_ = _T_.inverse().eval();
00611 
00612       if(!pcl_isfinite(_T_.sum())) {
00613         ROS_WARN("_T_ is invalid");
00614         _T_.fill(0);
00615         _T_(0,0)=_T_(1,1)=1;
00616       }
00617 
00618       setup(max_curvature);
00619     }
00620 
00621     inline Eigen::Vector3f getWeight() const {return weight_;}
00622 
00623     virtual Eigen::Vector3f operator()(const Eigen::Vector3f &bc) {
00624       pts_[indAB(ORDER/2,ORDER)]        = sf_[0](bc(0),bc(1));
00625       pts_[indAB(ORDER/2,ORDER/2)]      = sf_[1](bc(1),bc(2));
00626       pts_[indAB(0,ORDER/2)]            = sf_[2](bc(2),bc(0));
00627 #if DEBUG_OUT_
00628       tri_.print(pts_);
00629 #endif
00630       return tri_(bc, pts_).head(3);
00631     }
00632 
00633     virtual Eigen::Vector3f normalAt(const Eigen::Vector3f &bc) {
00634       pts_[indAB(ORDER/2,ORDER)]        = sf_[0](bc(0),bc(1));
00635       pts_[indAB(ORDER/2,ORDER/2)]      = sf_[1](bc(1),bc(2));
00636       pts_[indAB(0,ORDER/2)]            = sf_[2](bc(2),bc(0));
00637       return tri_.normalAt(bc, pts_);
00638     }
00639 
00640     virtual Eigen::Vector3f normalAt2(const Eigen::Vector3f &bc) {
00641       pts_[indAB(ORDER/2,ORDER)]        = sf_[0](bc(0),bc(1));
00642       pts_[indAB(ORDER/2,ORDER/2)]      = sf_[1](bc(1),bc(2));
00643       pts_[indAB(0,ORDER/2)]            = sf_[2](bc(2),bc(0));
00644       return tri_.normalAt2(bc, pts_);
00645     }
00646 
00647     virtual Eigen::Matrix4f normalAtUV(const Eigen::Vector3f &bc) {
00648       pts_[indAB(ORDER/2,ORDER)]        = sf_[0](bc(0),bc(1));
00649       pts_[indAB(ORDER/2,ORDER/2)]      = sf_[1](bc(1),bc(2));
00650       pts_[indAB(0,ORDER/2)]            = sf_[2](bc(2),bc(0));
00651       return tri_.normalAtUV(bc, pts_, uv_);
00652     }
00653 
00654     Eigen::Matrix3f delta() const {
00655       Eigen::Matrix3f M;
00656       for(int i=0; i<3; i++)
00657         M.col(i) = sf_[i].delta();
00658       return M;
00659     }
00660 
00661     Eigen::Vector3f operator()(const Eigen::Vector2f &pt) {
00662       //1. bayrcentric coordinates 2D -> 3D
00663       Eigen::Vector3f br;
00664       br.head<2>() = _T_*(pt-uv_[2]);
00665       br(2) = 1-br(0)-br(1);
00666 
00667       //return (*this)(br);
00668       Eigen::Vector3f v=(*this)(br);
00669 #if BIG_V_
00670       if(v.squaredNorm()>70 || !pcl_isfinite(v.sum())) {
00671         std::cout<<"BIG v\n"<<v<<"\n";
00672         std::cout<<"uv\n"<<pt<<"\n";
00673         std::cout<<"bc\n"<<br<<"\n";
00674         std::cout<<"T\n"<<_T_<<"\n";
00675         size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00676 
00677         for(int i=0; i<3; i++) {
00678           std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00679           std::cout<<"uv\n"<<uv_[i]<<"\n";
00680         }
00681       }
00682 #endif
00683       return v;
00684     }
00685 
00686     Eigen::Vector3f normalAt(const Eigen::Vector2f &pt) {
00687       //1. bayrcentric coordinates 2D -> 3D
00688       Eigen::Matrix<float,3,2> M = normalBC( _T_*(pt-uv_[2]) );
00689 
00690       return M.col(0).cross( M.col(1) );
00691     }
00692 
00693     Eigen::Vector3f UV2BC(const Eigen::Vector2f &pt) const {
00694       //1. bayrcentric coordinates 2D -> 3D
00695       Eigen::Vector3f br;
00696       br.head<2>() = _T_*(pt-uv_[2]);
00697       br(2) = 1-br(0)-br(1);
00698 
00699       return br;
00700     }
00701 
00702     Eigen::Vector3f normalAt2(const Eigen::Vector2f &pt) {
00703       Eigen::Vector2f v = _T_*(pt-uv_[2]);
00704       Eigen::Matrix<float,3,2> M1 = normalBC( v );
00705       Eigen::Matrix<float,3,2> M2 = normal2BC( v );
00706 
00707       M1.col(0) = -( M2.col(0).cross(M1.col(1)) ).cross( M2.col(1).cross(M1.col(0)) );
00708 
00709       //M1.col(0).normalize();
00710 
00711       if(!pcl_isfinite(M1.col(0).sum())) {
00712         std::cout<<"INF v\n"<<M1<<"\n";
00713         std::cout<<"M1\n"<<normalBC( v )<<"\n";
00714         std::cout<<"M2\n"<<normal2BC( v )<<"\n";
00715         std::cout<<"uv\n"<<pt<<"\n";
00716         std::cout<<"bc\n"<<v<<"\n";
00717         std::cout<<"T\n"<<_T_<<"\n";
00718         size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00719 
00720         for(int i=0; i<3; i++) {
00721           std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00722           std::cout<<"uv\n"<<uv_[i]<<"\n";
00723         }
00724       }
00725 
00726       if(!pcl_isfinite(M1.col(0).sum()))
00727         return Eigen::Vector3f::Zero();
00728 
00729       return M1.col(0);
00730       /*
00731       //1. bayrcentric coordinates 2D -> 3D
00732       Eigen::Matrix3f M;
00733 
00734       M.topLeftCorner<3,2>() = normal2BC(_T_*(pt-uv_[2]));
00735       M.col(2) = M.col(0).cross(M.col(1));
00736 
00737       Eigen::Matrix<float,3,2> R;
00738       Eigen::Vector3f v;
00739       v(2)=0;
00740 
00741       v.head<2>() = _T_.col(0);
00742       R.col(0) = M*v;
00743 
00744       v.head<2>() = _T_.col(1);
00745       R.col(1) = M*v;
00746 
00747       std::cout<<"normalAt2\n"<<R<<"\n";
00748       std::cout<<"normalAt2v\n"<<R*pt<<"\n";
00749 
00750       return R*pt;*/
00751     }
00752 
00753     virtual void transform(const Eigen::Matrix3f &rot, const Eigen::Vector3f &tr) {
00754       TriSpline<2>::transform(rot, tr);
00755       for(int i=0; i<3; i++) {
00756         //std::cout<<tr;
00757         n_[i]  = rot*n_[i];
00758         n2_[i] = rot*n2_[i];
00759         sf_[i].transform(rot,tr);
00760       }
00761 
00762       m_ = rot*m_ + tr;
00763     }
00764 
00765     inline Eigen::Vector3f getMid() const {return m_;}
00766 
00767     inline Eigen::Vector2f getMidUV() const {return (uv_[0]+uv_[1]+uv_[2])/3;}
00768 
00769     Eigen::Matrix4f normalAtUV(const Eigen::Vector2f &pt) {
00770       for(int i=0; i<3; i++)
00771         sf_[i].print();
00772 
00773       //1. bayrcentric coordinates 2D -> 3D
00774       Eigen::Vector3f br;
00775 
00776       br.head<2>() = _T_*(pt-uv_[2]);
00777       br(2) = 1-br(0)-br(1);
00778 
00779       Eigen::Matrix4f M = normalAtUV(br);
00780       M.col(0).head<3>() = (*this)(br);
00781       //      M.col(1).head<3>().normalize();
00782       //      M.col(2).head<3>().normalize();
00783       return M;
00784     }
00785 
00786     inline float POW2(const float f) {return f*f;}
00787     inline float POW3(const float f) {return f*f*f;}
00788 
00789     inline Eigen::Matrix<float,3,2> normal(const Eigen::Vector2f &uv) {
00790       Eigen::Matrix3f M;
00791       M.topLeftCorner<3,2>() = normalBC(_T_*(uv-uv_[2]));
00792       M.col(2) = M.col(0).cross(M.col(1));
00793 
00794       Eigen::Matrix<float,3,2> R;
00795       Eigen::Vector3f v;
00796       v(2)=0;
00797 
00798       v.head<2>() = _T_.col(0);
00799       R.col(0) = M*v;
00800 
00801       v.head<2>() = _T_.col(1);
00802       R.col(1) = M*v;
00803 
00804       if(!pcl_isfinite(R.sum())) {
00805         std::cout<<"INF v\n"<<R<<"\n";
00806         std::cout<<"uv\n"<<uv<<"\n";
00807         std::cout<<"bc\n"<<(_T_*(uv-uv_[2]))<<"\n";
00808         std::cout<<"T\n"<<_T_<<"\n";
00809         size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00810 
00811         for(int i=0; i<3; i++) {
00812           std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00813           std::cout<<"uv\n"<<uv_[i]<<"\n";
00814         }
00815       }
00816 
00817       return R;
00818     }
00819 
00820     inline Eigen::Matrix<float,3,2> normalBC(const Eigen::Vector2f &bc) {
00821       Eigen::Matrix<float,3,2> M;
00822       static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00823 
00824 #if 0
00825       if(std::abs(bc(0)-1)<0.0001f) {
00826         //        M.col(0) = 2*pts_[ind[0]]-2*sf_[2].pts_[1];
00827         //        M.col(1) = 2*sf_[0].pts_[0]-2*sf_[2].pts_[1];
00828 
00829         M.col(0) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+(bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))+bc(0)*((-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+pts_[ind[0]])+(-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))+bc(1)*(-(sf_[1].pts_[1]+sf_[1].pts_[0])/2+bc(0)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-(bc(1)*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+bc(1)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))+bc(0)*pts_[ind[0]];
00830         M.col(1) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+(sf_[1].pts_[1]+sf_[1].pts_[0])/2)+bc(1)*(pts_[ind[1]]-(sf_[1].pts_[1]+sf_[1].pts_[0])/2+bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0))))+bc(1)*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-(bc(1)*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+((-bc(1)-bc(0)+1)*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+bc(0)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)));
00831 
00832         //std::cout<<"A\n"<<M<<"\n";
00833       }
00834       else if(std::abs(bc(1)-1)<0.0001f) {
00835         //        M.col(0) = 2*sf_[0].pts_[1]-2*sf_[1].pts_[0];
00836         //        M.col(1) = 2*pts_[ind[1]]-2*sf_[1].pts_[0];
00837 
00838         M.col(0) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+(sf_[2].pts_[1]+sf_[2].pts_[0])/2+bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))))+bc(0)*(-(sf_[2].pts_[1]+sf_[2].pts_[0])/2+bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+pts_[ind[0]])+((-bc(1)-bc(0)+1)*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2-(bc(0)*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2+bc(1)*((-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))+bc(0)*pts_[ind[0]];
00839         M.col(1) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*(pts_[ind[1]]+(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0))))+bc(1)*pts_[ind[1]]+bc(0)*(-(sf_[2].pts_[1]+sf_[2].pts_[0])/2+bc(1)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-(bc(0)*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+(-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(0)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)));
00840 
00841         //std::cout<<"B\n"<<M<<"\n";
00842       }
00843       else if( std::abs(bc(0)+bc(1))<0.0001f) {
00844         //        M.col(0) = 2*sf_[2].pts_[0]-2*pts_[ind[2]];
00845         //        M.col(1) = 2*sf_[1].pts_[1]-2*pts_[ind[2]];
00846 
00847         M.col(0) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+(bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))))+bc(0)*((-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+pts_[ind[0]])+(-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))+bc(1)*((-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+(sf_[0].pts_[1]+sf_[0].pts_[0])/2)-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+(bc(1)*(sf_[0].pts_[1]+sf_[0].pts_[0]))/2+bc(0)*pts_[ind[0]];
00848         M.col(1) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*(pts_[ind[1]]+(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+(sf_[0].pts_[1]+sf_[0].pts_[0])/2)-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+(-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+(bc(0)*(sf_[0].pts_[1]+sf_[0].pts_[0]))/2;
00849 
00850         //std::cout<<"C\n"<<M<<"\n";
00851       }
00852       else {
00853         M.col(0) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+(bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))))+bc(0)*
00854             ((-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+pts_[ind[0]])+(-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))+bc(1)*
00855             ((-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))+bc(0)*pts_[ind[0]];
00856         M.col(1) = -(-bc(1)-bc(0)+1)*pts_[ind[2]]+(-bc(1)-bc(0)+1)*(-pts_[ind[2]]+bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(1)*
00857             (pts_[ind[1]]+(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0))))+bc(1)*pts_[ind[1]]+bc(0)*
00858             ((-bc(1)-bc(0)+1)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-(bc(0)*sf_[2].pts_[1])/(1-bc(1))-((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)))-bc(0)*((bc(0)*sf_[2].pts_[1])/(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1)))-bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+
00859             (-bc(1)-bc(0)+1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/(1-bc(0)))+bc(0)*((bc(1)*sf_[0].pts_[1])/(bc(1)+bc(0))+(bc(0)*sf_[0].pts_[0])/(bc(1)+bc(0)));
00860       }
00861 #else
00862       const float a=bc(0), b=bc(1);
00863 
00864       if(std::abs(a-1)<0.001f) {
00865         //        M.col(0) = 2*pts_[ind[0]]-2*sf_[2].pts_[1];
00866         //        M.col(1) = 2*sf_[0].pts_[0]-2*sf_[2].pts_[1];
00867 
00868         M.col(0) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))+(a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))+a*((-b-a+1)*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+pts_[ind[0]])+(-b-a+1)*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))+b*(-(sf_[1].pts_[1]+sf_[1].pts_[0])/2+a*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-(b*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+b*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))+a*pts_[ind[0]] ).head<3>();
00869         M.col(1) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))+(sf_[1].pts_[1]+sf_[1].pts_[0])/2)+b*(pts_[ind[1]]-(sf_[1].pts_[1]+sf_[1].pts_[0])/2+a*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a)))+b*pts_[ind[1]]+a*((-b-a+1)*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-(b*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+((-b-a+1)*(sf_[1].pts_[1]+sf_[1].pts_[0]))/2+a*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a)) ).head<3>();
00870 
00871         //std::cout<<"A\n"<<M<<"\n";
00872       }
00873       else if(std::abs(b-1)<0.001f) {
00874         //        M.col(0) = 2*sf_[0].pts_[1]-2*sf_[1].pts_[0];
00875         //        M.col(1) = 2*pts_[ind[1]]-2*sf_[1].pts_[0];
00876 
00877         M.col(0) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+(sf_[2].pts_[1]+sf_[2].pts_[0])/2+b*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a)))+a*(-(sf_[2].pts_[1]+sf_[2].pts_[0])/2+b*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+pts_[ind[0]])+((-b-a+1)*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2-(a*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2+b*((-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+a*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))+a*pts_[ind[0]] ).head<3>();
00878         M.col(1) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+b*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))+((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*(pts_[ind[1]]+(-b-a+1)*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+a*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a)))+b*pts_[ind[1]]+a*(-(sf_[2].pts_[1]+sf_[2].pts_[0])/2+b*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-(a*(sf_[2].pts_[1]+sf_[2].pts_[0]))/2-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+(-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+a*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a)) ).head<3>();
00879 
00880         //std::cout<<"B\n"<<M<<"\n";
00881       }
00882       else if( std::abs(a+b)<0.003f) {
00883         //        M.col(0) = 2*sf_[2].pts_[0]-2*pts_[ind[2]];
00884         //        M.col(1) = 2*sf_[1].pts_[1]-2*pts_[ind[2]];
00885 
00886         M.col(0) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))+(a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a)))+a*((-b-a+1)*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+pts_[ind[0]])+(-b-a+1)*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))+b*((-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+(sf_[0].pts_[1]+sf_[0].pts_[0])/2)-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+(b*(sf_[0].pts_[1]+sf_[0].pts_[0]))/2+a*pts_[ind[0]] ).head<3>();
00887         M.col(1) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))+b*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))+((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*(pts_[ind[1]]+(-b-a+1)*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a))+b*pts_[ind[1]]+a*((-b-a+1)*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+(sf_[0].pts_[1]+sf_[0].pts_[0])/2)-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+(-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+(a*(sf_[0].pts_[1]+sf_[0].pts_[0]))/2 ).head<3>();
00888 
00889         //std::cout<<"C\n"<<M<<"\n";
00890       }
00891       else {
00892 #if 0
00893         M.col(0) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))+(a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a)))+a*
00894             ((-b-a+1)*(sf_[2].pts_[1]/(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+pts_[ind[0]])+(-b-a+1)*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))+b*
00895             ((-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/POW2(1-a)-sf_[1].pts_[1]/(1-a)+(b*sf_[1].pts_[0])/POW2(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+a*(-(b*sf_[0].pts_[1])/POW2(b+a)+sf_[0].pts_[0]/(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))+a*pts_[ind[0]] ).head<3>();
00896         M.col(1) = ( -(-b-a+1)*pts_[ind[2]]+(-b-a+1)*(-pts_[ind[2]]+a*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))+b*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))+((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+b*
00897             (pts_[ind[1]]+(-b-a+1)*(sf_[1].pts_[0]/(1-a)-sf_[1].pts_[1]/(1-a))-((-b-a+1)*sf_[1].pts_[1])/(1-a)-(b*sf_[1].pts_[0])/(1-a)+a*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a)))+b*pts_[ind[1]]+a*
00898             ((-b-a+1)*((a*sf_[2].pts_[1])/POW2(1-b)+((-b-a+1)*sf_[2].pts_[0])/POW2(1-b)-sf_[2].pts_[0]/(1-b))-(a*sf_[2].pts_[1])/(1-b)-((-b-a+1)*sf_[2].pts_[0])/(1-b)+b*(sf_[0].pts_[1]/(b+a)-(b*sf_[0].pts_[1])/POW2(b+a)-(a*sf_[0].pts_[0])/POW2(b+a))+(b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a))-a*((a*sf_[2].pts_[1])/(1-b)+((-b-a+1)*sf_[2].pts_[0])/(1-b))-b*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+
00899             (-b-a+1)*(((-b-a+1)*sf_[1].pts_[1])/(1-a)+(b*sf_[1].pts_[0])/(1-a))+a*((b*sf_[0].pts_[1])/(b+a)+(a*sf_[0].pts_[0])/(b+a)) ).head<3>();
00900 #else
00901 
00902         const float a2=a*a, b2=b*b;
00903         const float a3=a2*a, b3=b2*b;
00904 
00905         M.col(0) = M.col(1) = (2*b*pts_[ind[2]]+2*a*pts_[ind[2]]-2*pts_[ind[2]] ).head<3>();
00906 
00907         M.col(0) += (
00908             ((4*a*b+6*a2-4*a)*sf_[2].pts_[1]+(-2*b2+(4-8*a)*b-6*a2+8*a-2)*sf_[2].pts_[0])/(b-1)
00909             +(2*b2*sf_[0].pts_[1]+4*a*b*sf_[0].pts_[0])/(b+a)
00910             -(2*a*b2*sf_[0].pts_[1]+2*a2*b*sf_[0].pts_[0])/(b2+2*a*b+a2)
00911             -((4*b2+(4*a-4)*b)*sf_[1].pts_[1]-2*b2*sf_[1].pts_[0])/(a-1)
00912             +((2*b3+(4*a-4)*b2+(2*a2-4*a+2)*b)*sf_[1].pts_[1]+((2-2*a)*b2-2*b3)*sf_[1].pts_[0])/(a2-2*a+1)
00913             +2*a*pts_[ind[0]]
00914         ).head<3>();
00915         M.col(1) += (
00916             (2*a2*sf_[2].pts_[1]+(-4*a*b-4*a2+4*a)*sf_[2].pts_[0])/(b-1)
00917             +(4*a*b*sf_[0].pts_[1]+2*a2*sf_[0].pts_[0])/(b+a)
00918             -(2*a*b2*sf_[0].pts_[1]+2*a2*b*sf_[0].pts_[0])/(b2+2*a*b+a2)
00919             -((6*b2+(8*a-8)*b+2*a2-4*a+2)*sf_[1].pts_[1]+((4-4*a)*b-6*b2)*sf_[1].pts_[0])/(a-1)
00920             -((2*a2*b+2*a3-2*a2)*sf_[2].pts_[1]+(-2*a*b2+(4*a-4*a2)*b-2*a3+4*a2-2*a)*sf_[2].pts_[0])/(b2-2*b+1)
00921             +2*b*pts_[ind[1]]
00922         ).head<3>();
00923 #endif
00924       }
00925 #endif
00926 
00927       if(!pcl_isfinite(M.sum())) {
00928         std::cout<<"INF2 v\n"<<M<<"\n";
00929         std::cout<<"bc\n"<<bc<<"\n";
00930         std::cout<<"T\n"<<_T_<<"\n";
00931         size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00932 
00933         for(int i=0; i<3; i++) {
00934           std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00935           std::cout<<"uv\n"<<uv_[i]<<"\n";
00936         }
00937       }
00938 
00939       return M;
00940     }
00941 
00942     inline Eigen::Matrix<float,3,2> normal2BC(const Eigen::Vector2f &bc) {
00943       //      if(std::abs(bc(0)-1)<0.0010f)
00944       //        return n2_[0];
00945       //      else if(std::abs(bc(1)-1)<0.0010f)
00946       //        return n2_[1];
00947       //      else if( std::abs(bc(0))+std::abs(bc(1))<0.0001f)
00948       //        return n2_[2];
00949 
00950       static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00951 
00952       Eigen::Matrix<float,3,2> M;
00953       if(std::abs(bc(0)-1)<0.001f) {
00954         M.col(0) = (2*pts_[ind[2]]+(-bc(1)-bc(0)+1)*((2*sf_[2].pts_[1])/(1-bc(1))-(2*sf_[2].pts_[0])/(1-bc(1)))+2*(-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-2*bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(0)*(-(2*sf_[2].pts_[1])/(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))))-(4*bc(0)*sf_[2].pts_[1])/(1-bc(1))-(4*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(bc(0)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*sf_[0].pts_[0])/(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+2*bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+2*pts_[ind[0]] ).head<3>();
00955         M.col(1) = (2*pts_[ind[2]]+2*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))-(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))+(2*sf_[0].pts_[1])/(bc(1)+bc(0))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))-2*bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(0)*(-bc(1)-bc(0)+1)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-2*sf_[1].pts_[1]-2*sf_[1].pts_[0]+2*bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+bc(0)*bc(1)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))) ).head<3>();
00956 
00957         //std::cout<<"A\n"<<M<<"\n";
00958       }
00959       else if(std::abs(bc(1)-1)<0.001f) {
00960         M.col(0) = (2*pts_[ind[2]]-2*sf_[2].pts_[1]-2*sf_[2].pts_[0]+bc(1)*((-bc(1)-bc(0)+1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0)))-(2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))+(2*sf_[1].pts_[1])/(1-bc(0))-(2*bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))+bc(0)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*sf_[0].pts_[0])/(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))-2*bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))+(-bc(1)-bc(0)+1)*bc(1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0)))+2*bc(1)*(-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+bc(0)*bc(1)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))+2*pts_[ind[0]]).head<3>();
00961         M.col(1) = (2*pts_[ind[2]]+2*pts_[ind[1]]+bc(1)*((2*sf_[1].pts_[1])/(1-bc(0))-(2*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))))-2*bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+2*(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+(-bc(1)-bc(0)+1)*((2*sf_[1].pts_[0])/(1-bc(0))-(2*sf_[1].pts_[1])/(1-bc(0)))-(4*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(4*bc(1)*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(bc(1)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))+(2*sf_[0].pts_[1])/(bc(1)+bc(0))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+2*bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))).head<3>();
00962 
00963         //std::cout<<"B\n"<<M<<"\n";
00964       }
00965       else if( std::abs(bc(0)+bc(1))<0.001f) {
00966         M.col(0) = (2*pts_[ind[2]]+(-bc(1)-bc(0)+1)*((2*sf_[2].pts_[1])/(1-bc(1))-(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0))))+2*(-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-2*bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(0)*((2*sf_[2].pts_[0])/(1-bc(1))-(2*sf_[2].pts_[1])/(1-bc(1)))-(4*bc(0)*sf_[2].pts_[1])/(1-bc(1))-(4*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((-bc(1)-bc(0)+1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0)))-(2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))+(2*sf_[1].pts_[1])/(1-bc(0))-(2*bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))-2*bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))+2*pts_[ind[0]]).head<3>();
00967         M.col(1) = (2*pts_[ind[2]]+2*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))-(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1)))+(-bc(1)-bc(0)+1)*(bc(0)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*sf_[1].pts_[1])/(1-bc(0))+(2*sf_[1].pts_[0])/(1-bc(0)))-2*bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(1)*((2*sf_[1].pts_[1])/(1-bc(0))-(2*sf_[1].pts_[0])/(1-bc(0)))-2*bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+2*(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-(4*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(4*bc(1)*sf_[1].pts_[0])/(1-bc(0))).head<3>();
00968 
00969         //std::cout<<"C\n"<<M<<"\n";
00970       }
00971       else {
00972         M.col(0) = (2*pts_[ind[2]]+(-bc(1)-bc(0)+1)*((2*sf_[2].pts_[1])/(1-bc(1))-(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0))))+2*(-bc(1)-bc(0)+1)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))-2*bc(0)*(sf_[2].pts_[1]/(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(0)*(-(2*sf_[2].pts_[1])/(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))))-(4*bc(0)*sf_[2].pts_[1])/(1-bc(1))-
00973             (4*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/(1-bc(1))+bc(1)*((-bc(1)-bc(0)+1)*((2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW3(1-bc(0))-(2*sf_[1].pts_[1])/POW2(1-bc(0))+(2*bc(1)*sf_[1].pts_[0])/POW3(1-bc(0)))-(2*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))+(2*sf_[1].pts_[1])/(1-bc(0))-(2*bc(1)*sf_[1].pts_[0])/POW2(1-bc(0))+bc(0)*((2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))-(2*sf_[0].pts_[0])/POW2(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*sf_[0].pts_[0])/(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))-2*bc(1)*(((-bc(1)-bc(0)+1)*sf_[1].pts_[1])/POW2(1-bc(0))-sf_[1].pts_[1]/(1-bc(0))+(bc(1)*sf_[1].pts_[0])/POW2(1-bc(0)))+2*bc(1)*
00974             (-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+sf_[0].pts_[0]/(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+2*pts_[ind[0]] ).head<3>();
00975 
00976         M.col(1) =
00977             (2*pts_[ind[2]]+2*pts_[ind[1]]+bc(0)*((-bc(1)-bc(0)+1)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))-(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))+(2*sf_[2].pts_[0])/(1-bc(1))+bc(1)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0)))+(2*sf_[0].pts_[1])/(bc(1)+bc(0))-(2*bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(2*bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0)))+(-bc(1)-bc(0)+1)*
00978                 (bc(0)*((2*bc(0)*sf_[2].pts_[1])/POW3(1-bc(1))+(2*(-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW3(1-bc(1))-(2*sf_[2].pts_[0])/POW2(1-bc(1)))-(2*sf_[1].pts_[1])/(1-bc(0))+(2*sf_[1].pts_[0])/(1-bc(0)))-2*bc(0)*((bc(0)*sf_[2].pts_[1])/POW2(1-bc(1))+((-bc(1)-bc(0)+1)*sf_[2].pts_[0])/POW2(1-bc(1))-sf_[2].pts_[0]/(1-bc(1)))+bc(1)*((2*sf_[1].pts_[1])/(1-bc(0))-(2*sf_[1].pts_[0])/(1-bc(0))+bc(0)*(-(2*sf_[0].pts_[1])/POW2(bc(1)+bc(0))+(2*bc(1)*sf_[0].pts_[1])/POW3(bc(1)+bc(0))+(2*bc(0)*sf_[0].pts_[0])/POW3(bc(1)+bc(0))))-2*bc(1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))+2*(-bc(1)-bc(0)+1)*(sf_[1].pts_[0]/(1-bc(0))-sf_[1].pts_[1]/(1-bc(0)))-
00979                 (4*(-bc(1)-bc(0)+1)*sf_[1].pts_[1])/(1-bc(0))-(4*bc(1)*sf_[1].pts_[0])/(1-bc(0))+2*bc(0)*(sf_[0].pts_[1]/(bc(1)+bc(0))-(bc(1)*sf_[0].pts_[1])/POW2(bc(1)+bc(0))-(bc(0)*sf_[0].pts_[0])/POW2(bc(1)+bc(0))) ).head<3>();
00980       }
00981 
00982       if(!pcl_isfinite(M.sum())) {
00983         std::cout<<"INF3 v\n"<<M<<"\n";
00984         std::cout<<"bc\n"<<bc<<"\n";
00985         std::cout<<"T\n"<<_T_<<"\n";
00986         size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
00987 
00988         for(int i=0; i<3; i++) {
00989           std::cout<<"cp\n"<<pts_[ind[i]]<<"\n";
00990           std::cout<<"uv\n"<<uv_[i]<<"\n";
00991         }
00992       }
00993 
00994       return M;
00995     }
00996 
00997     inline bool inside(const Eigen::Vector2f &uv) const {
00998       Eigen::Vector2f br;
00999 
01000       br = _T_*(uv-uv_[2]);
01001 
01002       return ( std::abs(br(0))+std::abs(br(1))+std::abs(1-br(0)-br(1))<=1 );
01003 
01004     }
01005 
01006     inline bool complete_inside(const Eigen::Vector2f &uv) const {
01007       Eigen::Vector2f br;
01008 
01009       br = _T_*(uv-uv_[2]);
01010 
01011       return ( std::abs(br(0))+std::abs(br(1))+std::abs(1-br(0)-br(1))<1 );
01012 
01013     }
01014 
01015     static float sqDistLinePt(const Eigen::Vector2f &uv, const Eigen::Vector2f &r1, const Eigen::Vector2f &r2) {
01016       float f = (uv-r1).dot(r2-r1) / (r2-r1).squaredNorm();
01017       if(f>1) f=1;
01018       else if(f<0) f=0;
01019       return (uv - f*(r2-r1) - r1).squaredNorm();
01020     }
01021 
01022     bool polating(const Eigen::Vector3f &pt, const Eigen::Vector2f &uv, bool &inside, Eigen::Vector2f &r1, Eigen::Vector2f &r2) {
01023       static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
01024       float dist[3] = { (pt-pts_[ind[0]].head<3>()).squaredNorm(), (pt-pts_[ind[1]].head<3>()).squaredNorm(), (pt-pts_[ind[2]].head<3>()).squaredNorm() };
01025 
01026       Eigen::Vector2f br;
01027 
01028       br = _T_*(uv-uv_[2]);
01029 //      std::cout<<"br\n"<<br<<"\n";
01030 //      std::cout<<"pt\n"<<pt<<"\n";
01031 
01032       if( std::abs(br(0))+std::abs(br(1))+std::abs(1-br(0)-br(1))<=1 ) {
01033         inside=true;
01034         r1=uv;
01035         return true;
01036         for(int i=0; i<3; i++) dist[i]=std::sqrt(dist[i]);
01037         br(0) = dist[0]/(dist[0]+dist[1]+dist[2]);
01038         br(1) = dist[1]/(dist[0]+dist[1]+dist[2]);
01039 //        std::cout<<"uv3434\n"<<_T_.inverse()*br + uv_[2]<<"\n"<<br<<"\n"<<dist[2]/(dist[0]+dist[1]+dist[2])<<std::endl;
01040         r1 = _T_.inverse()*br + uv_[2];
01041         return true;
01042       }
01043 
01044       inside=false;
01045 
01046       int m=0;
01047       if(sqDistLinePt(uv,uv_[(1+1)%3],uv_[(1+2)%3])<sqDistLinePt(uv,uv_[(m+1)%3],uv_[(m+2)%3])) m=1;
01048       if(sqDistLinePt(uv,uv_[(2+1)%3],uv_[(2+2)%3])<sqDistLinePt(uv,uv_[(m+1)%3],uv_[(m+2)%3])) m=2;
01049       const int a = (m+1)%3;
01050       const int b = (m+2)%3;
01051       const float f = (uv_[a]-uv_[b]).squaredNorm()/(pts_[ind[a]]-pts_[ind[b]]).squaredNorm();
01052 
01053 //      std::cout<<"r1 "<<std::sqrt(dist[a])<<"\n";
01054 //      std::cout<<"r2 "<<std::sqrt(dist[b])<<"\n";
01055 //      std::cout<<"r3 "<<(pts_[ind[a]]-pts_[ind[b]]).norm()<<"\n";
01056 
01057       Eigen::Vector2f p1, p2;
01058 
01059       if(pcl_isfinite(f)) {
01060         dist[a]*=f;
01061         dist[b]*=f;
01062 
01063         if(std::abs((2*uv_[b](0)-2*uv_[a](0)))>std::abs((2*uv_[b](1)-2*uv_[a](1)))) {
01064           const float n = -(2*uv_[b](1)-2*uv_[a](1)) / (2*uv_[b](0)-2*uv_[a](0));
01065           const float o = uv_[a](0)+(dist[b]-dist[a]+uv_[a].squaredNorm()-uv_[b].squaredNorm())/(2*uv_[b](0)-2*uv_[a](0));
01066 
01067           p1(1)=-(std::sqrt((n*n+1)*dist[a]-o*o+2*uv_[a](1)*n*o-uv_[a](1)*uv_[a](1)*n*n)-(n*o+uv_[a](1)))/(n*n+1);
01068           p2(1)= (std::sqrt((n*n+1)*dist[a]-o*o+2*uv_[a](1)*n*o-uv_[a](1)*uv_[a](1)*n*n)+(n*o+uv_[a](1)))/(n*n+1);
01069           p1(0) = n*p1(1) - o+uv_[a](0);
01070           p2(0) = n*p2(1) - o+uv_[a](0);
01071 
01072 //          std::cout<<"n "<<n<<"\n";
01073 //          std::cout<<"o "<<o<<std::endl;
01074         }
01075         else {
01076           const float n = -(2*uv_[b](0)-2*uv_[a](0)) / (2*uv_[b](1)-2*uv_[a](1));
01077           const float o = uv_[a](1)+(dist[b]-dist[a]+uv_[a].squaredNorm()-uv_[b].squaredNorm())/(2*uv_[b](1)-2*uv_[a](1));
01078 
01079           p1(0)=-(std::sqrt((n*n+1)*dist[a]-o*o+2*uv_[a](0)*n*o-uv_[a](0)*uv_[a](0)*n*n)-(n*o+uv_[a](0)))/(n*n+1);
01080           p2(0)= (std::sqrt((n*n+1)*dist[a]-o*o+2*uv_[a](0)*n*o-uv_[a](0)*uv_[a](0)*n*n)+(n*o+uv_[a](0)))/(n*n+1);
01081           p1(1) = n*p1(0) - o+uv_[a](1);
01082           p2(1) = n*p2(0) - o+uv_[a](1);
01083 
01084 //          std::cout<<"n "<<n<<"\n";
01085 //          std::cout<<"o "<<o<<std::endl;
01086         }
01087       }
01088 
01089 //      std::cout<<"a\n"<<uv_[a]<<"\n";
01090 //      std::cout<<"b\n"<<uv_[b]<<"\n";
01091 //      std::cout<<"r1 "<<std::sqrt(dist[a])<<"\n";
01092 //      std::cout<<"r2 "<<std::sqrt(dist[b])<<"\n";
01093 //      std::cout<<"r3 "<<(uv_[a]-uv_[b]).norm()<<"\n";
01094 //      std::cout<<"r\n"<<(uv_[a]-uv_[b]).squaredNorm()<<"\n";
01095 //      std::cout<<"p1\n"<<p1<<"\n";
01096 //      std::cout<<"p2\n"<<p2<<std::endl;
01097 //      std::cout<<"uvm\n"<<uv_[m]<<std::endl;
01098 //      std::cout<<"d1 "<<(p1-uv_[m]).squaredNorm()<<"\n";
01099 //      std::cout<<"d2 "<<(p2-uv_[m]).squaredNorm()<<std::endl;
01100 
01101       if(!pcl_isfinite(f)|| (!pcl_isfinite(p1.sum()) && !pcl_isfinite(p2.sum())) ) {
01102         dist[a] = std::sqrt(dist[a]);
01103         dist[b] = std::sqrt(dist[b]);
01104 
01105 //        std::cout<<"using second\n"<<std::endl;
01106 
01107         r1 = (uv_[a]*dist[a] + uv_[b]*dist[b])/(dist[a]+dist[b]);
01108         inside=true;
01109         return true;
01110       }
01111 
01112 //      std::cout<<"br\n"<< _T_*(uv-uv_[2])<<std::endl;
01113 //      ROS_ASSERT( !(this->inside(p1)&&this->inside(p2)) );
01114 
01115       r1 = p1;
01116       r2 = p2;
01117       return false;
01118     }
01119 
01120     void print() const {
01121       static const size_t ind[3] = { indAB(0,ORDER), indAB(ORDER,ORDER), indAB(0,0) };
01122       for(int i=0; i<3; i++) {
01123         std::cout<<"pt\n"<<pts_[ind[i]]<<"\n";
01124         std::cout<<"n\n"<<n_[ind[i]]<<"\n";
01125         std::cout<<"n2\n"<<n2_[ind[i]]<<"\n";
01126       }
01127       for(int i=0; i<3; i++)
01128         sf_[i].print();
01129       std::cout<<std::endl;
01130     }
01131 
01132   };
01133 }
01134 
01135 #endif /* TRISPLINE_H_ */


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