00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "vimt_transform_2d.h"
00009 #include <vcl_cmath.h>
00010 #include <vcl_cstdlib.h>
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_);
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
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
00220
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
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
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)
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
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)
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);
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> ();
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> ();
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
00506 vimt_transform_2d operator*(const vimt_transform_2d& L, const vimt_transform_2d& R)
00507 {
00508
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
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
00568
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
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
00624
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);
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
00757 vsl_indent_inc(os);
00758 t.print_summary(os);
00759 vsl_indent_dec(os);
00760 }