Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vimt_transform_2d.h

Go to the documentation of this file.
00001 // This is mul/vimt/vimt_transform_2d.h
00002 #ifndef vimt_transform_2d_h_
00003 #define vimt_transform_2d_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \author Tim Cootes
00010 // \brief 2D transform, which can be up to a projective transformation
00011 
00012 #include <vnl/vnl_fwd.h>
00013 #include <vgl/vgl_vector_2d.h>
00014 #include <vgl/vgl_point_2d.h>
00015 #include <vsl/vsl_binary_io.h>
00016 
00017 //: 2D transform, which can be up to a projective transformation.
00018 // In order of complexity the transform can be
00019 // \verbatim
00020 // Identity     x->x, y->y
00021 // Translation  x->x + tx, y->y + ty
00022 // ZoomOnly     x->sx.x + tx, y->sy.y + ty
00023 // RigidBody    (Translate + rotation)
00024 // Euclidean    (Translation + rotation + scale)
00025 // Affine
00026 // Projective
00027 // \endverbatim
00028 //
00029 // NOTES:
00030 // The transformation can be represented by a 3x3 matrix mapping homogeneous co-ordinates about.
00031 // \verbatim
00032 // ( xx xy xt )
00033 // ( yx yy yt )
00034 // ( tx ty tt )
00035 // \endverbatim
00036 // For efficiency the elements are stored explicitly, rather than in a vnl_matrix<double>, to avoid lots
00037 // of copying of matrices with all the attendant memory allocation.
00038 //
00039 //
00040 //  Example:
00041 // \code
00042 // vimt_transform_2d T1;
00043 // vimt_transform_2d T2;
00044 // T1.set_zoom(scale,translation.x(),translation.y());
00045 // T2.set_similarity(scale2,theta,translation2.x(),translation2.y());
00046 //
00047 // vimt_transform_2d T3 = T2 * T1; // T1 followed by T2
00048 //
00049 // vgl_point_2d<double>  p(10,10);
00050 // vgl_point_2d<double>  p_new = T3(p);
00051 //
00052 // vimt_transform_2d T_inverse = T3.inverse();
00053 // \endcode
00054 class vimt_transform_2d
00055 {
00056  public:
00057     //: Defines form of transformation
00058     enum Form { Identity,
00059                 Translation,
00060                 ZoomOnly,
00061                 RigidBody,
00062                 Similarity,
00063                 Affine,
00064                 Projective,
00065                 Reflection};
00066 
00067     vimt_transform_2d() :
00068         xx_(1),xy_(0),xt_(0),
00069         yx_(0),yy_(1),yt_(0),
00070         tx_(0),ty_(0),tt_(1),
00071         form_(Identity),inv_uptodate_(0) {};
00072 
00073 
00074     bool is_identity() const { return form_==Identity; };
00075     Form form() const { return form_; };
00076     vnl_matrix<double> matrix() const;
00077     void matrix(vnl_matrix<double>&) const;
00078 
00079     //: Fills v with parameters
00080     void params(vnl_vector<double>& v) const;
00081     //: Sets transform using v (converse of params(v))
00082     void set(const vnl_vector<double>& v, Form); // Sets transform using v
00083     //: Set to identity transformation
00084     void set_identity();
00085     //: Sets the transformation to be separable affine.
00086     // x' = s_x.x + t_x,  y' = s_y.y + t_y
00087     // s_x: Scaling in x
00088     // s_y: Scaling in y
00089     // t_x: Translation in x
00090     // t_y: Translation in y
00091     void set_zoom_only(double s_x, double s_y, double t_x, double t_y);
00092     //: Sets the transformation to be a zoom.
00093     // x' = s.x + t_x,  y' = s.y + t_y
00094     //   s: Scaling
00095     // t_x: Translation in x
00096     // t_y: Translation in y
00097     void set_zoom_only(double s, double t_x, double t_y) { set_zoom_only(s,s,t_x,t_y);};
00098     //: Sets the transformation to be a translation.
00099     // t_x: Translation in x
00100     // t_y: Translation in y
00101     void set_translation(double t_x, double t_y);
00102     //: Sets the transformation to rotation then translation.
00103     // theta: rotation
00104     // t_x: Translation in x
00105     // t_y: Translation in y
00106     void set_rigid_body(double theta, double t_x, double t_y);
00107     //: Sets the transformation to apply scaling, rotation then translation.
00108     // s: Scaling
00109     // theta: rotation
00110     // t_x: Translation in x
00111     // t_y: Translation in y
00112     void set_similarity(double s, double theta, double t_x, double t_y);
00113 
00114     //: Sets Euclidean transformation.
00115     // \param dx  Rotation and scaling of x axis
00116     // \param t  Translation
00117     void set_similarity(const vgl_point_2d<double> & dx, const vgl_point_2d<double> & t);
00118 
00119     //: reflect about a line though the points m1, and m2
00120     void set_reflection( const vgl_point_2d<double> & m1, const vgl_point_2d<double> & m2);
00121 
00122     //: Sets to be 2D affine transformation using 2x3 matrix
00123     void set_affine(const vnl_matrix<double>&);
00124 
00125     //: Sets to be 2D affine transformation T(x,y)=p+x.u+y.v
00126     void set_affine(const vgl_point_2d<double> & p,
00127                     const vgl_vector_2d<double> & u,
00128                     const vgl_vector_2d<double> & v);
00129 
00130     //: Sets to be 2D projective transformation
00131     void set_projective(const vnl_matrix<double>&);   // 3x3 matrix
00132 
00133     //: Returns the coordinates of the origin.
00134     // I.e. operator()(vgl_point_2d<double> (0,0))
00135     vgl_point_2d<double>  origin() const
00136         { return vgl_point_2d<double> (tt_==1?xt_:xt_/tt_,tt_==1?yt_:yt_/tt_); }
00137     //: Modifies the transformation so that operator()(vgl_point_2d<double> (0,0)) == p.
00138     // The rest of the transformation is unaffected.
00139     // If the transformation was previously the identity,
00140     // it becomes a translation.
00141     void set_origin( const vgl_point_2d<double> & );
00142 
00143     //: Applies transformation to (x,y)
00144     vgl_point_2d<double>  operator()(double x, double y) const;
00145     //: Returns transformation applied to point p
00146     vgl_point_2d<double>  operator()(const vgl_point_2d<double> & p) const { return operator()(p.x(),p.y()); }
00147 
00148     //: Calculates inverse of this transformation
00149     vimt_transform_2d inverse() const;
00150     //: Returns change in transformed point when original point moved by dp.
00151     // Point dp: Movement from point
00152     // Returns: T(p+dp)-T(p)
00153     vgl_vector_2d<double>  delta(const vgl_point_2d<double> & p, const vgl_vector_2d<double> & dp) const;
00154 
00155     friend vimt_transform_2d operator*(const vimt_transform_2d&,
00156                                        const vimt_transform_2d&);
00157 
00158     short version_no() const;
00159     void print_summary(vcl_ostream&) const;
00160     void b_write(vsl_b_ostream& bfs) const;
00161     void b_read(vsl_b_istream& bfs);
00162 
00163     //: True if t is the same as this
00164     bool operator==(const vimt_transform_2d& t) const;
00165 
00166  private:
00167 
00168     double xx_,xy_,xt_,yx_,yy_,yt_,tx_,ty_,tt_;
00169     Form form_;
00170 
00171     // Notice the mutable here - take care if using threads!
00172     mutable double xx2_,xy2_,xt2_,yx2_,yy2_,yt2_,tx2_,ty2_,tt2_; // Inverse
00173     mutable bool inv_uptodate_;
00174 
00175     void calcInverse() const;
00176     void setCheck(int n1,int n2,const char* str) const;
00177 };
00178 
00179 
00180 vcl_ostream& operator<<(vcl_ostream&,const vimt_transform_2d& t);
00181 
00182 //: Binary file stream output operator for pointer to class
00183 void vsl_b_write(vsl_b_ostream& bfs, const vimt_transform_2d& b);
00184 
00185 //: Binary file stream input operator for class reference
00186 void vsl_b_read(vsl_b_istream& bfs, vimt_transform_2d& b);
00187 
00188 //: Stream output operator for class reference
00189 void vsl_print_summary(vcl_ostream& os,const vimt_transform_2d& t);
00190 
00191 
00192 #endif // vimt_transform_2d_h_

Generated on Thu Jan 10 14:43:58 2008 for contrib/mul/vimt by  doxygen 1.4.4