transform.h

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2006 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 
00037 #ifndef eman__transform_h__
00038 #define eman__transform_h__ 1
00039 
00040 #ifdef _WIN32
00041         #pragma warning(disable:4819)
00042 #endif  //_WIN32
00043 
00044 #include "vec3.h"
00045 #include "emobject.h"
00046 #include <cstdio>
00047 
00048 // #include <vector>
00049 // using std::vector;
00050 //
00051 // #include <map>
00052 // using std::map;
00053 //
00054 // #include <string>
00055 // using std::string;
00056 
00057 
00058 
00059 namespace EMAN
00060 {
00084         class Transform {
00085 //              friend Transform EMAN::operator*(const Transform & M2, const Transform & M1);
00086                 public:
00087                         static const float ERR_LIMIT;
00088 
00092                         Transform();
00093 
00097                         Transform( const Transform& rhs );
00098 
00102                         Transform& operator=(const Transform& that);
00103 
00107                         Transform(const Dict& d);
00108 
00112                         Transform(const float array[12]);
00113 
00117                         Transform(const vector<float> array);
00118 
00119 
00120                         ~Transform() { }
00121 
00126                         void set_rotation( const Dict &rotation );
00127 
00133                         void set_rotation(const Vec3f & v);
00134 
00139                         Dict get_rotation(const string& euler_type = "eman") const;
00140 
00141 
00145                         Transform get_rotation_transform() const;
00146 
00150                         Transform get_hflip_transform() const;
00151 
00155                         Transform get_vflip_transform() const;
00156 
00162                         void set_params(const Dict& d);
00163 
00170                         void set_params_inverse(const Dict& d);
00171 
00176                         Dict get_params(const string& euler_type) const;
00177 
00182                         Dict get_params_inverse(const string& euler_type) const;
00183 
00184                         //=============== set and get post trans =============
00190                         void set_trans(const float& x, const float& y, const float& z=0);
00191 
00195                         inline void set_trans(const Vec3f& v) { set_trans(v[0],v[1],v[2]); }
00196 
00200                         inline void set_trans(const Vec2f& v) { set_trans(v[0],v[1]); }
00201 
00205                         Vec3f get_trans() const;
00206 
00210                         Vec2f get_trans_2d() const;
00211 
00212                         //================= get pre trans is supported =========
00213 
00218                         Vec3f get_pre_trans() const;
00219 
00224                         Vec2f get_pre_trans_2d() const;
00225 
00230                         template<typename type>
00231                         void set_pre_trans(const type& v);
00232 
00233                         //=============== set and get scale =============
00237                         void set_scale(const float& scale);
00238 
00242                         float get_scale() const;
00243 
00244                         //=============== set and get post x mirror =============
00248                         bool get_mirror() const;
00249 
00253                         void set_mirror(const bool x_mirror);
00254 
00255                         //=============== other stuff ============================
00261                         void get_scale_and_mirror(float& scale, bool& x_mirror) const;
00262 
00265                         void to_identity();
00266 
00269                         bool is_identity() const;
00270 
00277                         void orthogonalize();
00278 
00282                         float get_determinant() const;
00283 
00286                         void printme() const {
00287                                 cout << matrix[0][0] << " " << matrix[0][1] << " " << matrix[0][2] << " " << matrix[0][3] << endl;
00288                                 cout << matrix[1][0] << " " << matrix[1][1] << " " << matrix[1][2] << " " << matrix[1][3] << endl;
00289                                 cout << matrix[2][0] << " " << matrix[2][1] << " " << matrix[2][2] << " " << matrix[2][3] << endl;
00290                                 cout << 0 << " " << 0 << " " << 0 << " " << 1 << endl;
00291                         }
00292 
00293                         //=============== get set matrix ============================
00297                         void set_matrix(const vector<float>& v);
00298 
00302                         vector<float> get_matrix() const;
00303 
00307                         void invert();
00308 
00312                         Transform inverse() const;
00313 
00316                         void transpose_inplace();
00317 
00321                         Transform transpose() const;
00322 
00325                         inline float at(int r,int c) const { return matrix[r][c]; }
00326 
00329                         inline void set(int r, int c, float value) { matrix[r][c] = value; }
00330 
00334                         inline float * operator[] (int i) { return matrix[i]; }
00335 
00339                         inline const float * operator[] (int i) const { return matrix[i]; }
00340 
00346                         inline Vec2f transform(const float& x, const float& y) const {
00347 //                              assert_valid_2d();
00348                                 Vec2f ret;
00349                                 ret[0] = matrix[0][0]*x + matrix[0][1]*y + matrix[0][3];
00350                                 ret[1] = matrix[1][0]*x + matrix[1][1]*y + matrix[1][3];
00351                                 return ret;
00352                         }
00353 
00358                         template<typename Type>
00359                         inline Vec2f transform(const Vec2<Type>& v) const {
00360                                 return transform(v[0],v[1]);
00361                         }
00362 
00369                         inline Vec3f transform(const float& x, const float& y, const float& z) const {
00370 //                              assert_consistent_type(THREED);
00371                                 Vec3f ret;
00372                                 ret[0] = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z + matrix[0][3];
00373                                 ret[1] = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z + matrix[1][3];
00374                                 ret[2] = matrix[2][0] * x + matrix[2][1] * y + matrix[2][2] * z + matrix[2][3];
00375                                 return ret;
00376                         }
00377 
00382                         template<typename Type>
00383                         inline Vec3f transform(const Vec3<Type>& v) const {
00384 //                              assert_consistent_type(THREED); // Transform does the assertion
00385                                 return transform(v[0],v[1],v[2]);
00386                         }
00387 
00388 
00394                         inline Vec3f get_matrix3_row(int i) const {
00395                                 return Vec3f(matrix[i][0], matrix[i][1], matrix[i][2]);
00396                         }
00397 
00400                         static int get_nsym(const string & sym);
00401 
00406                         Transform get_sym(const string & sym, int n) const;
00407 
00410                         void copy_matrix_into_array(float* const) const;
00411 
00416                         Transform negate() const;
00417 
00421                         static Transform tet_3_to_2();
00422 
00426                         static Transform icos_5_to_2();
00427 
00428                 private:
00429                         float matrix[3][4];
00430 
00431                         void assert_valid_2d() const;
00432 
00434                         static vector<string> permissable_2d_not_rot;
00435                         static vector<string> permissable_3d_not_rot;
00436                         static map<string,vector<string> >  permissable_rot_keys;
00437 
00440                         void init_permissable_keys();
00441 
00449                         void detect_problem_keys(const Dict& d);
00450 
00451         };
00453         Transform operator*(const Transform & M2, const Transform & M1);
00454 
00456         template<typename Type>
00457         Vec3f operator*( const Transform& M, const Vec3<Type> & v)
00458         {
00459                 return M.transform(v);
00460         }
00461 
00463         template<typename Type>
00464         Vec2f operator*( const Transform& M, const Vec2<Type> & v)
00465         {
00466                 return M.transform(v);
00467         }
00468 
00472         template<typename Type>
00473         Vec3f operator*(const Vec3<Type> & v, const Transform & M)
00474         {
00475                 float x = v[0] * M[0][0] + v[1] * M[1][0] + v[2] * M[2][0] ;
00476                 float y = v[0] * M[0][1] + v[1] * M[1][1] + v[2] * M[2][1];
00477                 float z = v[0] * M[0][2] + v[1] * M[1][2] + v[2] * M[2][2];
00478                 return Vec3f(x, y, z);
00479         }
00480 
00481         template<typename type>
00482         void Transform::set_pre_trans(const type& v) {
00483 
00484                 Transform tmp;
00485                 Dict rot = get_rotation("eman");
00486                 tmp.set_rotation(rot);
00487 
00488                 float scale = get_scale();
00489                 if (scale != 1.0 ) tmp.set_scale(scale);
00490 
00491                 Transform trans;
00492                 trans.set_trans(v);
00493 
00494                 trans = tmp*trans;
00495 
00496                 Transform tmp2;
00497                 tmp2.set_rotation(rot);
00498                 tmp2.invert(); // invert
00499                 if (scale != 1.0 ) tmp2.set_scale(1.0f/scale);
00500 
00501 
00502                 trans = trans*tmp2;
00503 
00504                 set_trans(trans.get_trans());
00505         }
00506 
00550         class Transform3D
00551         {
00552         public:
00553                 static const float ERR_LIMIT;
00554                 enum EulerType
00555                 {
00556                         UNKNOWN,
00557                         EMAN,
00558                         IMAGIC,
00559                         SPIN,
00560                         QUATERNION,
00561                         SGIROT,
00562                         SPIDER,
00563                         MRC,
00564                         XYZ,
00565                         MATRIX
00566                 };
00567 
00571                 Transform3D();
00572 
00576             Transform3D( const Transform3D& rhs );
00577 
00583                 Transform3D(const float& az,const float& alt,const float& phi); // EMAN by default
00584 
00592                 Transform3D(const float& az, const float& alt, const float& phi, const Vec3f& posttrans);
00593 
00602                 Transform3D(const Vec3f & pretrans, const float& az,const float& alt,const float& phi, const Vec3f& posttrans);
00603 
00611                 Transform3D(EulerType euler_type, const float& a1, const float& a2, const float& a3) ;
00612 
00621                 Transform3D(EulerType euler_type, const float& a1, const float& a2, const float& a3, const float& a4) ; // o
00622 
00628                 Transform3D(EulerType euler_type, const Dict& rotation);
00629 
00634                 Transform3D(const float& m11, const float& m12, const float& m13,
00635                                         const float& m21, const float& m22, const float& m23,
00636                                         const float& m31, const float& m32, const float& m33);
00637 
00640                 ~Transform3D();
00641 
00644                 void apply_scale(const float& scale);
00645 
00648                 void set_scale(const float& scale);
00649 
00652                 void orthogonalize();
00653 
00656                 void transpose();
00657 
00658                 void set_rotation(const float& az, const float& alt,const float& phi);
00659 
00667                 void set_rotation(EulerType euler_type,const float& a1,const float& a2,const float& a3);
00668 
00677                 void set_rotation(EulerType euler_type,const float& a1,const float& a2,const float& a3, const float& a4);
00678 
00682                 void set_rotation(const float& m11, const float& m12, const float& m13,
00683                                                   const float& m21, const float& m22, const float& m23,
00684                                                   const float& m31, const float& m32, const float& m33);
00685 
00686 //              void set_params(const Dict& params, const string& parameter_convention, const EulerType euler_type = EMAN);
00687 //
00688 //              Dict get_params(const string& parameter_convention, const EulerType euler_type = EMAN) const;
00689 
00695                 void set_rotation(EulerType euler_type, const Dict &rotation );
00696 
00701                 Dict get_rotation(EulerType euler_type=EMAN) const;
00702 
00707                 void set_rotation(const Vec3f & eahat, const Vec3f & ebhat,
00708                                                     const Vec3f & eAhat, const Vec3f & eBhat);
00711                 float get_mag() const;
00712 
00715                 Vec3f get_finger() const;
00716 
00721                 Vec3f get_pretrans( int flag=0) const; // flag=1 => all trans is pre
00722 
00728                 Vec3f get_posttrans(int flag=0) const; // flag=1 => all trans is post
00729 
00733                 Vec3f get_total_posttrans() const;
00734 
00738                 Vec3f get_total_pretrans() const;
00739 
00742                 Vec3f get_center() const; // This doesn't do anything
00743 
00748                 Vec3f get_matrix3_col(int i) const;
00749 
00754                 Vec3f get_matrix3_row(int i) const;
00755 
00760                 Vec3f transform(const Vec3f & v3f) const;
00761 
00766                 Vec3f rotate(const Vec3f & v3f) const;
00767 
00770                 Transform3D inverseUsingAngs() const;
00771 
00774                 Transform3D inverse() const;
00775 
00776 
00779                 void printme() const {
00780                         for (int i=0; i<3; i++) {
00781                                 printf("%6.15f\t%6.15f\t%6.15f\t%6.1f\n",
00782                                            matrix[i][0],matrix[i][1],matrix[i][2],matrix[i][3]);
00783                         }
00784                         printf("%6.3f\t%6.3f\t%6.3f\t%6.3f\n",0.0,0.0,0.0,1.0);
00785                         printf("\n");
00786                 }
00787 
00790                 inline float at(int r,int c) const { return matrix[r][c]; }
00791 
00794                 void set(int r, int c, float value) { matrix[r][c] = value; }
00795 
00799                 inline float * operator[] (int i) { return matrix[i]; }
00800 
00804                 inline const float * operator[] (int i) const { return matrix[i]; }
00805 
00806                 static int get_nsym(const string & sym);
00807                 Transform3D get_sym(const string & sym, int n) const;
00808 
00811                 void set_center(const Vec3f & center);
00812                 void set_pretrans(const Vec3f & pretrans);
00813                 void set_pretrans(const float& dx, const float& dy, const float& dz);
00814                 void set_pretrans(const float& dx, const float& dy);
00815                 void set_pretrans(const Vec2f& pretrans);
00816                 void set_posttrans(const Vec3f & posttrans);
00817                 void set_posttrans(const float& dx, const float& dy, const float& dz);
00818                 void set_posttrans(const float& dx, const float& dy);
00819                 void set_posttrans(const Vec2f& posttrans);
00820 
00821                 void set_post_x_mirror(const bool b) { post_x_mirror = b; }
00822                 bool get_post_x_mirror() const { return post_x_mirror; }
00823 
00824                 float get_scale() const;
00825 
00826                 void to_identity();
00827         bool is_identity();
00828 
00836                 static vector<Transform3D*>
00837                         angles2tfvec(EulerType eulertype, const vector<float> angles);
00838 
00841                 void dsaw_zero_hack(){
00842                         for (int j=0; j<4; ++j) {
00843                                 for (int i=0; i<4; i++) {
00844                                 if ( fabs(matrix[j][i]) < 0.000001 )
00845                                         matrix[j][i] = 0.0;
00846                                 }
00847                         }
00848 
00849                 }
00850 
00851         protected:
00852                 enum SymType
00853                 {      CSYM,
00854                         DSYM,
00855                         TET_SYM,
00856                         ICOS_SYM,
00857                         OCT_SYM,
00858                         ISYM,
00859                         UNKNOWN_SYM
00860                 };
00861 
00862                 void init();
00863 
00864                 static SymType get_sym_type(const string & symname);
00865 
00866                 float matrix[4][4];
00867 
00868                 bool post_x_mirror;
00869 
00870                 Transform3D::EulerType s;
00871         }; // ends Class
00872 
00873         Transform3D operator*(const Transform3D & M1, const Transform3D & M2);
00874 //      Vec3f operator*(const Vec3f & v    , const Transform3D & M);
00875 //      Vec3f operator*(const Transform3D & M, const Vec3f & v    );
00876 
00877         template<typename Type>
00878         Vec3f operator*(const Vec3<Type> & v, const Transform3D & M)   // YYY
00879         {
00880 //               This is the right multiplication of a row vector, v by a transform3D matrix M
00881                 float x = v[0] * M[0][0] + v[1] * M[1][0] + v[2] * M[2][0] ;
00882                 float y = v[0] * M[0][1] + v[1] * M[1][1] + v[2] * M[2][1];
00883                 float z = v[0] * M[0][2] + v[1] * M[1][2] + v[2] * M[2][2];
00884                 return Vec3f(x, y, z);
00885         }
00886 
00887         template<typename Type>
00888         Vec3f operator*( const Transform3D & M, const Vec3<Type> & v)      // YYY
00889         {
00890 //      This is the  left multiplication of a vector, v by a matrix M
00891                 float x = M[0][0] * v[0] + M[0][1] * v[1] + M[0][2] * v[2] + M[0][3];
00892                 float y = M[1][0] * v[0] + M[1][1] * v[1] + M[1][2] * v[2] + M[1][3];
00893                 float z = M[2][0] * v[0] + M[2][1] * v[1] + M[2][2] * v[2] + M[2][3];
00894                 return Vec3f(x, y, z);
00895         }
00896 
00897 
00898         template<typename Type>
00899         Vec2f operator*( const Transform3D & M, const Vec2<Type> & v)      // YYY
00900         {
00901 //      This is the  left multiplication of a vector, v by a matrix M
00902                 float x = M[0][0] * v[0] + M[0][1] * v[1] + M[0][3] ;
00903                 float y = M[1][0] * v[0] + M[1][1] * v[1] + M[1][3];
00904                 return Vec2f(x, y);
00905         }
00906 
00907 }  // ends NameSpace EMAN
00908 
00909 
00910 
00911 #endif
00912 
00913 
00914 /* vim: set ts=4 noet: */

Generated on Mon Jul 19 12:40:14 2010 for EMAN2 by  doxygen 1.4.7