#include <transform.h>
Public Member Functions | |
Transform () | |
Default constructor Internal matrix is the identity. | |
Transform (const Transform &rhs) | |
Copy constructor. | |
Transform & | operator= (const Transform &that) |
Assignment operator. | |
bool | operator== (const Transform &rhs) const |
Equality comparision operator. | |
bool | operator!= (const Transform &rhs) const |
Unequality comparision operator. | |
Transform (const Dict &d) | |
Construction using a dictionary. | |
Transform (const float array[12]) | |
Construction using an array of floats. | |
Transform (const vector< float > array) | |
Construction using a vector of size 12. | |
~Transform () | |
void | set_rotation (const Dict &rotation) |
Set a rotation using a specific Euler type and the dictionary interface Works for all Euler types. | |
void | set_rotation (const Vec3f &v) |
Determine the rotation that would transform a vector pointing in the Z direction so that it points in the direction of the argument vector Automatically normalizes the vector. | |
void | rotate_origin (const Transform &by) |
Increment the rotation by multipling the rotation bit of the argument transfrom by the rotation part of the current transfrom. | |
void | rotate_origin_newBasis (const Transform &tcs, const float &omega, const float &n1, const float &n2, const float &n3) |
Increment the rotation by multipling the rotation bit of the argument transfrom by the rotation part of the current transfrom This version rotates in the standard coordinate system, even after it have been modified by tcs. | |
void | rotate (const Transform &by) |
Increment the rotation by multipling the rotation bit of the argument transfrom by the current transfrom. | |
Dict | get_rotation (const string &euler_type="eman") const |
Get a rotation in any Euler format. | |
Transform | get_rotation_transform () const |
Get the rotation part of the tranformation matrix as a Transform object. | |
Transform | get_hflip_transform () const |
How do I get the transform that will yield the horizontally flipped projection? | |
Transform | get_vflip_transform () const |
How do I get the transform that will yield the vertically flipped projection? | |
void | set_params (const Dict &d) |
Set the parameters of the entire transform. | |
void | set_params_inverse (const Dict &d) |
Set the parameters of the entire transform as though they there in the inverse format. | |
Dict | get_params (const string &euler_type) const |
Get the parameters of the entire transform, using a specific euler convention. | |
Dict | get_params_inverse (const string &euler_type) const |
Get the parameters of the inverse of the transform as though it were in RSMT order not MTSR. | |
void | set_trans (const float &x, const float &y, const float &z=0) |
Set the post translation component. | |
void | set_trans (const Vec3f &v) |
Set the post translation component using a Vec3f. | |
void | set_trans (const Vec2f &v) |
Set the post translation component using a Vec2f. | |
Vec3f | get_trans () const |
Get the post trans as a vec3f. | |
void | translate (const float &tx, const float &ty, const float &tz=0) |
Increment the current translation by tx, ty, tz. | |
void | translate (const Vec3f &v) |
Increment the current translation using vec3f& v. | |
void | translate (const Vec2f &v) |
Increment the current translation using vec2f& v. | |
void | translate_newBasis (const Transform &tcs, const float &tx, const float &ty, const float &tz=0) |
Increment the current translation by tx, ty, tz using a non standard basis Actualy what it does is remove the effect of tcs when a composite transfrom tcs*t (where t is the current transform) This function is used in the scenegraph. | |
void | translate (const Transform &tcs, const Vec3f &v) |
Increment the current translation using vec3f& v and a non standard basis. | |
Vec2f | get_trans_2d () const |
Get the degenerant 2D post trans as a vec2f. | |
Vec3f | get_pre_trans () const |
Get the translation vector as though this object was MSRT_ not MTSR, where T_ is what you want Note M means post x mirror, T means translation, S means scale, and R means rotaiton. | |
Vec2f | get_pre_trans_2d () const |
2D version of getting the translation vector as though this object was MSRT_ not MTSR, where T_ is what you want Note M means post x mirror, T means translation, S means scale, and R means rotation | |
template<typename type> | |
void | set_pre_trans (const type &v) |
Set the translational component of the matrix as though it was MSRT_ not MTSR, where T_ is the pre translation. | |
void | set_scale (const float &scale) |
Set the scale. | |
float | get_scale () const |
Get the scale that was applied. | |
void | scale (const float &scale) |
Increment the scale. | |
bool | get_mirror () const |
Query whether x_mirroring is occuring. | |
void | set_mirror (const bool x_mirror) |
Set whether or not x_mirroring is occuring. | |
void | get_scale_and_mirror (float &scale, bool &x_mirror) const |
Get scale and x_mirror with 1 function call. | |
void | to_identity () |
Force the internal matrix to become the identity. | |
bool | is_identity () const |
Returns whethers or this matrix is the identity. | |
bool | is_rot_identity () const |
Returns whethers or this matrix rotation is the identity. | |
void | orthogonalize () |
Reorthogonalize the rotation part of the matrix in place. | |
float | get_determinant () const |
Get the determinant of the matrix. | |
void | printme () const |
Print the contents of the internal matrix verbatim to standard out. | |
void | set_matrix (const vector< float > &v) |
Set the transformation matrix using a vector. | |
vector< float > | get_matrix () const |
Get the transformation matrix using a vector. | |
vector< float > | get_matrix_4x4 () const |
Get the 4x4 transformation matrix using a vector. | |
void | invert () |
Get the inverse of this transformation matrix. | |
Transform | inverse () const |
Get the inverse of this transformation matrix. | |
void | transpose_inplace () |
Get the transpose of this transformation matrix. | |
Transform | transpose () const |
Get the transpose of this transformation matrix. | |
float | at (int r, int c) const |
Get the value stored in the internal transformation matrix at at coordinate (r,c). | |
void | set (int r, int c, float value) |
Set the value stored in the internal transformation matrix at at coordinate (r,c) to value. | |
float * | operator[] (int i) |
Operator[] convenience so Transform3D[2][2] etc terminology can be used. | |
const float * | operator[] (int i) const |
Operator[] convenience so Transform3D[2][2] etc terminology can be used. | |
Vec2f | transform (const float &x, const float &y) const |
Transform 2D coordinates using the internal transformation matrix. | |
template<typename Type> | |
Vec2f | transform (const Vec2< Type > &v) const |
Transform a 2D vector using the internal transformation matrix. | |
Vec3f | transform (const float &x, const float &y, const float &z) const |
Transform 3D coordinates using the internal transformation matrix. | |
template<typename Type> | |
Vec3f | transform (const Vec3< Type > &v) const |
Transform a 3D vector using the internal transformation matrix. | |
Vec3f | get_matrix3_row (int i) const |
Get a matrix row as a Vec3f required for back compatibility with Tranform3D - see PawelProjector. | |
Transform | get_sym (const string &sym, int n) const |
Apply the symmetry deduced from the function arguments to this Transform and return the result. | |
vector< Transform > | get_sym_proj (const string &sym) const |
void | copy_matrix_into_array (float *const) const |
Transform | negate () const |
Negates the Transform - a useful way, for example, for getting an orientation on the opposite side of the sphere. | |
Static Public Member Functions | |
static int | get_nsym (const string &sym) |
get the number of symmetries associated with the given symmetry name | |
static Transform | tet_3_to_2 () |
Get the transform that moves any tetrahedron generated by eman2 so that it matches the 2-2-2 (MRC, FREALIGN) convention. | |
static Transform | icos_5_to_2 () |
Get the transform that moves any icosahedron generated by eman2 so that it matches the 2-2-2 (MRC, FREALIGN) convention. | |
Static Public Attributes | |
static const float | ERR_LIMIT = 0.000001f |
Private Member Functions | |
void | assert_valid_2d () const |
void | init_permissable_keys () |
Called internally to initialize permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys static members. | |
void | detect_problem_keys (const Dict &d) |
Test to ensure the parametes in the given dictionary are valid Throws if an error is detected Generic - works in every circumstance (set_params, set_rotation, set_params_inv) Uses static members permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys as basis of decision. | |
Private Attributes | |
float | matrix [3][4] |
Static Private Attributes | |
static vector< string > | permissable_2d_not_rot |
This map is used to validate keys in the argument maps - e.g. if the type is 2d and the angle is not "alpha" then we should throw. | |
static vector< string > | permissable_3d_not_rot |
static map< string, vector< string > > | permissable_rot_keys |
It's designed to store four transformations in a specific order, namely Transform = MTSR Where M is a mirroring operation (about the x-axis) or the identity T is a Translation matrix S is a uniform scaling matrix R is a rotation matrix This means you can call set_scale, set_trans, set_rotation in any order but still have the operations arranged internally in the order of MTSR. This is somewhat restrictive, for example in the context of how OpenGL handles transformations, but in practice is nicely suited to the situations that arise in EMAN2 - namely, alignment and projection orientation characterization.
Note that you can fool the Transform object into storing any matrix by using the constructors that take array arguments. This can useful, for example, for shearing your image.
See http://blake.bcm.tmc.edu/emanwiki/Eman2TransformInPython for using it from Python and detailed discussion See test_transform.py for examples of the way it is unit tested See http://blake.bcm.tmc.edu/emanwiki/EMAN2/Tutorials/RotateTranslate for examples showing how to transform EMDatas with it.
Definition at line 83 of file transform.h.
Transform::Transform | ( | ) |
Default constructor Internal matrix is the identity.
Definition at line 104 of file transform.cpp.
References to_identity().
Referenced by rotate_origin_newBasis(), set_params_inverse(), and translate_newBasis().
00105 { 00106 to_identity(); 00107 }
Transform::Transform | ( | const Transform & | rhs | ) |
Copy constructor.
rhs | the object to be copied |
Definition at line 109 of file transform.cpp.
Transform::Transform | ( | const Dict & | d | ) |
Construction using a dictionary.
d | the dictionary containing the parameters |
Definition at line 135 of file transform.cpp.
References set_params(), and to_identity().
00135 { 00136 to_identity(); 00137 set_params(d); 00138 }
Transform::Transform | ( | const float | array[12] | ) |
Construction using an array of floats.
array | the array of values that will become the internal matrix. row order (3 rows of 4) |
Definition at line 141 of file transform.cpp.
References matrix.
00141 { 00142 memcpy(matrix,array,12*sizeof(float)); 00143 }
Transform::Transform | ( | const vector< float > | array | ) |
Construction using a vector of size 12.
array | the array of values that will become the internal matrix. row order (3 rows of 4) |
Definition at line 145 of file transform.cpp.
References set_matrix().
00146 { 00147 set_matrix(array); 00148 }
EMAN::Transform::~Transform | ( | ) | [inline] |
void Transform::assert_valid_2d | ( | ) | const [private] |
Definition at line 1319 of file transform.cpp.
References ERR_LIMIT, matrix, and UnexpectedBehaviorException.
Referenced by get_rotation(), and set_rotation().
01319 { 01320 int rotation_error = 0; 01321 int translation_error = 0; 01322 if (fabs(matrix[2][0]) > ERR_LIMIT) rotation_error++; 01323 if (fabs(matrix[2][1]) > ERR_LIMIT) rotation_error++; 01324 if (fabs(matrix[2][3]) > ERR_LIMIT) translation_error++; 01325 if (fabs(matrix[0][2]) > ERR_LIMIT) rotation_error++; 01326 if (fabs(matrix[1][2]) > ERR_LIMIT) rotation_error++; 01327 // if (fabs(matrix[2][2]-1.0) >ERR_LIMIT) rotation_error++; 01328 if ( translation_error && rotation_error ) { 01329 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and 3D translations. This object can not be considered 2D"); 01330 } else if ( translation_error ) { 01331 throw UnexpectedBehaviorException("Error, the internal matrix contains a non zero z component for a 3D translation. This object can not be considered 2D"); 01332 } 01333 else if ( rotation_error ) { 01334 throw UnexpectedBehaviorException("Error, the internal matrix contains 3D rotations and this object can not be considered 2D"); 01335 } 01336 01337 }
float EMAN::Transform::at | ( | int | r, | |
int | c | |||
) | const [inline] |
Get the value stored in the internal transformation matrix at at coordinate (r,c).
Definition at line 401 of file transform.h.
References matrix.
Referenced by EMAN::PawelProjector::backproject3d().
00401 { return matrix[r][c]; }
void Transform::copy_matrix_into_array | ( | float * | const | ) | const |
Definition at line 161 of file transform.cpp.
References matrix.
Referenced by EMAN::FourierReconstructor::do_compare_slice_work(), EMAN::FourierReconstructor::do_insert_slice_work(), EMAN::TransformProcessor::process(), EMAN::TransformProcessor::process_inplace(), and EMAN::StandardProjector::project3d().
00161 { 00162 00163 int idx = 0; 00164 for(int i=0; i<3; ++i) { 00165 for(int j=0; j<4; ++j) { 00166 array[idx] = matrix[i][j]; 00167 idx ++; 00168 } 00169 } 00170 }
void Transform::detect_problem_keys | ( | const Dict & | d | ) | [private] |
Test to ensure the parametes in the given dictionary are valid Throws if an error is detected Generic - works in every circumstance (set_params, set_rotation, set_params_inv) Uses static members permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys as basis of decision.
d | the dictionary that was the function argument of the set_params, set_rotation or the set_params_inv function |
InvalidParameterException | if the dictionary is invalid in anyway |
Definition at line 361 of file transform.cpp.
References EMAN::Dict::begin(), copy(), EMAN::Dict::end(), EMAN::Dict::has_key_ci(), init_permissable_keys(), InvalidParameterException, permissable_2d_not_rot, permissable_3d_not_rot, permissable_rot_keys, and EMAN::Util::str_to_lower().
Referenced by set_params(), set_params_inverse(), and set_rotation().
00361 { 00362 if (permissable_rot_keys.size() == 0 ) { 00363 init_permissable_keys(); 00364 } 00365 00366 vector<string> verification; 00367 vector<string> problem_keys; 00368 bool is_2d = false; 00369 if (d.has_key_ci("type") ) { 00370 string type = Util::str_to_lower((string)d["type"]); 00371 bool problem = false; 00372 if (permissable_rot_keys.find(type) == permissable_rot_keys.end() ) { 00373 problem_keys.push_back(type); 00374 problem = true; 00375 } 00376 if ( !problem ) { 00377 vector<string> perm = permissable_rot_keys[type]; 00378 std::copy(perm.begin(),perm.end(),back_inserter(verification)); 00379 00380 if ( type == "2d" ) { 00381 is_2d = true; 00382 std::copy(permissable_2d_not_rot.begin(),permissable_2d_not_rot.end(),back_inserter(verification)); 00383 } 00384 } 00385 } 00386 if ( !is_2d ) { 00387 std::copy(permissable_3d_not_rot.begin(),permissable_3d_not_rot.end(),back_inserter(verification)); 00388 } 00389 00390 for (Dict::const_iterator it = d.begin(); it != d.end(); ++it) { 00391 if ( std::find(verification.begin(),verification.end(), it->first) == verification.end() ) { 00392 problem_keys.push_back(it->first); 00393 } 00394 } 00395 00396 if (problem_keys.size() != 0 ) { 00397 string error; 00398 if (problem_keys.size() == 1) { 00399 error = "Transform Error: The \"" +problem_keys[0]+ "\" key is unsupported"; 00400 } else { 00401 error = "Transform Error: The "; 00402 for(vector<string>::const_iterator cit = problem_keys.begin(); cit != problem_keys.end(); ++cit ) { 00403 if ( cit != problem_keys.begin() ) { 00404 if (cit == (problem_keys.end() -1) ) error += " and "; 00405 else error += ", "; 00406 } 00407 error += "\""; 00408 error += *cit; 00409 error += "\""; 00410 } 00411 error += " keys are unsupported"; 00412 } 00413 throw InvalidParameterException(error); 00414 } 00415 }
float Transform::get_determinant | ( | ) | const |
Get the determinant of the matrix.
Definition at line 1232 of file transform.cpp.
References EMAN::Util::apply_precision(), ERR_LIMIT, and matrix.
Referenced by get_mirror(), get_scale(), get_scale_and_mirror(), and scale().
01233 { 01234 float det; 01235 double det2; 01236 det2 = matrix[0][0]*((double)matrix[1][1]*matrix[2][2]-(double)matrix[2][1]*matrix[1][2]); 01237 det2 -= matrix[0][1]*((double)matrix[1][0]*matrix[2][2]-(double)matrix[2][0]*matrix[1][2]); 01238 det2 += matrix[0][2]*((double)matrix[1][0]*matrix[2][1]-(double)matrix[2][0]*matrix[1][1]); 01239 01240 det = (float)det2; 01241 Util::apply_precision(det,ERR_LIMIT); 01242 01243 return det; 01244 }
Transform Transform::get_hflip_transform | ( | ) | const |
How do I get the transform that will yield the horizontally flipped projection?
Definition at line 778 of file transform.cpp.
References get_rotation(), and get_trans().
00778 { 00779 00780 Dict rot = get_rotation("eman"); 00781 rot["alt"] = 180.0f + static_cast<float>(rot["alt"]); 00782 rot["phi"] = 180.0f - static_cast<float>(rot["phi"]); 00783 // This is the same as new_alt= 180-alt, new_phi=-phi, new_az=180+az 00784 00785 Transform ret(*this); // Is the identity 00786 ret.set_rotation(rot); 00787 00788 Vec3f trans = get_trans(); 00789 trans[0] = -trans[0]; 00790 ret.set_trans(trans); 00791 00792 // ret.set_mirror(self.get_mirror()); 00793 00794 return ret; 00795 }
vector< float > Transform::get_matrix | ( | ) | const |
Get the transformation matrix using a vector.
Definition at line 172 of file transform.cpp.
References matrix.
Referenced by EMAN::Util::BPCQ(), EMAN::EMData::extract_box(), rotate(), and rotate_origin().
00173 { 00174 vector<float> ret(12); 00175 for(int i=0; i<3; ++i) { 00176 for(int j=0; j<4; ++j) { 00177 ret[i*4+j] = matrix[i][j]; 00178 } 00179 } 00180 return ret; 00181 }
Vec3f EMAN::Transform::get_matrix3_row | ( | int | i | ) | const [inline] |
Get a matrix row as a Vec3f required for back compatibility with Tranform3D - see PawelProjector.
i | the row number (starting at 0) |
Definition at line 470 of file transform.h.
References matrix.
Referenced by EMAN::PawelProjector::project3d().
vector< float > Transform::get_matrix_4x4 | ( | ) | const |
Get the 4x4 transformation matrix using a vector.
Definition at line 183 of file transform.cpp.
References matrix.
00184 { 00185 vector<float> ret(16); 00186 for(int i=0; i<3; ++i) { 00187 for(int j=0; j<4; ++j) { 00188 ret[i*4+j] = matrix[i][j]; 00189 } 00190 } 00191 ret[12] = 0.0; 00192 ret[13] = 0.0; 00193 ret[14] = 0.0; 00194 ret[15] = 1.0; 00195 00196 return ret; 00197 }
bool Transform::get_mirror | ( | ) | const |
Query whether x_mirroring is occuring.
Definition at line 1203 of file transform.cpp.
References get_determinant().
Referenced by get_params(), get_params_inverse(), get_trans(), get_trans_2d(), EMAN::BackProjectionReconstructor::preprocess_slice(), EMAN::GaussFFTProjector::project3d(), set_mirror(), set_trans(), and translate().
01203 { 01204 float determinant = get_determinant(); 01205 01206 bool x_mirror = false; 01207 if ( determinant < 0 ) x_mirror = true; 01208 01209 return x_mirror; 01210 01211 }
int Transform::get_nsym | ( | const string & | sym | ) | [static] |
get the number of symmetries associated with the given symmetry name
Definition at line 1469 of file transform.cpp.
References EMAN::Symmetry3D::get_nsym().
Referenced by EMAN::PointArray::set_from(), EMAN::nnSSNR_ctfReconstructor::setup(), EMAN::nn4_ctf_rectReconstructor::setup(), EMAN::nn4_ctfReconstructor::setup(), EMAN::nnSSNR_Reconstructor::setup(), EMAN::nn4_rectReconstructor::setup(), EMAN::nn4Reconstructor::setup(), and EMAN::EMData::symvol().
01470 { 01471 Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name); 01472 int nsym = sym->get_nsym(); 01473 delete sym; 01474 return nsym; 01475 }
Dict Transform::get_params | ( | const string & | euler_type | ) | const |
Get the parameters of the entire transform, using a specific euler convention.
euler_type | the euler type of the retrieved rotation |
Definition at line 471 of file transform.cpp.
References get_mirror(), get_rotation(), get_scale(), get_trans(), scale(), EMAN::Util::str_to_lower(), and v.
Referenced by EMAN::Util::BPCQ(), compose_transform2(), and EMAN::Util::get_transform_params().
00471 { 00472 Dict params = get_rotation(euler_type); 00473 00474 Vec3f v = get_trans(); 00475 params["tx"] = v[0]; params["ty"] = v[1]; 00476 00477 string type = Util::str_to_lower(euler_type); 00478 if ( type != "2d") params["tz"] = v[2]; 00479 00480 float scale = get_scale(); 00481 params["scale"] = scale; 00482 00483 bool mirror = get_mirror(); 00484 params["mirror"] = mirror; 00485 00486 return params; 00487 }
Dict Transform::get_params_inverse | ( | const string & | euler_type | ) | const |
Get the parameters of the inverse of the transform as though it were in RSMT order not MTSR.
euler_type | the euler type of the retrieved rotation |
Definition at line 491 of file transform.cpp.
References get_mirror(), get_pre_trans(), get_rotation(), get_scale(), inverse(), scale(), EMAN::Util::str_to_lower(), and v.
00491 { 00492 Transform inv(inverse()); 00493 00494 Dict params = inv.get_rotation(euler_type); 00495 Vec3f v = inv.get_pre_trans(); 00496 params["tx"] = v[0]; params["ty"] = v[1]; 00497 00498 string type = Util::str_to_lower(euler_type); 00499 if ( type != "2d") params["tz"] = v[2]; 00500 00501 float scale = inv.get_scale(); 00502 params["scale"] = scale; 00503 00504 bool mirror = inv.get_mirror(); 00505 params["mirror"] = mirror; 00506 00507 return params; 00508 }
Vec3f Transform::get_pre_trans | ( | ) | const |
Get the translation vector as though this object was MSRT_ not MTSR, where T_ is what you want Note M means post x mirror, T means translation, S means scale, and R means rotaiton.
Definition at line 1053 of file transform.cpp.
References get_trans(), invert(), and set_trans().
Referenced by get_params_inverse().
01054 { 01055 Transform T(*this); 01056 T.set_trans(0,0,0); 01057 T.invert(); 01058 01059 Transform soln = T*(*this); 01060 // soln.printme(); 01061 return soln.get_trans(); 01062 }
Vec2f Transform::get_pre_trans_2d | ( | ) | const |
2D version of getting the translation vector as though this object was MSRT_ not MTSR, where T_ is what you want Note M means post x mirror, T means translation, S means scale, and R means rotation
Definition at line 1064 of file transform.cpp.
References get_trans_2d(), invert(), and set_trans().
01065 { 01066 Transform T(*this); 01067 T.set_trans(0,0,0); 01068 T.invert(); 01069 01070 Transform soln = T*(*this); 01071 // soln.printme(); 01072 return soln.get_trans_2d(); 01073 }
Dict Transform::get_rotation | ( | const string & | euler_type = "eman" |
) | const |
Get a rotation in any Euler format.
euler_type | the requested Euler type |
Definition at line 815 of file transform.cpp.
References assert_valid_2d(), EMAN::EMConsts::deg2rad, get_scale_and_mirror(), InvalidStringException, matrix, phi, EMAN::EMConsts::rad2deg, scale(), sqrt(), EMAN::Util::str_to_lower(), and UnexpectedBehaviorException.
Referenced by EMAN::RotateTranslateAligner::align(), EMAN::RotationalAligner::align(), EMAN::PawelProjector::backproject3d(), EMAN::ChaoProjector::backproject3d(), get_hflip_transform(), get_params(), get_params_inverse(), get_sym_proj(), get_vflip_transform(), EMAN::FourierReconstructorSimple2D::insert_slice(), EMAN::ChaoProjector::project3d(), EMAN::FourierGriddingProjector::project3d(), and set_pre_trans().
00816 { 00817 Dict result; 00818 00819 //float max = 1 - ERR_LIMIT; 00820 float scale; 00821 bool x_mirror; 00822 get_scale_and_mirror(scale,x_mirror); 00823 if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected."); 00824 00825 double cosalt = matrix[2][2]/scale; 00826 double x_mirror_scale = (x_mirror ? -1.0f : 1.0f); 00827 double inv_scale = 1.0f/scale; 00828 00829 double az = 0; 00830 double alt = 0; 00831 double phi = 0; 00832 double phiS = 0; // like az (but in SPIDER ZYZ) 00833 double psiS = 0; // like phi (but in SPIDER ZYZ) 00834 00835 // get alt, az, phi in EMAN convention 00836 00837 if (cosalt >= 1) { // that is, alt close to 0 00838 alt = 0; 00839 az = 0; 00840 phi = (double)EMConsts::rad2deg * atan2(x_mirror_scale*matrix[0][1], x_mirror_scale*matrix[0][0]); 00841 } else if (cosalt <= -1) { // that is, alt close to 180 00842 alt = 180; 00843 az = 0; 00844 phi = (double)EMConsts::rad2deg * atan2(-x_mirror_scale*matrix[0][1], x_mirror_scale*matrix[0][0]); 00845 } else { // for non exceptional cases: 0 < alt < 180 00846 00847 az = (double)EMConsts::rad2deg * atan2(scale*matrix[2][0], -scale*matrix[2][1]); 00848 00849 if (matrix[2][2]==0.0) 00850 alt = 90.0; 00851 else 00852 alt = (double)EMConsts::rad2deg * atan(sqrt((double)matrix[2][0]*matrix[2][0]+(double)matrix[2][1]*matrix[2][1])/fabs(matrix[2][2])); 00853 00854 if (matrix[2][2] * scale < 0) 00855 alt = 180.0f-alt; 00856 00857 phi = (double)EMConsts::rad2deg * atan2(x_mirror_scale*(double)matrix[0][2], (double)matrix[1][2]); 00858 00859 } // ends separate cases: alt close to 0, 180, or neither 00860 00861 phi = phi-360.0*floor(phi/360.0); 00862 az = az -360.0*floor(az/360.0); 00863 00864 // get phiS, psiS (SPIDER) 00865 if (cosalt >= 1) { // that is, alt close to 0 00866 phiS = 0; 00867 psiS = phi; 00868 } else if (cosalt <= -1) { // that is, alt close to 180 00869 phiS = 0; 00870 psiS = phi + 180.0; 00871 } else { 00872 phiS = az - 90.0; 00873 psiS = phi + 90.0; 00874 } 00875 00876 phiS = phiS-360.0*floor(phiS/360.0); 00877 psiS = psiS-360.0*floor(psiS/360.0); 00878 00879 // do some quaternionic stuff here 00880 double xtilt = 0; 00881 double ytilt = 0; 00882 double ztilt = 0; 00883 00884 00885 string type = Util::str_to_lower(euler_type); 00886 00887 result["type"] = type; 00888 if (type == "2d") { 00889 assert_valid_2d(); 00890 result["alpha"] = phi; 00891 } else if (type == "eman") { 00892 // assert_consistent_type(THREED); 00893 result["az"] = az; 00894 result["alt"] = alt; 00895 result["phi"] = phi; 00896 } else if (type == "imagic") { 00897 // assert_consistent_type(THREED); 00898 result["alpha"] = az; 00899 result["beta"] = alt; 00900 result["gamma"] = phi; 00901 } else if (type == "spider") { 00902 // assert_consistent_type(THREED); 00903 result["phi"] = phiS; // The first Euler like az 00904 result["theta"] = alt; 00905 result["psi"] = psiS; 00906 } else if (type == "mrc") { 00907 // assert_consistent_type(THREED); 00908 result["phi"] = phiS; 00909 result["theta"] = alt; 00910 result["omega"] = psiS; 00911 } else if (type == "xyz") { // need to double-check these 3 equations ******** 00912 // assert_consistent_type(THREED); 00913 xtilt = atan2(-sin(EMConsts::deg2rad*phiS)*sin(EMConsts::deg2rad*alt),cos(EMConsts::deg2rad*alt)); 00914 ytilt = asin( cos(EMConsts::deg2rad*phiS)*sin(EMConsts::deg2rad*alt)); 00915 ztilt = psiS*EMConsts::deg2rad - atan2(sin(xtilt), cos(xtilt) *sin(ytilt)); 00916 00917 xtilt *= EMConsts::rad2deg; ytilt *= EMConsts::rad2deg; ztilt *= EMConsts::rad2deg; 00918 xtilt = xtilt-360*.0*floor((xtilt+180.0)/360.0); 00919 ytilt = ytilt-360*.0*floor((ytilt+180.0)/360.0); //already in range [-90,90] but anyway... 00920 ztilt = ztilt-360*.0*floor((ztilt+180.0)/360.0); 00921 00922 result["xtilt"] = xtilt; 00923 result["ytilt"] = ytilt; 00924 result["ztilt"] = ztilt; 00925 } else if ((type == "quaternion") || (type == "spin") || (type == "sgirot")) { 00926 00927 // The cosOover2 is also e0 00928 // double nphi = (az-phi)/2.0; 00929 // double cosOover2 = cos((az+phi)*EMConsts::deg2rad/2.0) * cos(alt*EMConsts::deg2rad/2.0); 00930 // printf("%f %f %f",matrix[0][0],matrix[1][1],matrix[2][2]); 00931 double traceR = matrix[0][0]+matrix[1][1]+matrix[2][2]; // This should be 1 + 2 cos omega 00932 double cosomega = (traceR-1.0)/2.0; 00933 if (cosomega>1.0) cosomega=1.0; 00934 if (cosomega<-1.0) cosomega=-1.0; 00935 00936 // matrix(x,y)-matrix(y,x) = 2 n_z sin(omega) etc 00937 // trace matrix = 1 + 2 cos(omega) 00938 double sinOover2= sqrt((1.0 -cosomega)/2.0); 00939 double cosOover2= sqrt(1.0 -sinOover2*sinOover2); 00940 double sinomega = 2* sinOover2*cosOover2; 00941 double n1 = 0; double n2 = 0; double n3 = 0; 00942 if (sinomega>0) { 00943 n1 = (matrix[1][2]-matrix[2][1])/2.0/sinomega ; 00944 n2 = (matrix[2][0]-matrix[0][2])/2.0/sinomega ; 00945 n3 = (matrix[0][1]-matrix[1][0])/2.0/sinomega ; 00946 } 00947 // printf("traceR=%lf,OneMinusCosomega=%lf,sinOover2=%lf,cosOover2=%lf,sinomega=%lf,cosomega=%lf,n3=%lf \n",traceR,1-cosomega,sinOover2,cosOover2,sinomega,cosomega,n3); 00948 00949 00950 if (type == "quaternion"){ 00951 result["e0"] = cosOover2 ; 00952 result["e1"] = sinOover2 * n1 ; 00953 result["e2"] = sinOover2 * n2; 00954 result["e3"] = sinOover2 * n3; 00955 } 00956 00957 if (type == "spin"){ 00958 result["omega"] = EMConsts::rad2deg * acos(cosomega); 00959 result["n1"] = n1; 00960 result["n2"] = n2; 00961 result["n3"] = n3; 00962 } 00963 00964 if (type == "sgirot"){ 00965 result["q"] = EMConsts::rad2deg * acos(cosomega); 00966 result["n1"] = n1; 00967 result["n2"] = n2; 00968 result["n3"] = n3; 00969 } 00970 00971 } else if (type == "matrix") { 00972 // assert_consistent_type(THREED); 00973 result["m11"] = x_mirror_scale*matrix[0][0]*inv_scale; 00974 result["m12"] = x_mirror_scale*matrix[0][1]*inv_scale; 00975 result["m13"] = x_mirror_scale*matrix[0][2]*inv_scale; 00976 result["m21"] = matrix[1][0]*inv_scale; 00977 result["m22"] = matrix[1][1]*inv_scale; 00978 result["m23"] = matrix[1][2]*inv_scale; 00979 result["m31"] = matrix[2][0]*inv_scale; 00980 result["m32"] = matrix[2][1]*inv_scale; 00981 result["m33"] = matrix[2][2]*inv_scale; 00982 } else { 00983 throw InvalidStringException(euler_type, "unknown Euler Type"); 00984 } 00985 00986 return result; 00987 }
Transform Transform::get_rotation_transform | ( | ) | const |
Get the rotation part of the tranformation matrix as a Transform object.
Definition at line 674 of file transform.cpp.
References set_mirror(), set_scale(), and set_trans().
Referenced by EMAN::GaussFFTProjector::project3d().
00675 { 00676 Transform ret(*this); 00677 ret.set_scale(1.0); 00678 ret.set_mirror(false); 00679 ret.set_trans(0,0,0); 00680 //ret.orthogonalize(); // ? 00681 return ret; 00682 }
float Transform::get_scale | ( | ) | const |
Get the scale that was applied.
Definition at line 1098 of file transform.cpp.
References EMAN::Util::apply_precision(), ERR_LIMIT, get_determinant(), and scale().
Referenced by get_params(), get_params_inverse(), EMAN::BackProjectionReconstructor::preprocess_slice(), EMAN::GaussFFTProjector::project3d(), set_pre_trans(), and set_scale().
01098 { 01099 float determinant = get_determinant(); 01100 if (determinant < 0 ) determinant *= -1; 01101 01102 float scale = std::pow(determinant,1.0f/3.0f); 01103 int int_scale = static_cast<int>(scale); 01104 float scale_residual = scale-static_cast<float>(int_scale); 01105 if ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); }; 01106 01107 Util::apply_precision(scale, ERR_LIMIT); 01108 01109 return scale; 01110 }
void Transform::get_scale_and_mirror | ( | float & | scale, | |
bool & | x_mirror | |||
) | const |
Get scale and x_mirror with 1 function call.
More efficient than calling get_scale and get_x_mirror separately
scale | a reference to the value that will be assigned the scale value | |
x_mirror | a reference to the value that will be assigned the x_mirror value |
Definition at line 1213 of file transform.cpp.
References EMAN::Util::apply_precision(), ERR_LIMIT, and get_determinant().
Referenced by get_rotation(), orthogonalize(), and set_rotation().
01213 { 01214 01215 float determinant = get_determinant(); 01216 x_mirror = false; 01217 if ( determinant < 0 ) { 01218 x_mirror = true; 01219 determinant *= -1; 01220 } 01221 if (determinant != 1 ) { 01222 scale = std::pow(determinant,1.0f/3.0f); 01223 int int_scale = static_cast<int>(scale); 01224 float scale_residual = scale-static_cast<float>(int_scale); 01225 if ( scale_residual < ERR_LIMIT ) { scale = static_cast<float>(int_scale); }; 01226 } 01227 else scale = 1; 01228 01229 Util::apply_precision(scale,ERR_LIMIT); 01230 }
Transform Transform::get_sym | ( | const string & | sym, | |
int | n | |||
) | const |
Apply the symmetry deduced from the function arguments to this Transform and return the result.
Definition at line 1341 of file transform.cpp.
References EMAN::Symmetry3D::get_sym().
Referenced by EMAN::PointArray::set_from(), and EMAN::EMData::symvol().
01342 { 01343 Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name); 01344 Transform ret; 01345 ret = (*this) * sym->get_sym(n); 01346 delete sym; 01347 return ret; 01348 }
vector< Transform > Transform::get_sym_proj | ( | const string & | sym | ) | const |
Definition at line 1350 of file transform.cpp.
References EMAN::EMConsts::deg2rad, EMAN::Symmetry3D::get_nsym(), get_rotation(), EMAN::Symmetry3D::get_sym(), matrix, and t.
01351 { 01352 vector<Transform> ret; 01353 Transform t; 01354 Symmetry3D* sym = Factory<Symmetry3D>::get(sym_name); 01355 int nsym = sym->get_nsym(); 01356 int n = nsym; 01357 01358 if ((sym_name[0] == 'c' || sym_name[0] == 'd' ) && fabs(matrix[2][2]) < 1.e-6){ 01359 01360 Dict d1,d2; 01361 d2["theta"] = (double)90.0; 01362 d2["psi"] = (double)0.0; 01363 d2["phi"] = (double)0.0; 01364 d2["type"] = "spider"; 01365 d1 = this->get_rotation("spider"); 01366 01367 if (sym_name[0] == 'c') { 01368 if( nsym%2 == 0) n = nsym/2; 01369 01370 for (int k=0;k<n;k++) { 01371 d2["phi"] = (double)d1["phi"] + k*double(360.0)/ nsym; 01372 d2["psi"] = d1["psi"]; 01373 t.set_rotation(d2); 01374 ret.push_back( t ); 01375 } 01376 01377 } 01378 else { 01379 nsym = nsym/2; 01380 01381 if (nsym%2 == 0) { 01382 n = nsym; 01383 float cos_phi = cos( EMConsts::deg2rad*360.0/2/nsym ); 01384 01385 for (int k=0;k<n;k++){ 01386 01387 if(k%2==0) { 01388 01389 d2["phi"] = (double)d1["phi"] + k/2*double(360.0)/ nsym; 01390 d2["psi"] = d1["psi"]; 01391 t.set_rotation(d2); 01392 ret.push_back( t ); 01393 } 01394 else { 01395 01396 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6 ){ 01397 //cout<<"jumped into"<<endl; 01398 d2["phi"] = k/2*double(360.0)/ nsym +180 - (double)d1["phi"]; 01399 d2["psi"] = (double)d1["psi"] + 180; 01400 t.set_rotation(d2); 01401 ret.push_back( t ); 01402 } 01403 } 01404 01405 } 01406 } 01407 01408 01409 01410 else { 01411 n = nsym*2; 01412 float cos_phi = cos( EMConsts::deg2rad*360.0/4/nsym ); 01413 for (int k=0;k<n;k++){ 01414 01415 if(k%4==0) { 01416 01417 d2["phi"] = (double)d1["phi"] + k/4*360.0/ nsym; 01418 d2["psi"] = (double)d1["psi"]; 01419 t.set_rotation(d2); 01420 ret.push_back( t ); 01421 } 01422 else if( k%4 ==1) { 01423 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6 ){ 01424 01425 d2["phi"] = k/4*360.0/nsym + 360.0/2/nsym+180 - (double)d1["phi"]; 01426 d2["psi"] = (double)d1["psi"] + 180; 01427 t.set_rotation(d2); 01428 ret.push_back( t ); 01429 } 01430 01431 } 01432 01433 else if( k%4 ==2) { 01434 01435 d2["phi"] = k/4*360.0/ nsym+360.0/2/nsym+180 + (double)d1["phi"]; 01436 d2["psi"] = (double)d1["psi"]; 01437 t.set_rotation(d2); 01438 ret.push_back( t ); 01439 01440 } 01441 01442 else if( k%4 ==3) { 01443 if( ( fabs(1.0-matrix[2][0])>1.0e-6 )&& fabs( matrix[2][0]-cos_phi)>1.0e-6 ) { 01444 d2["phi"] = k/4*360.0/nsym+ 2.0*360.0/2/nsym - (double)d1["phi"]; 01445 d2["psi"] = (double)d1["psi"] + 180; 01446 t.set_rotation(d2); 01447 ret.push_back( t ); 01448 } 01449 } 01450 01451 } 01452 } 01453 01454 } 01455 01456 } 01457 else { 01458 for (int k=0;k<nsym;k++) { 01459 t = sym->get_sym(k); 01460 ret.push_back( (*this) * t ); 01461 } 01462 01463 } 01464 delete sym; 01465 return ret; 01466 }
Vec3f Transform::get_trans | ( | ) | const |
Get the post trans as a vec3f.
Definition at line 999 of file transform.cpp.
References EMAN::Util::apply_precision(), ERR_LIMIT, get_mirror(), matrix, and v.
Referenced by get_hflip_transform(), get_params(), get_pre_trans(), get_vflip_transform(), EMAN::GaussFFTProjector::project3d(), rotate_origin_newBasis(), set_params_inverse(), and translate_newBasis().
01000 { 01001 // No type asserted 01002 bool x_mirror = get_mirror(); 01003 Vec3f v; 01004 if (x_mirror) v[0] = -matrix[0][3]; 01005 else v[0] = matrix[0][3]; 01006 v[1] = matrix[1][3]; 01007 v[2] = matrix[2][3]; 01008 01009 Util::apply_precision(v[0],ERR_LIMIT); 01010 Util::apply_precision(v[1],ERR_LIMIT); 01011 Util::apply_precision(v[2],ERR_LIMIT); 01012 01013 return v; 01014 }
Vec2f Transform::get_trans_2d | ( | ) | const |
Get the degenerant 2D post trans as a vec2f.
Definition at line 1041 of file transform.cpp.
References get_mirror(), matrix, and v.
Referenced by get_pre_trans_2d(), and EMAN::BackProjectionReconstructor::preprocess_slice().
01042 { 01043 bool x_mirror = get_mirror(); 01044 Vec2f v; 01045 if (x_mirror) v[0] = -matrix[0][3]; 01046 else v[0] = matrix[0][3]; 01047 v[1] = matrix[1][3]; 01048 return v; 01049 }
Transform Transform::get_vflip_transform | ( | ) | const |
How do I get the transform that will yield the vertically flipped projection?
Definition at line 797 of file transform.cpp.
References get_rotation(), and get_trans().
00797 { 00798 00799 Dict rot = get_rotation("eman"); 00800 rot["alt"] = 180.0f + static_cast<float>(rot["alt"]); 00801 rot["phi"] = - static_cast<float>(rot["phi"]); 00802 00803 // This is the same as new_alt= 180-alt, new_phi=180-phi, new_az=180+az 00804 00805 Transform ret(*this); 00806 ret.set_rotation(rot); 00807 00808 Vec3f trans = get_trans(); 00809 trans[1] = -trans[1]; 00810 ret.set_trans(trans); 00811 00812 return ret; 00813 }
Transform Transform::icos_5_to_2 | ( | ) | [static] |
Get the transform that moves any icosahedron generated by eman2 so that it matches the 2-2-2 (MRC, FREALIGN) convention.
Doctor Steve says Phil's answer put the 2-fold in the wrong place based on the standard Virus convention (empirically). It was also 2 to 5 not 5 to 2. It is possible to rotate to a 2-fold directly from a 5-fold, though there are 2 possible orientations for the 2-2-2 convention, and this finds only one of them :^(
Doctor Phil says: alt = (acos(cos(pi/5)/sqrt(3)/sin(pi/5)) + acos(2*cos(pi/5)/ sqrt(3) ) )*180/pi This is the angle between a 5 and a 3 plus the angle between a 3 and a 2
Definition at line 67 of file transform.cpp.
References t.
00067 { 00068 Transform t; 00069 Dict d; 00070 d["type"] = "eman"; 00071 d["phi"] = 0; 00072 d["az"] = 90.0f; 00073 d["alt"] = 31.717474; // 5 fold to the nearest 2-fold 00085 t.set_rotation(d); 00086 return t; 00087 }
void Transform::init_permissable_keys | ( | ) | [private] |
Called internally to initialize permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys static members.
Definition at line 276 of file transform.cpp.
References permissable_2d_not_rot, permissable_3d_not_rot, and permissable_rot_keys.
Referenced by detect_problem_keys().
00277 { 00278 00279 permissable_2d_not_rot.push_back("tx"); 00280 permissable_2d_not_rot.push_back("ty"); 00281 permissable_2d_not_rot.push_back("scale"); 00282 permissable_2d_not_rot.push_back("mirror"); 00283 permissable_2d_not_rot.push_back("type"); 00284 00285 permissable_3d_not_rot.push_back("tx"); 00286 permissable_3d_not_rot.push_back("ty"); 00287 permissable_3d_not_rot.push_back("tz"); 00288 permissable_3d_not_rot.push_back("scale"); 00289 permissable_3d_not_rot.push_back("mirror"); 00290 permissable_3d_not_rot.push_back("type"); 00291 00292 vector<string> tmp; 00293 tmp.push_back("alpha"); 00294 permissable_rot_keys["2d"] = tmp; 00295 00296 tmp.clear(); 00297 tmp.push_back("alt"); 00298 tmp.push_back("az"); 00299 tmp.push_back("phi"); 00300 permissable_rot_keys["eman"] = tmp; 00301 00302 tmp.clear(); 00303 tmp.push_back("psi"); 00304 tmp.push_back("theta"); 00305 tmp.push_back("phi"); 00306 permissable_rot_keys["spider"] = tmp; 00307 00308 tmp.clear(); 00309 tmp.push_back("alpha"); 00310 tmp.push_back("beta"); 00311 tmp.push_back("gamma"); 00312 permissable_rot_keys["imagic"] = tmp; 00313 00314 tmp.clear(); 00315 tmp.push_back("ztilt"); 00316 tmp.push_back("xtilt"); 00317 tmp.push_back("ytilt"); 00318 permissable_rot_keys["xyz"] = tmp; 00319 00320 tmp.clear(); 00321 tmp.push_back("phi"); 00322 tmp.push_back("theta"); 00323 tmp.push_back("omega"); 00324 permissable_rot_keys["mrc"] = tmp; 00325 00326 tmp.clear(); 00327 tmp.push_back("e0"); 00328 tmp.push_back("e1"); 00329 tmp.push_back("e2"); 00330 tmp.push_back("e3"); 00331 permissable_rot_keys["quaternion"] = tmp; 00332 00333 tmp.clear(); 00334 tmp.push_back("n1"); 00335 tmp.push_back("n2"); 00336 tmp.push_back("n3"); 00337 tmp.push_back("omega"); 00338 permissable_rot_keys["spin"] = tmp; 00339 00340 tmp.clear(); 00341 tmp.push_back("n1"); 00342 tmp.push_back("n2"); 00343 tmp.push_back("n3"); 00344 tmp.push_back("q"); 00345 permissable_rot_keys["sgirot"] = tmp; 00346 00347 tmp.clear(); 00348 tmp.push_back("m11"); 00349 tmp.push_back("m12"); 00350 tmp.push_back("m13"); 00351 tmp.push_back("m21"); 00352 tmp.push_back("m22"); 00353 tmp.push_back("m23"); 00354 tmp.push_back("m31"); 00355 tmp.push_back("m32"); 00356 tmp.push_back("m33"); 00357 permissable_rot_keys["matrix"] = tmp; 00358 }
Transform Transform::inverse | ( | ) | const |
Get the inverse of this transformation matrix.
Definition at line 1280 of file transform.cpp.
References t.
Referenced by get_params_inverse(), EMAN::EMData::max_3D_pixel_error(), EMAN::RotateInFSProcessor::process_inplace(), EMAN::MaxValProjector::project3d(), and EMAN::StandardProjector::project3d().
void Transform::invert | ( | ) |
Get the inverse of this transformation matrix.
Definition at line 1246 of file transform.cpp.
Referenced by get_pre_trans(), get_pre_trans_2d(), EMAN::Symmetry3D::in_which_asym_unit(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::GaussFFTProjector::project3d(), EMAN::Symmetry3D::reduce(), rotate_origin_newBasis(), set_params_inverse(), set_pre_trans(), and translate_newBasis().
01246 { 01247 01248 double m00 = matrix[0][0]; double m01=matrix[0][1]; double m02=matrix[0][2]; 01249 double m10 = matrix[1][0]; double m11=matrix[1][1]; double m12=matrix[1][2]; 01250 double m20 = matrix[2][0]; double m21=matrix[2][1]; double m22=matrix[2][2]; 01251 double v0 = matrix[0][3]; double v1 =matrix[1][3]; double v2 =matrix[2][3]; 01252 01253 double cof00 = m11*m22-m12*m21; 01254 double cof11 = m22*m00-m20*m02; 01255 double cof22 = m00*m11-m01*m10; 01256 double cof01 = m10*m22-m20*m12; 01257 double cof02 = m10*m21-m20*m11; 01258 double cof12 = m00*m21-m01*m20; 01259 double cof10 = m01*m22-m02*m21; 01260 double cof20 = m01*m12-m02*m11; 01261 double cof21 = m00*m12-m10*m02; 01262 01263 double det = m00* cof00 + m02* cof02 -m01*cof01; 01264 01265 matrix[0][0] = (float)(cof00/det); 01266 matrix[0][1] = - (float)(cof10/det); 01267 matrix[0][2] = (float)(cof20/det); 01268 matrix[1][0] = - (float)(cof01/det); 01269 matrix[1][1] = (float)(cof11/det); 01270 matrix[1][2] = - (float)(cof21/det); 01271 matrix[2][0] = (float)(cof02/det); 01272 matrix[2][1] = - (float)(cof12/det); 01273 matrix[2][2] = (float)(cof22/det); 01274 01275 matrix[0][3] = (float)((- cof00*v0 + cof10*v1 - cof20*v2)/det); 01276 matrix[1][3] = (float)(( cof01*v0 - cof11*v1 + cof21*v2)/det); 01277 matrix[2][3] = (float)((- cof02*v0 + cof12*v1 - cof22*v2)/det); 01278 }
bool Transform::is_identity | ( | ) | const |
Returns whethers or this matrix is the identity.
Definition at line 213 of file transform.cpp.
References EMAN::Util::apply_precision(), ERR_LIMIT, and matrix.
Referenced by EMAN::TestTomoImage::insert_rectangle(), and EMAN::FourierReconstructor::preprocess_slice().
00213 { 00214 for(int i=0; i<3; ++i) { 00215 for(int j=0; j<4; ++j) { 00216 float c = matrix[i][j]; 00217 Util::apply_precision(c,ERR_LIMIT); 00218 if(i==j) { 00219 if (c != 1.0) return false; 00220 } 00221 else { 00222 if (c != 0.0) return false; 00223 } 00224 } 00225 } 00226 return true; 00227 }
bool Transform::is_rot_identity | ( | ) | const |
Returns whethers or this matrix rotation is the identity.
Definition at line 229 of file transform.cpp.
References EMAN::Util::apply_precision(), ERR_LIMIT, and matrix.
00229 { 00230 for(int i=0; i<3; ++i) { 00231 for(int j=0; j<3; ++j) { 00232 float c = matrix[i][j]; 00233 Util::apply_precision(c,ERR_LIMIT); 00234 if(i==j) { 00235 if (c != 1.0) return false; 00236 } 00237 else { 00238 if (c != 0.0) return false; 00239 } 00240 } 00241 } 00242 return true; 00243 }
Transform Transform::negate | ( | ) | const |
Negates the Transform - a useful way, for example, for getting an orientation on the opposite side of the sphere.
Definition at line 767 of file transform.cpp.
References t.
00768 { 00769 Transform t(*this); 00770 for(unsigned int i = 0; i < 3; ++i) { 00771 for(unsigned int j = 0; j < 4; ++j) { 00772 t.set(i,j,t[i][j]*-1); 00773 } 00774 } 00775 return t; 00776 }
bool Transform::operator!= | ( | const Transform & | rhs | ) | const |
Unequality comparision operator.
rhs | the Transform object compared to |
Definition at line 131 of file transform.cpp.
References operator==(), and rhs.
00131 { 00132 return !(operator==(rhs)); 00133 }
Assignment operator.
that | that which this will become |
Definition at line 114 of file transform.cpp.
References matrix.
00114 { 00115 if (this != &that ) { 00116 memcpy(matrix,that.matrix,12*sizeof(float)); 00117 // transform_type = that.transform_type; 00118 } 00119 return *this; 00120 }
bool Transform::operator== | ( | const Transform & | rhs | ) | const |
Equality comparision operator.
rhs | the Transform object compared to |
Definition at line 122 of file transform.cpp.
References rhs.
Referenced by operator!=().
00122 { 00123 if (memcmp(this->matrix, rhs.matrix, 3*4*sizeof(float)) == 0) { 00124 return true; 00125 } 00126 else { 00127 return false; 00128 } 00129 }
const float* EMAN::Transform::operator[] | ( | int | i | ) | const [inline] |
Operator[] convenience so Transform3D[2][2] etc terminology can be used.
Definition at line 415 of file transform.h.
References matrix.
00415 { return matrix[i]; }
float* EMAN::Transform::operator[] | ( | int | i | ) | [inline] |
Operator[] convenience so Transform3D[2][2] etc terminology can be used.
Definition at line 410 of file transform.h.
References matrix.
00410 { return matrix[i]; }
void Transform::orthogonalize | ( | ) |
Reorthogonalize the rotation part of the matrix in place.
Does this by performing the SVD decomposition of the rotation matrix R such that R = USV^T - since the eigenvalues of a rotation matrix are all 1 we enforce that S should be the identity and produce a corrected matrix R' = UV^T
Definition at line 1132 of file transform.cpp.
References get_scale_and_mirror(), matrix, R, scale(), UnexpectedBehaviorException, and V.
01133 { 01134 float scale; 01135 bool x_mirror; 01136 get_scale_and_mirror(scale,x_mirror); 01137 if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected."); 01138 double inv_scale = 1.0/static_cast<double>(scale); 01139 double mirror_scale = (x_mirror == true ? -1.0:1.0); 01140 01141 gsl_matrix * R = gsl_matrix_calloc(3,3); 01142 for ( unsigned int i = 0; i < 3; ++i ) 01143 { 01144 for ( unsigned int j = 0; j < 3; ++j ) 01145 { 01146 if (i == 0 && mirror_scale != 1.0 ) { 01147 gsl_matrix_set( R, i, j, static_cast<double>(matrix[i][j])*mirror_scale*inv_scale ); 01148 } 01149 else { 01150 gsl_matrix_set( R, i, j, static_cast<double>(matrix[i][j])*inv_scale ); 01151 } 01152 } 01153 } 01154 01155 gsl_matrix * V = gsl_matrix_calloc(3,3); 01156 gsl_vector * S = gsl_vector_calloc(3); 01157 gsl_vector * work = gsl_vector_calloc(3); 01158 gsl_linalg_SV_decomp (R, V, S, work); // Now R is U of the SVD R = USV^T 01159 01160 gsl_matrix * Soln = gsl_matrix_calloc(3,3); 01161 gsl_blas_dgemm (CblasNoTrans, CblasTrans, 1.0, R, V, 0.0, Soln); 01162 01163 for ( unsigned int i = 0; i < 3; ++i ) 01164 { 01165 for ( unsigned int j = 0; j < 3; ++j ) 01166 { 01167 matrix[i][j] = static_cast<float>( gsl_matrix_get(Soln,i,j) ); 01168 } 01169 } 01170 01171 // Apply scale if it existed previously 01172 if (scale != 1.0f) { 01173 for(int i=0; i<3; ++i) { 01174 for(int j=0; j<3; ++j) { 01175 matrix[i][j] *= scale; 01176 } 01177 } 01178 } 01179 01180 // Apply post x mirroring if it was applied previouslys 01181 if ( x_mirror ) { 01182 for(int j=0; j<3; ++j) { 01183 matrix[0][j] *= -1.0f; 01184 } 01185 } 01186 01187 gsl_matrix_free(V); gsl_matrix_free(R); gsl_matrix_free(Soln); 01188 gsl_vector_free(S); gsl_vector_free(work); 01189 }
void EMAN::Transform::printme | ( | ) | const [inline] |
Print the contents of the internal matrix verbatim to standard out.
Definition at line 356 of file transform.h.
References matrix.
00356 { 00357 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[0][0],matrix[0][1],matrix[0][2],matrix[0][3]); 00358 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[1][0],matrix[1][1],matrix[1][2],matrix[1][3]); 00359 printf("%8.6f %8.6f %8.6f %8.6f\n",matrix[2][0],matrix[2][1],matrix[2][2],matrix[2][3]); 00360 printf("%8.6f %8.6f %8.6f %8.6f\n",0.0,0.0,0.0,1.0); 00361 00362 }
void Transform::rotate | ( | const Transform & | by | ) |
Increment the rotation by multipling the rotation bit of the argument transfrom by the current transfrom.
rotation | multiplican, a tranform, R'', by which to multiply the current one, R' == R''R' |
Definition at line 749 of file transform.cpp.
References get_matrix(), and matrix.
00750 { 00751 vector<float> multmatrix = by.get_matrix(); 00752 // First Multiply and put the result in a temp matrix 00753 Transform result; 00754 for (int i=0; i<3; i++) { 00755 for (int j=0; j<4; j++) { 00756 result[i][j] = multmatrix[i*4]*matrix[0][j] + multmatrix[i*4+1]*matrix[1][j] + multmatrix[i*4+2]*matrix[2][j]; 00757 } 00758 } 00759 //Then put the result from the tmep matrix in the original one 00760 for (int i=0; i<3; i++) { 00761 for (int j=0; j<4; j++) { 00762 matrix[i][j] = result[i][j]; 00763 } 00764 } 00765 }
void Transform::rotate_origin | ( | const Transform & | by | ) |
Increment the rotation by multipling the rotation bit of the argument transfrom by the rotation part of the current transfrom.
by | multiplican, a tranform, R'', by which to multiply the current one, R' == R''R' |
Definition at line 706 of file transform.cpp.
References get_matrix(), and matrix.
Referenced by rotate_origin_newBasis().
00707 { 00708 vector<float> multmatrix = by.get_matrix(); 00709 // First Multiply and put the result in a temp matrix 00710 Transform result; 00711 for (int i=0; i<3; i++) { 00712 for (int j=0; j<3; j++) { 00713 result[i][j] = multmatrix[i*4]*matrix[0][j] + multmatrix[i*4+1]*matrix[1][j] + multmatrix[i*4+2]*matrix[2][j]; 00714 } 00715 } 00716 //Then put the result from the tmep matrix in the original one 00717 for (int i=0; i<3; i++) { 00718 for (int j=0; j<3; j++) { 00719 matrix[i][j] = result[i][j]; 00720 } 00721 } 00722 }
void Transform::rotate_origin_newBasis | ( | const Transform & | tcs, | |
const float & | omega, | |||
const float & | n1, | |||
const float & | n2, | |||
const float & | n3 | |||
) |
Increment the rotation by multipling the rotation bit of the argument transfrom by the rotation part of the current transfrom This version rotates in the standard coordinate system, even after it have been modified by tcs.
The effect is to undo the distortion casued by dcs. Useful in the scenegraph
tcs,the | stansfrom that moves us to a non standard coordinate system | |
by | multiplican, a tranform, R'', by which to multiply the current one, R' == R''R' |
Definition at line 724 of file transform.cpp.
References get_trans(), invert(), rotate_origin(), set_scale(), set_trans(), and Transform().
00725 { 00726 //Get the rotational inverse 00727 Transform tcsinv = Transform(tcs); 00728 tcsinv.set_trans(0.0, 0.0, 0.0); 00729 tcsinv.set_scale(1.0); 00730 tcsinv.invert(); 00731 00732 //Get the current rotation 00733 Transform temp = Transform(); 00734 temp.set_trans(n1, n2, n3); 00735 Transform cc = tcsinv*temp; 00736 Vec3f cctrans = cc.get_trans(); 00737 00738 //set the right rotation 00739 Dict spinrot = Dict(); 00740 spinrot["type"] = "spin"; 00741 spinrot["omega"] = omega; 00742 spinrot["n1"] = cctrans[0]; 00743 spinrot["n2"] = cctrans[1]; 00744 spinrot["n3"] = cctrans[2]; 00745 Transform rightrot = Transform(spinrot); 00746 rotate_origin(rightrot); 00747 }
void Transform::scale | ( | const float & | scale | ) |
Increment the scale.
scale | the amount increment by |
Definition at line 1112 of file transform.cpp.
References get_determinant(), and set_scale().
Referenced by get_params(), get_params_inverse(), get_rotation(), get_scale(), orthogonalize(), set_params(), set_params_inverse(), set_pre_trans(), and set_rotation().
01113 { 01114 float determinant = get_determinant(); 01115 if (determinant < 0) determinant *= -1.0f; 01116 float newscale = std::pow(determinant,1.0f/3.0f) + scale; 01117 if(newscale > 0.0001) set_scale(newscale); // If scale ~ 0 things blowup, so we need a little fudge factor 01118 }
void EMAN::Transform::set | ( | int | r, | |
int | c, | |||
float | value | |||
) | [inline] |
Set the value stored in the internal transformation matrix at at coordinate (r,c) to value.
Definition at line 405 of file transform.h.
References matrix.
Referenced by EMAN::PointArray::align_2d().
00405 { matrix[r][c] = value; }
void Transform::set_matrix | ( | const vector< float > & | v | ) |
Set the transformation matrix using a vector.
Must be of length 12.
v | the transformation matrix stored as a vector - 3 rows of 4. |
Definition at line 150 of file transform.cpp.
References InvalidParameterException, and matrix.
Referenced by EMAN::EMObject::operator Transform *(), and Transform().
00151 { 00152 if (v.size() != 12 ) throw InvalidParameterException("The construction array must be of size 12"); 00153 00154 for(int i=0; i<3; ++i) { 00155 for(int j=0; j<4; ++j) { 00156 matrix[i][j] = v[i*4+j]; 00157 } 00158 } 00159 }
void Transform::set_mirror | ( | const bool | x_mirror | ) |
Set whether or not x_mirroring is occuring.
x_mirror | whether x_mirroring should be applied |
Definition at line 1191 of file transform.cpp.
References get_mirror(), and matrix.
Referenced by EMAN::RefineAlignerCG::align(), EMAN::RefineAligner::align(), EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), get_rotation_transform(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), set_params(), and set_params_inverse().
01191 { 01192 01193 bool old_x_mirror = get_mirror(); 01194 if (old_x_mirror == x_mirror) return; // The user is setting the same value 01195 else { 01196 // Toggle the mirroring operation 01197 for (int j = 0; j < 4; ++j ) { 01198 matrix[0][j] *= -1; 01199 } 01200 } 01201 }
void Transform::set_params | ( | const Dict & | d | ) |
Set the parameters of the entire transform.
keys acted upon are "type" - if this exists then the correct euler angles need to be included - also "tx","ty","tz", "scale", and "mirror"
d | the dictionary containing the parameters |
Definition at line 245 of file transform.cpp.
References EMAN::EMObject::BOOL, detect_problem_keys(), EMAN::Dict::get_ci(), EMAN::Dict::has_key_ci(), EMAN::EMObject::INT, InvalidParameterException, scale(), set_mirror(), set_rotation(), set_scale(), set_trans(), and EMAN::EMObject::UNSIGNEDINT.
Referenced by Transform().
00245 { 00246 detect_problem_keys(d); 00247 00248 if (d.has_key_ci("type") ) set_rotation(d); 00249 00250 if (d.has_key_ci("scale")) { 00251 float scale = static_cast<float>(d.get_ci("scale")); 00252 set_scale(scale); 00253 } 00254 00255 float dx=0,dy=0,dz=0; 00256 00257 if (d.has_key_ci("tx")) dx = static_cast<float>(d.get_ci("tx")); 00258 if (d.has_key_ci("ty")) dy = static_cast<float>(d.get_ci("ty")); 00259 if (d.has_key_ci("tz")) dz = static_cast<float>(d.get_ci("tz")); 00260 00261 if ( dx != 0.0 || dy != 0.0 || dz != 0.0 ) { 00262 set_trans(dx,dy,dz); 00263 } 00264 00265 if (d.has_key_ci("mirror")) { 00266 EMObject e = d.get_ci("mirror"); 00267 if ( (e.get_type() != EMObject::BOOL ) && (e.get_type() != EMObject::INT ) && (e.get_type() != EMObject::UNSIGNEDINT ) ) 00268 throw InvalidParameterException("Error, mirror must be a bool or an int"); 00269 00270 bool mirror = static_cast<bool>(e); 00271 set_mirror(mirror); 00272 } 00273 }
void Transform::set_params_inverse | ( | const Dict & | d | ) |
Set the parameters of the entire transform as though they there in the inverse format.
in other words, calling set_params_inverse(get_params_inverse()) should essentially leave the object unchanged.
d | the dictionary containing the inverse parameters |
Definition at line 417 of file transform.cpp.
References EMAN::EMObject::BOOL, detect_problem_keys(), EMAN::Dict::get_ci(), get_trans(), EMAN::Dict::has_key_ci(), EMAN::EMObject::INT, InvalidParameterException, invert(), scale(), set_mirror(), set_rotation(), set_scale(), set_trans(), Transform(), and EMAN::EMObject::UNSIGNEDINT.
00417 { 00418 detect_problem_keys(d); 00419 00420 if (d.has_key_ci("type") ) set_rotation(d); 00421 00422 float dx=0,dy=0,dz=0; 00423 if (d.has_key_ci("tx")) dx = static_cast<float>(d.get_ci("tx")); 00424 if (d.has_key_ci("ty")) dy = static_cast<float>(d.get_ci("ty")); 00425 if (d.has_key_ci("tz")) dz = static_cast<float>(d.get_ci("tz")); 00426 00427 if ( (dx != 0.0 || dy != 0.0 || dz != 0.0) && d.has_key_ci("type") ) { 00428 Transform pre_trans; 00429 pre_trans.set_trans(dx,dy,dz); 00430 00431 Transform tmp; 00432 tmp.set_rotation(d); 00433 00434 if (d.has_key_ci("scale")) { 00435 float scale = static_cast<float>(d.get_ci("scale")); 00436 tmp.set_scale(scale); 00437 } 00438 00439 Transform solution_trans = tmp*pre_trans; 00440 00441 if (d.has_key_ci("scale")) { 00442 Transform tmp; 00443 float scale = static_cast<float>(d.get_ci("scale")); 00444 tmp.set_scale(scale); 00445 solution_trans = solution_trans*tmp; 00446 } 00447 00448 tmp = Transform(); 00449 tmp.set_rotation(d); 00450 solution_trans = solution_trans*tmp; 00451 set_trans(solution_trans.get_trans()); 00452 } 00453 00454 if (d.has_key_ci("scale")) { 00455 float scale = static_cast<float>(d.get_ci("scale")); 00456 set_scale(scale); 00457 } 00458 00459 if (d.has_key_ci("mirror")) { 00460 EMObject e = d.get_ci("mirror"); 00461 if ( (e.get_type() != EMObject::BOOL ) && (e.get_type() != EMObject::INT ) && (e.get_type() != EMObject::UNSIGNEDINT ) ) 00462 throw InvalidParameterException("Error, mirror must be a bool or an int"); 00463 00464 bool mirror = static_cast<bool>(e); 00465 set_mirror(mirror); 00466 } 00467 invert(); 00468 }
void EMAN::Transform::set_pre_trans | ( | const type & | v | ) |
Set the translational component of the matrix as though it was MSRT_ not MTSR, where T_ is the pre translation.
Internally the correct form of MTSR is computed.
v | the vector (Vec3f or Vec2f) that is the pre trans |
Definition at line 559 of file transform.h.
References get_rotation(), get_scale(), invert(), scale(), set_rotation(), set_scale(), and set_trans().
Referenced by EMAN::PointArray::align_2d().
00559 { 00560 00561 Transform tmp; 00562 Dict rot = get_rotation("eman"); 00563 tmp.set_rotation(rot); 00564 00565 float scale = get_scale(); 00566 if (scale != 1.0 ) tmp.set_scale(scale); 00567 00568 Transform trans; 00569 trans.set_trans(v); 00570 00571 trans = tmp*trans; 00572 00573 Transform tmp2; 00574 tmp2.set_rotation(rot); 00575 tmp2.invert(); // invert 00576 if (scale != 1.0 ) tmp2.set_scale(1.0f/scale); 00577 00578 00579 trans = trans*tmp2; 00580 00581 set_trans(trans.get_trans()); 00582 }
void Transform::set_rotation | ( | const Vec3f & | v | ) |
Determine the rotation that would transform a vector pointing in the Z direction so that it points in the direction of the argument vector Automatically normalizes the vector.
v | the direction you want to solve for |
Definition at line 684 of file transform.cpp.
References EMAN::Vec3< Type >::normalize(), EMAN::EMConsts::rad2deg, set_rotation(), theta, UnexpectedBehaviorException, and v.
00685 { 00686 if ( v[0] == 0 && v[1] == 0 && v[2] == 0 ) 00687 throw UnexpectedBehaviorException("Can't set rotation for the null vector"); 00688 00689 Vec3f v1(v); 00690 v1.normalize(); 00691 00692 double theta = acos(v1[2]); // in radians 00693 double psi = atan2(v1[1],-v1[0]); 00694 00695 Dict d; 00696 d["theta"] = (double)EMConsts::rad2deg*theta; 00697 d["psi"] = (double)EMConsts::rad2deg*psi; 00698 d["phi"] = (double)0.0; 00699 d["type"] = "spider"; 00700 00701 set_rotation(d); 00702 00703 00704 }
void Transform::set_rotation | ( | const Dict & | rotation | ) |
Set a rotation using a specific Euler type and the dictionary interface Works for all Euler types.
rotation | a dictionary containing all key-entry pair required of the associated Euler type |
Definition at line 511 of file transform.cpp.
References assert_valid_2d(), EMAN::EMConsts::deg2rad, detect_problem_keys(), EMAN::Dict::get_ci(), get_scale_and_mirror(), EMAN::Dict::has_key_ci(), InvalidParameterException, InvalidStringException, matrix, phi, scale(), EMAN::Util::str_to_lower(), and UnexpectedBehaviorException.
Referenced by EMAN::RotatePrecenterAligner::align(), EMAN::BackProjectionReconstructor::preprocess_slice(), EMAN::FourierReconstructor::preprocess_slice(), EMAN::MrcIO::read_mrc_header(), set_params(), set_params_inverse(), set_pre_trans(), and set_rotation().
00512 { 00513 detect_problem_keys(rotation); 00514 string euler_type; 00515 00516 if (!rotation.has_key_ci("type") ){ 00517 throw InvalidParameterException("argument dictionary does not contain the type key"); 00518 } 00519 00520 euler_type = static_cast<string>(rotation.get_ci("type"));// Warning, will throw 00521 00522 00523 double e0=0; double e1=0; double e2=0; double e3=0; 00524 double omega=0; 00525 double az = 0; 00526 double alt = 0; 00527 double phi = 0; 00528 double cxtilt = 0; 00529 double sxtilt = 0; 00530 double cytilt = 0; 00531 double sytilt = 0; 00532 double cztilt = 0; 00533 double sztilt = 0; 00534 bool is_quaternion = 0; 00535 bool is_matrix = 0; 00536 bool is_xyz = 0; 00537 00538 bool x_mirror; 00539 float scale; 00540 // Get these before anything changes so we can apply them again after the rotation is set 00541 get_scale_and_mirror(scale,x_mirror); 00542 if (scale == 0) throw UnexpectedBehaviorException("The determinant of the Transform is 0. This is unexpected."); 00543 00544 string type = Util::str_to_lower(euler_type); 00545 if (type == "2d") { 00546 assert_valid_2d(); 00547 az = 0; 00548 alt = 0; 00549 phi = (double)rotation["alpha"] ; 00550 } else if ( type == "eman" ) { 00551 // validate_and_set_type(THREED); 00552 az = (double)rotation["az"] ; 00553 alt = (double)rotation["alt"] ; 00554 phi = (double)rotation["phi"] ; 00555 } else if ( type == "imagic" ) { 00556 // validate_and_set_type(THREED); 00557 az = (double)rotation["alpha"] ; 00558 alt = (double)rotation["beta"] ; 00559 phi = (double)rotation["gamma"] ; 00560 } else if ( type == "spider" ) { 00561 // validate_and_set_type(THREED); 00562 az = (double)rotation["phi"] + 90.0; 00563 alt = (double)rotation["theta"] ; 00564 phi = (double)rotation["psi"] - 90.0; 00565 } else if ( type == "xyz" ) { 00566 // validate_and_set_type(THREED); 00567 is_xyz = 1; 00568 cxtilt = cos(EMConsts::deg2rad*(double)rotation["xtilt"]); 00569 sxtilt = sin(EMConsts::deg2rad*(double)rotation["xtilt"]); 00570 cytilt = cos(EMConsts::deg2rad*(double)rotation["ytilt"]); 00571 sytilt = sin(EMConsts::deg2rad*(double)rotation["ytilt"]); 00572 cztilt = cos(EMConsts::deg2rad*(double)rotation["ztilt"]); 00573 sztilt = sin(EMConsts::deg2rad*(double)rotation["ztilt"]); 00574 } else if ( type == "mrc" ) { 00575 // validate_and_set_type(THREED); 00576 az = (double)rotation["phi"] + 90.0f ; 00577 alt = (double)rotation["theta"] ; 00578 phi = (double)rotation["omega"] - 90.0f ; 00579 } else if ( type == "quaternion" ) { 00580 // validate_and_set_type(THREED); 00581 is_quaternion = 1; 00582 e0 = (double)rotation["e0"]; 00583 e1 = (double)rotation["e1"]; 00584 e2 = (double)rotation["e2"]; 00585 e3 = (double)rotation["e3"]; 00586 } else if ( type == "spin" ) { 00587 // validate_and_set_type(THREED); 00588 is_quaternion = 1; 00589 omega = (double)rotation["omega"]; 00590 e0 = cos(omega*EMConsts::deg2rad/2.0); 00591 e1 = sin(omega*EMConsts::deg2rad/2.0) * (double)rotation["n1"]; 00592 e2 = sin(omega*EMConsts::deg2rad/2.0) * (double)rotation["n2"]; 00593 e3 = sin(omega*EMConsts::deg2rad/2.0) * (double)rotation["n3"]; 00594 } else if ( type == "sgirot" ) { 00595 // validate_and_set_type(THREED); 00596 is_quaternion = 1; 00597 omega = (double)rotation["q"] ; 00598 e0 = cos(omega*EMConsts::deg2rad/2.0); 00599 e1 = sin(omega*EMConsts::deg2rad/2.0) * (double)rotation["n1"]; 00600 e2 = sin(omega*EMConsts::deg2rad/2.0) * (double)rotation["n2"]; 00601 e3 = sin(omega*EMConsts::deg2rad/2.0) * (double)rotation["n3"]; 00602 } else if ( type == "matrix" ) { 00603 is_matrix = 1; 00604 matrix[0][0] = (float)rotation["m11"]; 00605 matrix[0][1] = (float)rotation["m12"]; 00606 matrix[0][2] = (float)rotation["m13"]; 00607 matrix[1][0] = (float)rotation["m21"]; 00608 matrix[1][1] = (float)rotation["m22"]; 00609 matrix[1][2] = (float)rotation["m23"]; 00610 matrix[2][0] = (float)rotation["m31"]; 00611 matrix[2][1] = (float)rotation["m32"]; 00612 matrix[2][2] = (float)rotation["m33"]; 00613 } else { 00614 // transform_type = UNKNOWN; 00615 throw InvalidStringException(euler_type, "unknown Euler Type"); 00616 } 00617 00618 double azp = az*EMConsts::deg2rad; 00619 double altp = alt*EMConsts::deg2rad; 00620 double phip = phi*EMConsts::deg2rad; 00621 00622 if (!is_quaternion && !is_matrix && !is_xyz) { 00623 matrix[0][0] = (float)(cos(phip)*cos(azp) - cos(altp)*sin(azp)*sin(phip)); 00624 matrix[0][1] = (float)(cos(phip)*sin(azp) + cos(altp)*cos(azp)*sin(phip)); 00625 matrix[0][2] = (float)(sin(altp)*sin(phip)); 00626 matrix[1][0] = (float)(-sin(phip)*cos(azp) - cos(altp)*sin(azp)*cos(phip)); 00627 matrix[1][1] = (float)(-sin(phip)*sin(azp) + cos(altp)*cos(azp)*cos(phip)); 00628 matrix[1][2] = (float)(sin(altp)*cos(phip)); 00629 matrix[2][0] = (float)(sin(altp)*sin(azp)); 00630 matrix[2][1] = (float)(-sin(altp)*cos(azp)); 00631 matrix[2][2] = (float)cos(altp); 00632 } 00633 if (is_quaternion){ 00634 matrix[0][0] = (float)(e0 * e0 + e1 * e1 - e2 * e2 - e3 * e3); 00635 matrix[0][1] = (float)(2.0f * (e1 * e2 + e0 * e3)); 00636 matrix[0][2] = (float)(2.0f * (e1 * e3 - e0 * e2)); 00637 matrix[1][0] = (float)(2.0f * (e2 * e1 - e0 * e3)); 00638 matrix[1][1] = (float)(e0 * e0 - e1 * e1 + e2 * e2 - e3 * e3); 00639 matrix[1][2] = (float)(2.0f * (e2 * e3 + e0 * e1)); 00640 matrix[2][0] = (float)(2.0f * (e3 * e1 + e0 * e2)); 00641 matrix[2][1] = (float)(2.0f * (e3 * e2 - e0 * e1)); 00642 matrix[2][2] = (float)(e0 * e0 - e1 * e1 - e2 * e2 + e3 * e3); 00643 // keep in mind matrix[0][2] is M13 gives an e0 e2 piece, etc 00644 } 00645 if (is_xyz){ 00646 matrix[0][0] = (float)(cytilt*cztilt); 00647 matrix[0][1] = (float)(cxtilt*sztilt+sxtilt*sytilt*cztilt); 00648 matrix[0][2] = (float)(sxtilt*sztilt-cxtilt*sytilt*cztilt); 00649 matrix[1][0] = (float)(-cytilt*sztilt); 00650 matrix[1][1] = (float)(cxtilt*cztilt-sxtilt*sytilt*sztilt); 00651 matrix[1][2] = (float)(sxtilt*cztilt+cxtilt*sytilt*sztilt); 00652 matrix[2][0] = (float)(sytilt); 00653 matrix[2][1] = (float)(-sxtilt*cytilt); 00654 matrix[2][2] = (float)(cxtilt*cytilt); 00655 } 00656 00657 // Apply scale if it existed previously 00658 if (scale != 1.0f) { 00659 for(int i=0; i<3; ++i) { 00660 for(int j=0; j<3; ++j) { 00661 matrix[i][j] *= scale; 00662 } 00663 } 00664 } 00665 00666 // Apply post x mirroring if it was applied previously 00667 if ( x_mirror ) { 00668 for(int j=0; j<3; ++j) { 00669 matrix[0][j] *= -1.0f; 00670 } 00671 } 00672 }
void Transform::set_scale | ( | const float & | scale | ) |
Set the scale.
scale | the amount to scale by |
Definition at line 1076 of file transform.cpp.
References EMAN::Util::apply_precision(), ERR_LIMIT, get_scale(), InvalidValueException, and matrix.
Referenced by EMAN::RefineAlignerCG::align(), EMAN::RefineAligner::align(), EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), get_rotation_transform(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), rotate_origin_newBasis(), scale(), set_params(), set_params_inverse(), and set_pre_trans().
01076 { 01077 if (new_scale <= 0) { 01078 throw InvalidValueException(new_scale,"The scale factor in a Transform object must be positive and non zero"); 01079 } 01080 // Transform = MTSR (Mirroring, Translation, Scaling, Rotate) 01081 // So changing the scale boils down to this.... 01082 01083 float old_scale = get_scale(); 01084 01085 float n_scale = new_scale; 01086 Util::apply_precision(n_scale,ERR_LIMIT); 01087 01088 float corrected_scale = n_scale/old_scale; 01089 if ( corrected_scale != 1.0 ) { 01090 for(int i = 0; i < 3; ++i ) { 01091 for(int j = 0; j < 3; ++j ) { 01092 matrix[i][j] *= corrected_scale; 01093 } 01094 } 01095 } 01096 }
void EMAN::Transform::set_trans | ( | const Vec2f & | v | ) | [inline] |
Set the post translation component using a Vec2f.
v | the 2D translation vector |
Definition at line 229 of file transform.h.
References set_trans(), and v.
void EMAN::Transform::set_trans | ( | const Vec3f & | v | ) | [inline] |
Set the post translation component using a Vec3f.
v | the 3D translation vector |
Definition at line 224 of file transform.h.
References set_trans(), and v.
void Transform::set_trans | ( | const float & | x, | |
const float & | y, | |||
const float & | z = 0 | |||
) |
Set the post translation component.
x | the x translation | |
y | the y translation | |
z | the z translation |
Definition at line 989 of file transform.cpp.
References get_mirror(), and matrix.
Referenced by EMAN::Refine3DAlignerGrid::align(), EMAN::RefineAlignerCG::align(), EMAN::RefineAligner::align(), EMAN::WienerFourierReconstructor::determine_slice_agreement(), EMAN::FourierReconstructor::determine_slice_agreement(), frm_2d_Align(), get_pre_trans(), get_pre_trans_2d(), get_rotation_transform(), EMAN::HSym::get_sym(), EMAN::BackProjectionReconstructor::insert_slice(), EMAN::WienerFourierReconstructor::insert_slice(), EMAN::FourierReconstructor::insert_slice(), EMAN::MrcIO::read_mrc_header(), rotate_origin_newBasis(), set_params(), set_params_inverse(), set_pre_trans(), set_trans(), translate_newBasis(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().
00990 { 00991 bool x_mirror = get_mirror(); 00992 00993 if (x_mirror) matrix[0][3] = -x; 00994 else matrix[0][3] = x; 00995 matrix[1][3] = y; 00996 matrix[2][3] = z; 00997 }
Transform Transform::tet_3_to_2 | ( | ) | [static] |
Get the transform that moves any tetrahedron generated by eman2 so that it matches the 2-2-2 (MRC, FREALIGN) convention.
Doctor Phil says: AltAngle= acos(-1/3.0)*90/pi;
Definition at line 89 of file transform.cpp.
References t.
00089 { 00090 Transform t; 00091 Dict d; 00092 d["type"] = "eman"; 00093 d["phi"] = 45.0f; 00094 d["az"] = 0.0f; 00095 d["alt"] = 54.73561f; // 3 fold to a 2 fold 00099 t.set_rotation(d); 00100 return t; 00101 }
void Transform::to_identity | ( | ) |
Force the internal matrix to become the identity.
Definition at line 198 of file transform.cpp.
References matrix.
Referenced by Transform().
00199 { 00200 // transform_type = UNKNOWN; 00201 for(int i=0; i<3; ++i) { 00202 for(int j=0; j<4; ++j) { 00203 if(i==j) { 00204 matrix[i][j] = 1; 00205 } 00206 else { 00207 matrix[i][j] = 0; 00208 } 00209 } 00210 } 00211 }
Transform a 3D vector using the internal transformation matrix.
v | a three dimensional vector to be transformed |
Definition at line 459 of file transform.h.
References transform(), and v.
00459 { 00460 // assert_consistent_type(THREED); // Transform does the assertion 00461 return transform(v[0],v[1],v[2]); 00462 }
Vec3f EMAN::Transform::transform | ( | const float & | x, | |
const float & | y, | |||
const float & | z | |||
) | const [inline] |
Transform 3D coordinates using the internal transformation matrix.
x | the x coordinate of the transformed point | |
y | the y coordinate of the transformed point | |
z | the z coordinate of the transformed point |
Definition at line 445 of file transform.h.
References matrix.
00445 { 00446 // assert_consistent_type(THREED); 00447 Vec3f ret; 00448 ret[0] = matrix[0][0] * x + matrix[0][1] * y + matrix[0][2] * z + matrix[0][3]; 00449 ret[1] = matrix[1][0] * x + matrix[1][1] * y + matrix[1][2] * z + matrix[1][3]; 00450 ret[2] = matrix[2][0] * x + matrix[2][1] * y + matrix[2][2] * z + matrix[2][3]; 00451 return ret; 00452 }
Transform a 2D vector using the internal transformation matrix.
v | a two dimensional vector to be transformed |
Definition at line 435 of file transform.h.
References transform(), and v.
Vec2f EMAN::Transform::transform | ( | const float & | x, | |
const float & | y | |||
) | const [inline] |
Transform 2D coordinates using the internal transformation matrix.
x | the x coordinate of the transformed point | |
y | the y coordinate of the transformed point |
Definition at line 422 of file transform.h.
References matrix.
Referenced by EMAN::EMData::get_rotated_clip(), EMAN::operator *(), and transform().
00422 { 00423 // assert_valid_2d(); 00424 Vec2f ret; 00425 ret[0] = matrix[0][0]*x + matrix[0][1]*y + matrix[0][3]; 00426 ret[1] = matrix[1][0]*x + matrix[1][1]*y + matrix[1][3]; 00427 return ret; 00428 }
Increment the current translation using vec3f& v and a non standard basis.
v | the 3D translation vector |
Definition at line 266 of file transform.h.
References translate_newBasis(), and v.
00266 { translate_newBasis(tcs, v[0],v[1],v[2]); }
void EMAN::Transform::translate | ( | const Vec2f & | v | ) | [inline] |
Increment the current translation using vec2f& v.
v | the translation vector |
Definition at line 251 of file transform.h.
References translate(), and v.
void EMAN::Transform::translate | ( | const Vec3f & | v | ) | [inline] |
Increment the current translation using vec3f& v.
v | the 3D translation vector |
Definition at line 246 of file transform.h.
References translate(), and v.
void Transform::translate | ( | const float & | tx, | |
const float & | ty, | |||
const float & | tz = 0 | |||
) |
Increment the current translation by tx, ty, tz.
tx | the x incrementation | |
ty | the y incrementation | |
tz | the z incrementation |
Definition at line 1016 of file transform.cpp.
References get_mirror(), and matrix.
Referenced by translate(), and translate_newBasis().
01017 { 01018 bool x_mirror = get_mirror(); 01019 if (x_mirror) matrix[0][3] = -matrix[0][3] + tx; 01020 else matrix[0][3] = matrix[0][3] + tx; 01021 matrix[1][3] = matrix[1][3] + ty; 01022 matrix[2][3] = matrix[2][3] + tz; 01023 }
void Transform::translate_newBasis | ( | const Transform & | tcs, | |
const float & | tx, | |||
const float & | ty, | |||
const float & | tz = 0 | |||
) |
Increment the current translation by tx, ty, tz using a non standard basis Actualy what it does is remove the effect of tcs when a composite transfrom tcs*t (where t is the current transform) This function is used in the scenegraph.
tcs | the transform specifing the new basis vectors | |
tx | the x incrementation | |
ty | the y incrementation | |
tz | the z incrementation |
Definition at line 1025 of file transform.cpp.
References get_trans(), invert(), set_trans(), Transform(), and translate().
Referenced by translate().
01026 { 01027 //Get the rotational inverse 01028 Transform tcsinv = Transform(tcs); 01029 tcsinv.set_trans(0.0, 0.0, 0.0); 01030 tcsinv.invert(); 01031 01032 //Now move the coordinate system 01033 Transform temp = Transform(); 01034 temp.set_trans(tx, ty, tz); 01035 Transform nb_trans = tcsinv*temp; 01036 01037 translate(nb_trans.get_trans()); 01038 01039 }
Transform Transform::transpose | ( | ) | const |
Get the transpose of this transformation matrix.
Definition at line 1299 of file transform.cpp.
References t.
Referenced by EMAN::PDBReader::right_transform().
void Transform::transpose_inplace | ( | ) |
Get the transpose of this transformation matrix.
Definition at line 1286 of file transform.cpp.
References matrix.
01286 { 01287 float tempij; 01288 for (int i = 0; i < 3; i++) { 01289 for (int j = 0; j < i; j++) { 01290 if (i != j) { 01291 tempij= matrix[i][j]; 01292 matrix[i][j] = matrix[j][i]; 01293 matrix[j][i] = tempij; 01294 } 01295 } 01296 } 01297 }
const float Transform::ERR_LIMIT = 0.000001f [static] |
Definition at line 86 of file transform.h.
Referenced by assert_valid_2d(), get_determinant(), get_scale(), get_scale_and_mirror(), get_trans(), is_identity(), is_rot_identity(), EMAN::Symmetry3D::point_in_which_asym_unit(), EMAN::Util::point_is_in_triangle_2d(), and set_scale().
float EMAN::Transform::matrix[3][4] [private] |
Definition at line 506 of file transform.h.
Referenced by assert_valid_2d(), at(), copy_matrix_into_array(), get_determinant(), get_matrix(), get_matrix3_row(), get_matrix_4x4(), get_rotation(), get_sym_proj(), get_trans(), get_trans_2d(), invert(), is_identity(), is_rot_identity(), operator=(), operator[](), orthogonalize(), printme(), rotate(), rotate_origin(), set(), set_matrix(), set_mirror(), set_rotation(), set_scale(), set_trans(), to_identity(), transform(), Transform(), translate(), and transpose_inplace().
vector< string > Transform::permissable_2d_not_rot [static, private] |
This map is used to validate keys in the argument maps - e.g. if the type is 2d and the angle is not "alpha" then we should throw.
Definition at line 511 of file transform.h.
Referenced by detect_problem_keys(), and init_permissable_keys().
vector< string > Transform::permissable_3d_not_rot [static, private] |
Definition at line 512 of file transform.h.
Referenced by detect_problem_keys(), and init_permissable_keys().
map< string, vector< string > > Transform::permissable_rot_keys [static, private] |
Definition at line 513 of file transform.h.
Referenced by detect_problem_keys(), and init_permissable_keys().