contrib/mul/vimt/vimt_transform_2d.cxx

Go to the documentation of this file.
00001 // This is mul/vimt/vimt_transform_2d.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 //  \file
00007 
00008 #include "vimt_transform_2d.h"
00009 #include <vcl_cmath.h>
00010 #include <vcl_cstdlib.h> // for vcl_abort()
00011 #include <vcl_cassert.h>
00012 #include <vsl/vsl_indent.h>
00013 #include <vnl/vnl_vector.h>
00014 #include <vnl/vnl_matrix.h>
00015 #include <vnl/vnl_inverse.h>
00016 
00017 vnl_matrix<double> vimt_transform_2d::matrix() const
00018 {
00019     vnl_matrix<double> M(3,3);
00020     matrix(M);
00021     return M;
00022 }
00023 
00024 void vimt_transform_2d::matrix(vnl_matrix<double>& M) const
00025 {
00026     M.set_size(3,3);
00027     double**m_data = M.data_array();
00028     m_data[0][0]=xx_;   m_data[0][1]=xy_;   m_data[0][2]=xt_;
00029     m_data[1][0]=yx_;   m_data[1][1]=yy_;   m_data[1][2]=yt_;
00030     m_data[2][0]=tx_;   m_data[2][1]=ty_;   m_data[2][2]=tt_;
00031 }
00032 
00033 void vimt_transform_2d::params_of(vnl_vector<double>& v, Form form) const
00034 {
00035     double *v_data;
00036     switch (form)
00037     {
00038         case (Identity):
00039             v.set_size(0);
00040             break;
00041         case (Translation):
00042             v.set_size(2);
00043             v(0)=xt_; v(1)=yt_;
00044             break;
00045         case (ZoomOnly):
00046             v.set_size(4);
00047             v(0)=xx_; v(1)=yy_;
00048             v(2)=xt_; v(3)=yt_;
00049             break;
00050         case (RigidBody):
00051             v.set_size(3);
00052             v(0)=vcl_atan2(-xy_,xx_); // Angle
00053             v(1)=xt_; v(2)=yt_;
00054             break;
00055         case (Reflection):
00056             v.set_size(4);
00057             v_data = v.begin();
00058             v_data[0]=xx_; v_data[1]=xy_;
00059             v_data[2]=xt_; v_data[3]=yt_;
00060             break;
00061         case (Similarity):
00062             v.set_size(4);
00063             v_data = v.begin();
00064             v_data[0]=xx_; v_data[1]=xy_;
00065             v_data[2]=xt_; v_data[3]=yt_;
00066             break;
00067         case (Affine):
00068             v.set_size(6);
00069             v_data = v.begin();
00070             v_data[0]=xx_; v_data[1]=xy_; v_data[2]=xt_;
00071             v_data[3]=yx_; v_data[4]=yy_; v_data[5]=yt_;
00072             break;
00073         case (Projective):
00074             v.set_size(9);
00075             v_data = v.begin();
00076             v_data[0]=xx_; v_data[1]=xy_; v_data[2]=xt_;
00077             v_data[3]=yx_; v_data[4]=yy_; v_data[5]=yt_;
00078             v_data[6]=tx_; v_data[7]=ty_; v_data[8]=tt_;
00079             break;
00080         default:
00081             vcl_cerr<<"vimt_transform_2d::params() Unexpected form: "<<int(form)<<vcl_endl;
00082             vcl_abort();
00083     }
00084 }
00085 
00086 void vimt_transform_2d::setCheck(int n1,int n2,const char* str) const
00087 {
00088     if (n1==n2) return;
00089     vcl_cerr<<"vimt_transform_2d::set() "<<n1<<" parameters required for "
00090             <<str<<". Passed "<<n2<<vcl_endl;
00091     vcl_abort();
00092 }
00093 
00094 void vimt_transform_2d::set(const vnl_vector<double>& v, Form form)
00095 {
00096     int n=v.size();
00097     const double* v_data = v.begin();
00098 
00099     switch (form)
00100     {
00101         case (Identity):
00102             set_identity();
00103             break;
00104         case (Translation):
00105             setCheck(2,n,"Translation");
00106             set_translation(v_data[0],v_data[1]);
00107             break;
00108         case (ZoomOnly):
00109             setCheck(4,n,"ZoomOnly");
00110             set_zoom_only(v_data[0],v_data[1],v_data[2],v_data[3]);
00111             break;
00112         case (RigidBody):
00113             setCheck(3,n,"RigidBody");
00114             set_rigid_body(v_data[0],v_data[1],v_data[2]);
00115             break;
00116         case (Reflection):
00117             setCheck(4,n,"Reflection");
00118             xx_ = v_data[0]; xy_ = v_data[1];
00119             yx_ = xy_; yy_ = -xx_;
00120             xt_ = v_data[2]; yt_ = v_data[3];
00121             form_ = Reflection;
00122             inv_uptodate_=false;
00123             break;
00124         case (Similarity):
00125             setCheck(4,n,"Similarity");
00126             xx_ = v_data[0]; xy_ = v_data[1];
00127             yx_ = -xy_; yy_=xx_;
00128             xt_ = v_data[2]; yt_ = v_data[3];
00129             form_ = Similarity;
00130             inv_uptodate_=false;
00131             break;
00132         case (Affine):
00133             setCheck(6,n,"Affine");
00134             xx_ = v_data[0]; xy_ = v_data[1]; xt_ = v_data[2];
00135             yx_ = v_data[3]; yy_ = v_data[4]; yt_ = v_data[5];
00136             form_ = Affine;
00137             inv_uptodate_=false;
00138             break;
00139         case (Projective):
00140             setCheck(9,n,"Projective");
00141             xx_ = v_data[0]; xy_ = v_data[1]; xt_ = v_data[2];
00142             yx_ = v_data[3]; yy_ = v_data[4]; yt_ = v_data[5];
00143             tx_ = v_data[6]; ty_ = v_data[7]; tt_ = v_data[8];
00144             form_ = Projective;
00145             inv_uptodate_=false;
00146             break;
00147         default:
00148             vcl_cerr<<"vimt_transform_2d::set() Unexpected form: "<<int(form)<<vcl_endl;
00149             vcl_abort();
00150     }
00151 }
00152 
00153 
00154 void vimt_transform_2d::set_identity()
00155 {
00156     if (form_==Identity) return;
00157     form_=Identity;
00158     xx_=yy_=tt_=1.0;
00159     xy_=xt_=0.0;
00160     yx_=yt_=0.0;
00161     tx_=ty_=0.0;
00162 
00163     inv_uptodate_=false;
00164 }
00165 
00166 void vimt_transform_2d::set_translation(double t_x, double t_y)
00167 {
00168     if (t_x==0 && t_y==0)
00169         set_identity();
00170     else
00171     {
00172         form_=Translation;
00173         xx_=yy_=tt_=1.0;
00174         xy_=0.0;
00175         yx_=0.0;
00176         tx_=ty_=0.0;
00177         xt_=t_x;
00178         yt_=t_y;
00179     }
00180 
00181     inv_uptodate_=false;
00182 }
00183 
00184 void vimt_transform_2d::set_origin( const vgl_point_2d<double> & p )
00185 {
00186     xt_ = p.x()*tt_;
00187     yt_ = p.y()*tt_;
00188 
00189     if (form_ == Identity) form_=Translation;
00190 
00191     inv_uptodate_=false;
00192 }
00193 
00194 void vimt_transform_2d::set_zoom_only(double s_x, double s_y, double t_x, double t_y)
00195 {
00196     form_=ZoomOnly;
00197     xx_=s_x;   yy_=s_y;   tt_=1.0;
00198     xt_=t_x;   yt_=t_y;
00199     xy_=yx_=tx_=ty_=0.0;
00200 
00201     inv_uptodate_=false;
00202 }
00203 
00204 
00205     //: reflect about a line though the points m1, and m2
00206 void vimt_transform_2d::set_reflection( const vgl_point_2d<double> & m1, const vgl_point_2d<double> & m2)
00207 {
00208     form_=Reflection;
00209 
00210     assert (m1 != m2);
00211     const double m1x = m1.x();
00212     const double m1y = m1.y();
00213     const double m2x = m2.x();
00214     const double m2y = m2.y();
00215     const double dx = m2x - m1x;
00216     const double dy = m2y - m1y;
00217     const double dx2dy2 = dx*dx + dy*dy;
00218 
00219 // after plugging all the equations for mirroring into matlab symbolic calculator,
00220 // I had to rearrange the equations to avoid divide-by-zero. See notebook for details. IMS
00221 
00222     xx_ = (dx*dx - dy*dy) / dx2dy2;
00223 
00224     xy_ = 2.0*dx*dy / dx2dy2;
00225 
00226     xt_ = (2.0*m1x*dy*dy - 2.0*m1y*dx*dy) / dx2dy2;
00227 
00228     yx_ = 2.0*dx*dy / dx2dy2;
00229 
00230     yy_ = (dy*dy - dx*dx) / dx2dy2;
00231 
00232     yt_ = (2.0*m1y*dx*dx - 2.0*m1x*dx*dy) / dx2dy2;
00233 
00234     tx_ = ty_ = 0.0;
00235     tt_ = 1.0;
00236 }
00237 
00238 void vimt_transform_2d::set_rigid_body(double theta, double t_x, double t_y)
00239 {
00240     if (theta==0.0)
00241         set_translation(t_x,t_y);
00242     else
00243     {
00244         form_=RigidBody;
00245         double a=vcl_cos(theta);
00246         double b=vcl_sin(theta);
00247         xx_=a;  xy_=-b;
00248         yx_=b;  yy_=a;
00249         xt_=t_x;   yt_=t_y;
00250         tx_=ty_=0.0;   tt_=1.0;
00251     }
00252 
00253     inv_uptodate_=false;
00254 }
00255 
00256 void vimt_transform_2d::set_similarity(double s, double theta, double t_x, double t_y)
00257 {
00258     if (s==1.0)
00259         set_rigid_body(theta,t_x,t_y);
00260     else
00261     {
00262         form_=Similarity;
00263         double a=s*vcl_cos(theta);
00264         double b=s*vcl_sin(theta);
00265         xx_=a;  xy_=-b;
00266         yx_=b;  yy_=a;
00267         xt_=t_x;   yt_=t_y;
00268         tx_=ty_=0.0;   tt_=1.0;
00269     }
00270 
00271     inv_uptodate_=false;
00272 }
00273 
00274 //: Sets Euclidean transformation.
00275 void vimt_transform_2d::set_similarity(const vgl_point_2d<double> & dx,
00276                                        const vgl_point_2d<double> & t)
00277 {
00278     form_=Similarity;
00279     xx_ = dx.x(); xy_ = -dx.y();
00280     yx_ = dx.y(); yy_ = dx.x();
00281     xt_ = t.x();  yt_ = t.y();
00282     tx_=ty_=0.0;   tt_=1.0;
00283     inv_uptodate_=false;
00284 }
00285 
00286 //: Sets Euclidean transformation.
00287 void vimt_transform_2d::set_similarity(const vgl_vector_2d<double> & dx,
00288                                        const vgl_point_2d<double> & t)
00289 {
00290     form_=Similarity;
00291     xx_ = dx.x(); xy_ = -dx.y();
00292     yx_ = dx.y(); yy_ = dx.x();
00293     xt_ = t.x();  yt_ = t.y();
00294     tx_=ty_=0.0;   tt_=1.0;
00295     inv_uptodate_=false;
00296 }
00297 
00298 
00299 void vimt_transform_2d::set_affine(const vnl_matrix<double>& M23)  // 2x3 matrix
00300 {
00301     if ((M23.rows()!=2) || (M23.columns()!=3))
00302     {
00303         vcl_cerr<<"vimt_transform_2d::affine : Expect 2x3 matrix, got "<<M23.rows()<<" x "<<M23.columns()<<vcl_endl;
00304         vcl_abort();
00305     }
00306 
00307     const double *const *m_data=M23.data_array();
00308 
00309     if (m_data[0][0]*m_data[1][1] < m_data[0][1]*m_data[1][0])
00310     {
00311         vcl_cerr << "vimt_transform_2d::affine :\n"
00312                  << "sub (2x2) matrix should have positive determinant\n";
00313         vcl_abort();
00314     }
00315 
00316     xx_=m_data[0][0];   xy_=m_data[0][1]; xt_=m_data[0][2];
00317     yx_=m_data[1][0];   yy_=m_data[1][1]; yt_=m_data[1][2];
00318     tx_=ty_=0.0;   tt_=1.0;
00319 
00320     form_=Affine;
00321 
00322     inv_uptodate_=false;
00323 }
00324 
00325 //: Sets to be 2D affine transformation T(x,y)=p+x.u+y.v
00326 void vimt_transform_2d::set_affine(const vgl_point_2d<double> & p,
00327                                    const vgl_vector_2d<double> & u,
00328                                    const vgl_vector_2d<double> & v)
00329 {
00330   xt_ = p.x();
00331   yt_ = p.y();
00332   xx_ = u.x();
00333   yx_ = u.y();
00334   xy_ = v.x();
00335   yy_ = v.y();
00336   form_=Affine;
00337   inv_uptodate_=false;
00338 }
00339 
00340 void vimt_transform_2d::set_projective(const vnl_matrix<double>& M33)   // 3x3 matrix
00341 {
00342      if ((M33.rows()!=3) || (M33.columns()!=3))
00343     {
00344         vcl_cerr<<"vimt_transform_2d::projective : Expect 3x3 matrix, got "<<M33.rows()<<" x "<<M33.columns()<<vcl_endl;
00345         vcl_abort();
00346     }
00347 
00348     const double *const *m_data=M33.data_array();
00349     xx_=m_data[0][0];   xy_=m_data[0][1]; xt_=m_data[0][2];
00350     yx_=m_data[1][0];   yy_=m_data[1][1]; yt_=m_data[1][2];
00351     tx_=m_data[2][0];   ty_=m_data[2][1]; tt_=m_data[2][2];
00352 
00353     form_=Projective;
00354 
00355     inv_uptodate_=false;
00356 }
00357 
00358 vgl_point_2d<double>  vimt_transform_2d::operator()(double x, double y) const
00359 {
00360     double z;
00361     switch (form_)
00362     {
00363         case Identity :
00364             return vgl_point_2d<double> (x,y);
00365         case Translation :
00366             return vgl_point_2d<double> (x+xt_,y+yt_);
00367         case ZoomOnly :
00368             return vgl_point_2d<double> (x*xx_+xt_,y*yy_+yt_);
00369         case RigidBody :
00370         case Similarity :
00371         case Reflection :
00372         case Affine :
00373             return vgl_point_2d<double> (x*xx_+y*xy_+xt_,x*yx_+y*yy_+yt_);
00374         case Projective :
00375             z=x*tx_+y*ty_+tt_;
00376             if (z==0) return vgl_point_2d<double> (0,0);   // Or should it be inf,inf?
00377            else  return vgl_point_2d<double> ((x*xx_+y*xy_+xt_)/z,(x*yx_+y*yy_+yt_)/z);
00378         default:
00379             vcl_cerr<<"vimt_transform_2d::operator() : Unrecognised form:"<<int(form_)<<vcl_endl;
00380             vcl_abort();
00381     }
00382 
00383     return vgl_point_2d<double> (); // To keep over-zealous compilers happy
00384 }
00385 
00386 vgl_vector_2d<double>  vimt_transform_2d::delta(const vgl_point_2d<double>& p, const vgl_vector_2d<double>& dp) const
00387 {
00388     switch (form_)
00389     {
00390         case Identity :
00391         case Translation:
00392             return dp;
00393         case ZoomOnly :
00394             return vgl_vector_2d<double> (dp.x()*xx_,dp.y()*yy_);
00395         case RigidBody :
00396         case Similarity :
00397         case Reflection :
00398         case Affine :
00399             return vgl_vector_2d<double> (dp.x()*xx_+dp.y()*xy_,dp.x()*yx_+dp.y()*yy_);
00400         case Projective :
00401             return operator()(p+dp)-operator()(p);
00402         default:
00403             vcl_cerr<<"vimt_transform_2d::delta() : Unrecognised form:"<<int(form_)<<vcl_endl;
00404             vcl_abort();
00405     }
00406 
00407     return vgl_vector_2d<double> (); // To keep over-zealous compilers happy
00408 }
00409 
00410 
00411 vimt_transform_2d vimt_transform_2d::inverse() const
00412 {
00413     if (!inv_uptodate_) calcInverse();
00414 
00415     vimt_transform_2d inv;
00416 
00417     inv.xx_ = xx2_; inv.xy_ = xy2_; inv.xt_ = xt2_;
00418     inv.yx_ = yx2_; inv.yy_ = yy2_; inv.yt_ = yt2_;
00419     inv.tx_ = tx2_; inv.ty_ = ty2_; inv.tt_ = tt2_;
00420 
00421     inv.xx2_ = xx_; inv.xy2_ = xy_; inv.xt2_ = xt_;
00422     inv.yx2_ = yx_; inv.yy2_ = yy_; inv.yt2_ = yt_;
00423     inv.tx2_ = tx_; inv.ty2_ = ty_; inv.tt2_ = tt_;
00424 
00425     inv.form_ = form_;
00426     inv.inv_uptodate_ = 1;
00427 
00428     return inv;
00429 }
00430 
00431 void vimt_transform_2d::calcInverse()  const
00432 {
00433     xx2_ = yy2_ = tt2_ = 1;
00434     xy2_ = xt2_ = yx2_ = yt2_ = tx2_ = ty2_ = 0;
00435 
00436     switch (form_)
00437     {
00438         case Identity :
00439             break;
00440         case Translation :
00441             xt2_ = -xt_;
00442             yt2_ = -yt_;
00443             break;
00444         case ZoomOnly :
00445             assert(xx_ != 0 && yy_ != 0);
00446             xx2_=1.0/xx_;
00447             xt2_=-xt_/xx_;
00448             yy2_=1.0/yy_;
00449             yt2_=-yt_/yy_;
00450             break;
00451         case RigidBody :
00452             xx2_ = xx_; xy2_ = yx_;
00453             yx2_ = xy_; yy2_ = yy_;
00454             xt2_ = -(xx2_*xt_ + xy2_*yt_);
00455             yt2_ = -(yx2_*xt_ + yy2_*yt_);
00456             break;
00457         case Similarity :
00458         case Affine :
00459         {
00460             double det = xx_*yy_-xy_*yx_;
00461             if (det==0)
00462             {
00463               vcl_cerr<<"vimt_transform_2d::calcInverse() : No inverse exists for this affine transform (det==0)\n";
00464               vcl_abort();
00465             }
00466             xx2_=yy_/det;   xy2_=-xy_/det;
00467             yx2_=-yx_/det;   yy2_=xx_/det;
00468             xt2_=-xx2_*xt_-xy2_*yt_;
00469             yt2_=-yx2_*xt_-yy2_*yt_;
00470             break;
00471         }
00472         case Projective :
00473         {
00474             vnl_matrix<double> M(3,3),M_inv(3,3);
00475             matrix(M);
00476             M_inv = vnl_inverse(M);
00477             double **m_data=M_inv.data_array();
00478             xx2_=m_data[0][0];   xy2_=m_data[0][1]; xt2_=m_data[0][2];
00479             yx2_=m_data[1][0];   yy2_=m_data[1][1]; yt2_=m_data[1][2];
00480             tx2_=m_data[2][0];   ty2_=m_data[2][1]; tt2_=m_data[2][2];
00481             break;
00482         }
00483         default:
00484             vcl_cerr<<"vimt_transform_2d::calcInverse() : Unrecognised form:"<<int(form_)<<vcl_endl;
00485             vcl_abort();
00486     }
00487 
00488     inv_uptodate_=true;
00489 }
00490 
00491 bool vimt_transform_2d::operator==(const vimt_transform_2d& t) const
00492 {
00493     return
00494         xx_ == t.xx_ &&
00495         xy_ == t.xy_ &&
00496         xt_ == t.xt_ &&
00497         yx_ == t.yx_ &&
00498         yy_ == t.yy_ &&
00499         yt_ == t.yt_ &&
00500         tx_ == t.tx_ &&
00501         ty_ == t.ty_ &&
00502         tt_ == t.tt_;
00503 }
00504 
00505 //: Transform composition (L*R)(x) = L(R(x))
00506 vimt_transform_2d operator*(const vimt_transform_2d& L, const vimt_transform_2d& R)
00507 {
00508                 // Default is identity_
00509     vimt_transform_2d T;
00510 
00511     if (L.form() == vimt_transform_2d::Identity)
00512         return R;
00513     else
00514     if (R.form() == vimt_transform_2d::Identity)
00515         return L;
00516     else
00517     if (L.form() == vimt_transform_2d::Translation)
00518     {
00519         T = R;
00520 
00521         if (R.form() == vimt_transform_2d::Projective)
00522         {
00523             T.xx_ += L.xt_*R.tx_;
00524             T.xy_ += L.xt_*R.ty_;
00525             T.xt_ += L.xt_*R.tt_;
00526 
00527             T.yx_ += L.yt_*R.tx_;
00528             T.yy_ += L.yt_*R.ty_;
00529             T.yt_ += L.yt_*R.tt_;
00530         }
00531         else
00532         {
00533             T.xt_ += L.xt_;
00534             T.yt_ += L.yt_;
00535         }
00536     }
00537     else
00538     if (R.form() == vimt_transform_2d::Translation)
00539     {
00540         T = L;
00541 
00542         T.xt_ += L.xx_*R.xt_ +
00543                 L.xy_*R.yt_;
00544         T.yt_ += L.yx_*R.xt_ +
00545                 L.yy_*R.yt_;
00546         T.tt_ += L.tx_*R.xt_ +
00547                 L.ty_*R.yt_;
00548     }
00549     else
00550     {
00551         if (R.form() == vimt_transform_2d::Projective ||
00552             L.form() == vimt_transform_2d::Projective)
00553         {
00554                             // full monty_...
00555             T.xx_ = L.xx_*R.xx_ + L.xy_*R.yx_ + L.xt_*R.tx_;
00556             T.xy_ = L.xx_*R.xy_ + L.xy_*R.yy_ + L.xt_*R.ty_;
00557             T.xt_ = L.xx_*R.xt_ + L.xy_*R.yt_ + L.xt_*R.tt_;
00558             T.yx_ = L.yx_*R.xx_ + L.yy_*R.yx_ + L.yt_*R.tx_;
00559             T.yy_ = L.yx_*R.xy_ + L.yy_*R.yy_ + L.yt_*R.ty_;
00560             T.yt_ = L.yx_*R.xt_ + L.yy_*R.yt_ + L.yt_*R.tt_;
00561             T.tx_ = L.tx_*R.xx_ + L.ty_*R.yx_ + L.tt_*R.tx_;
00562             T.ty_ = L.tx_*R.xy_ + L.ty_*R.yy_ + L.tt_*R.ty_;
00563             T.tt_ = L.tx_*R.xt_ + L.ty_*R.yt_ + L.tt_*R.tt_;
00564         }
00565         else
00566         {
00567                             // Affine, Similarity, Reflection
00568                             // ZoomOnly, RigidBody
00569             T.xx_ = L.xx_*R.xx_ + L.xy_*R.yx_;
00570             T.xy_ = L.xx_*R.xy_ + L.xy_*R.yy_;
00571             T.xt_ = L.xx_*R.xt_ + L.xy_*R.yt_ + L.xt_;
00572             T.yx_ = L.yx_*R.xx_ + L.yy_*R.yx_;
00573             T.yy_ = L.yx_*R.xy_ + L.yy_*R.yy_;
00574             T.yt_ = L.yx_*R.xt_ + L.yy_*R.yt_ + L.yt_;
00575         }
00576 
00577                             // now set the type using the type of L and R
00578         if (R.form() == L.form())
00579             T.form_ = R.form();
00580         else
00581         {
00582             if (R.form() == vimt_transform_2d::Projective ||
00583                 L.form() == vimt_transform_2d::Projective)
00584                 T.form_ = vimt_transform_2d::Projective;
00585             else
00586             if (R.form() == vimt_transform_2d::Affine ||
00587                 L.form() == vimt_transform_2d::Affine)
00588                 T.form_ = vimt_transform_2d::Affine;
00589             else
00590             if (R.form() == vimt_transform_2d::Reflection ||
00591                 L.form() == vimt_transform_2d::Reflection)
00592                 T.form_ = vimt_transform_2d::Affine;
00593             else
00594             if (R.form() == vimt_transform_2d::Similarity ||
00595                 L.form() == vimt_transform_2d::Similarity)
00596                 T.form_ = vimt_transform_2d::Similarity;
00597             else
00598             if (R.form() == vimt_transform_2d::RigidBody ||
00599                 L.form() == vimt_transform_2d::RigidBody)
00600             {
00601                 if (R.form() == vimt_transform_2d::ZoomOnly)
00602                     if (R.xx_ == R.yy_)
00603                         T.form_ = vimt_transform_2d::Similarity;
00604                     else
00605                         T.form_ = vimt_transform_2d::Affine;
00606                 else
00607                 if (L.form() == vimt_transform_2d::ZoomOnly)
00608                     if (L.xx_ == L.yy_)
00609                         T.form_ = vimt_transform_2d::Similarity;
00610                     else
00611                         T.form_ = vimt_transform_2d::Affine;
00612                 else
00613                     T.form_ = vimt_transform_2d::RigidBody;
00614             }
00615             else
00616             if (R.form() == vimt_transform_2d::ZoomOnly ||
00617                 L.form() == vimt_transform_2d::ZoomOnly)
00618                 T.form_ = vimt_transform_2d::ZoomOnly;
00619             else
00620                 T.form_ = vimt_transform_2d::Translation;
00621         }
00622 
00623                 // make sure det == 1 for rigid body (prevents
00624                 // accumulated rounding errors)
00625         if (T.form_ == vimt_transform_2d::RigidBody)
00626         {
00627             double det = T.xx_*T.yy_ - T.xy_*T.yx_;
00628             T.xx_ /= det;
00629             T.xy_ /= det;
00630             T.yx_ /= det;
00631             T.yy_ /= det;
00632         }
00633     }
00634 
00635     T.inv_uptodate_ = false;
00636 
00637     return T;
00638 }
00639 
00640 void vimt_transform_2d::print_summary(vcl_ostream& o) const
00641 {
00642     o << vsl_indent()<< "Form: ";
00643     vsl_indent_inc(o);
00644     switch (form_)
00645     {
00646         case Identity:
00647             o << "Identity";
00648             break;
00649 
00650         case Translation:
00651             o << "Translation (" << xt_ << ',' << yt_ << ')';
00652             break;
00653 
00654         case ZoomOnly:
00655             o << "ZoomOnly\n"
00656               << vsl_indent()<< "scale factor = (" << xx_ << ',' << yy_ << ")\n"
00657               << vsl_indent()<< "translation = (" << xt_ << ',' << yt_ << ')';
00658             break;
00659 
00660         case RigidBody:
00661             o << "RigidBody\n"
00662               << vsl_indent()<< "angle = " << vcl_atan2(yx_,xx_) << '\n'
00663               << vsl_indent()<< "translation = (" << xt_ << ',' << yt_ << ')';
00664             break;
00665 
00666         case Similarity:
00667             o << "Similarity {"
00668               << " s= " << vcl_sqrt(xx_*xx_+xy_*xy_)
00669               << " A= " << vcl_atan2(xy_,xx_)
00670               << " t= (" << xt_ << ',' << yt_ << " ) }";
00671             break;
00672 
00673         case Reflection:
00674             o << "Reflection\n"
00675               << vsl_indent()<< xx_ << ' ' << xy_ << '\n'
00676               << vsl_indent()<< yx_ << ' ' << yy_ << '\n'
00677               << vsl_indent()<< "translation = (" << xt_ << ',' << yt_ << ')';
00678             break;
00679 
00680         case Affine:
00681             o << "Affine\n"
00682               << vsl_indent()<< xx_ << ' ' << xy_ << '\n'
00683               << vsl_indent()<< yx_ << ' ' << yy_ << '\n'
00684               << vsl_indent()<< "translation = (" << xt_ << ',' << yt_ << ')';
00685             break;
00686 
00687         case Projective:
00688             o << "Projective\n"
00689               << vsl_indent()<< xx_ << ' ' << xy_ << ' ' << xt_ << '\n'
00690               << vsl_indent()<< yx_ << ' ' << yy_ << ' ' << yt_ << '\n'
00691               << vsl_indent()<< tx_ << ' ' << ty_ << ' ' << tt_;
00692             break;
00693         default:
00694             assert(!"Invalid form");
00695     }
00696     vsl_indent_dec(o);
00697 }
00698 
00699 vcl_ostream& operator<<( vcl_ostream& os, const vimt_transform_2d& t )
00700 {
00701     os << "vimt_transform_2d:\n";
00702     vsl_indent_inc(os);
00703     t.print_summary(os);
00704     vsl_indent_dec(os);
00705     return os;
00706 }
00707 
00708 short vimt_transform_2d::version_no() const { return 1; }
00709 
00710 
00711 void vimt_transform_2d::b_write(vsl_b_ostream& bfs) const
00712 {
00713     vsl_b_write(bfs,version_no());
00714     vsl_b_write(bfs,int(form_));
00715     vsl_b_write(bfs,xx_); vsl_b_write(bfs,xy_); vsl_b_write(bfs,xt_);
00716     vsl_b_write(bfs,yx_); vsl_b_write(bfs,yy_); vsl_b_write(bfs,yt_);
00717     vsl_b_write(bfs,tx_); vsl_b_write(bfs,ty_); vsl_b_write(bfs,tt_);
00718 }
00719 
00720 void vimt_transform_2d::b_read(vsl_b_istream& bfs)
00721 {
00722     if (!bfs) return;
00723 
00724     short version;
00725     vsl_b_read(bfs,version);
00726     int f;
00727     switch (version) {
00728     case 1:
00729         vsl_b_read(bfs,f); form_=Form(f);
00730         vsl_b_read(bfs,xx_); vsl_b_read(bfs,xy_); vsl_b_read(bfs,xt_);
00731         vsl_b_read(bfs,yx_); vsl_b_read(bfs,yy_); vsl_b_read(bfs,yt_);
00732         vsl_b_read(bfs,tx_); vsl_b_read(bfs,ty_); vsl_b_read(bfs,tt_);
00733         break;
00734     default:
00735         vcl_cerr << "I/O ERROR: vimt_transform_2d::b_read(vsl_b_istream&)\n"
00736                  << "           Unknown version number "<< version << '\n';
00737         bfs.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00738         return;
00739     }
00740 
00741     inv_uptodate_ = false;
00742 }
00743 
00744 void vsl_b_read(vsl_b_istream& bfs,vimt_transform_2d& t)
00745 {
00746     t.b_read(bfs);
00747 }
00748 
00749 void vsl_b_write(vsl_b_ostream& bfs,const vimt_transform_2d& t)
00750 {
00751     t.b_write(bfs);
00752 }
00753 
00754 void vsl_print_summary(vcl_ostream& os,const vimt_transform_2d& t)
00755 {
00756   //os << t.is_a() << ": ";
00757   vsl_indent_inc(os);
00758   t.print_summary(os);
00759   vsl_indent_dec(os);
00760 }

Generated on Mon Mar 8 05:15:32 2010 for contrib/mul/vimt by  doxygen 1.5.1