#include <transform.h>
Public Types | |
UNKNOWN | |
EMAN | |
IMAGIC | |
SPIN | |
QUATERNION | |
SGIROT | |
SPIDER | |
MRC | |
XYZ | |
MATRIX | |
enum | EulerType { UNKNOWN, EMAN, IMAGIC, SPIN, QUATERNION, SGIROT, SPIDER, MRC, XYZ, MATRIX } |
Public Member Functions | |
Transform3D () | |
Default constructor Internal matrix is the identity. | |
Transform3D (const Transform3D &rhs) | |
Copy constructor. | |
Transform3D (const float &az, const float &alt, const float &phi) | |
Construct a Transform3D object describing a rotation, assuming the EMAN Euler type. | |
Transform3D (const float &az, const float &alt, const float &phi, const Vec3f &posttrans) | |
Construct a Transform3D object describing a rotation (assuming the EMAN Euler type) and a post translation. | |
Transform3D (const Vec3f &pretrans, const float &az, const float &alt, const float &phi, const Vec3f &posttrans) | |
Construct a Transform3D object describing a pre trans, a rotation assuming the EMAN Euler type) and a post translation. | |
Transform3D (EulerType euler_type, const float &a1, const float &a2, const float &a3) | |
Construct a Transform3D object describing a rotation, using a specific Euler type. | |
Transform3D (EulerType euler_type, const float &a1, const float &a2, const float &a3, const float &a4) | |
Construct a Transform3D object describing a rotation, using a specific Euler type. | |
Transform3D (EulerType euler_type, const Dict &rotation) | |
Construct a Transform3D object consisting only of a rotation, using a specific Euler type. | |
Transform3D (const float &m11, const float &m12, const float &m13, const float &m21, const float &m22, const float &m23, const float &m31, const float &m32, const float &m33) | |
Construct a Transform3D object consisting only of a rotation by initializing the internal rotation matrix component wise. | |
~Transform3D () | |
Destructor. | |
void | apply_scale (const float &scale) |
FIXME insert comments. | |
void | set_scale (const float &scale) |
FIXME insert comments. | |
void | orthogonalize () |
Reorthogonalize the matrix. | |
void | transpose () |
create the transpose in place | |
void | set_rotation (const float &az, const float &alt, const float &phi) |
A rotation is given by. | |
void | set_rotation (EulerType euler_type, const float &a1, const float &a2, const float &a3) |
Sets the rotation as defined by the EulerType works for EMAN, SPIDER, MRC, IMAGIC and XYZ. | |
void | set_rotation (EulerType euler_type, const float &a1, const float &a2, const float &a3, const float &a4) |
Set quaternion-based rotations Works for QUATERNION, SPIN and SGIROT. | |
void | set_rotation (const float &m11, const float &m12, const float &m13, const float &m21, const float &m22, const float &m23, const float &m31, const float &m32, const float &m33) |
set the internal rotation matrix component wise | |
void | set_rotation (EulerType euler_type, const Dict &rotation) |
Set a rotation using a specific Euler type and the dictionary interface Works for all Euler types. | |
Dict | get_rotation (EulerType euler_type=EMAN) const |
Get a rotation in any Euler format. | |
void | set_rotation (const Vec3f &eahat, const Vec3f &ebhat, const Vec3f &eAhat, const Vec3f &eBhat) |
returns a rotation that maps a pair of unit vectors, a,b to a second pair A,B | |
float | get_mag () const |
returns the magnitude of the rotation | |
Vec3f | get_finger () const |
returns the spin-axis (or finger) of the rotation | |
Vec3f | get_pretrans (int flag=0) const |
Gets one of two pre translation vectors. | |
Vec3f | get_posttrans (int flag=0) const |
Gets one of two post translation vectors. | |
Vec3f | get_total_posttrans () const |
Get the total translation as a post translation. | |
Vec3f | get_total_pretrans () const |
Get the total translation as a pre translation. | |
Vec3f | get_center () const |
This doesn't do anything, it returns an empty vector. | |
Vec3f | get_matrix3_col (int i) const |
Get a matrix column as a Vec3f. | |
Vec3f | get_matrix3_row (int i) const |
Get a matrix row as a Vec3f. | |
Vec3f | transform (const Vec3f &v3f) const |
Perform a full transform a Vec3f using the internal transformation matrix. | |
Vec3f | rotate (const Vec3f &v3f) const |
Rotate a Vec3f using the internal rotation matrix. | |
Transform3D | inverseUsingAngs () const |
FIXME insert comments. | |
Transform3D | inverse () const |
FIXME insert comments. | |
void | printme () const |
Print the Transform3D 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. | |
Transform3D | get_sym (const string &sym, int n) const |
void | set_center (const Vec3f ¢er) |
Set functions FIXME insert more comments from here down. | |
void | set_pretrans (const Vec3f &pretrans) |
void | set_pretrans (const float &dx, const float &dy, const float &dz) |
void | set_pretrans (const float &dx, const float &dy) |
void | set_pretrans (const Vec2f &pretrans) |
void | set_posttrans (const Vec3f &posttrans) |
void | set_posttrans (const float &dx, const float &dy, const float &dz) |
void | set_posttrans (const float &dx, const float &dy) |
void | set_posttrans (const Vec2f &posttrans) |
void | set_post_x_mirror (const bool b) |
bool | get_post_x_mirror () const |
float | get_scale () const |
void | to_identity () |
bool | is_identity () |
void | dsaw_zero_hack () |
This added by d.woolford, will eventually be removed by author. | |
Static Public Member Functions | |
static int | get_nsym (const string &sym) |
static vector< Transform3D * > | angles2tfvec (EulerType eulertype, const vector< float > angles) |
Convert a list of euler angles to a vector of Transform3D objects. | |
Static Public Attributes | |
static const float | ERR_LIMIT = 0.000001f |
Protected Types | |
CSYM | |
DSYM | |
TET_SYM | |
ICOS_SYM | |
OCT_SYM | |
ISYM | |
UNKNOWN_SYM | |
enum | SymType { CSYM, DSYM, TET_SYM, ICOS_SYM, OCT_SYM, ISYM, UNKNOWN_SYM } |
Protected Member Functions | |
void | init () |
Static Protected Member Functions | |
static SymType | get_sym_type (const string &symname) |
Protected Attributes | |
float | matrix [4][4] |
bool | post_x_mirror |
Transform3D::EulerType | s |
The left-top 3x3 submatrix
a b c R = e f g j k m
provides rotation, scaling and skewing (not yet implimented).
The cumulative translation is stored in (d, h, n). We put the post-translation into (p, q, r), since it is convenient to carry along at times. When matrices are multiplied or printed, these are hidden to the user. They can only be found by applying the post_translation method, and these elements are non-zero. Otherwise the post-translation method returns the cumulative translationmlb
If rotations need to be found around alternate origins, then brief calculations need to be performed Pre and Post Translations should be kept as separate vectors
a matrix R is called orthogonal if R * transpose(R) = 1. All Real Orthogonal Matrices have eigenvalues with unit modulus and determinant therefore equal to "\pm 1"
Definition at line 550 of file transform.h.
enum EMAN::Transform3D::SymType [protected] |
Definition at line 852 of file transform.h.
00853 { CSYM, 00854 DSYM, 00855 TET_SYM, 00856 ICOS_SYM, 00857 OCT_SYM, 00858 ISYM, 00859 UNKNOWN_SYM 00860 };
Transform3D::Transform3D | ( | ) |
Default constructor Internal matrix is the identity.
Definition at line 1200 of file transform.cpp.
References init().
01201 { 01202 init(); 01203 }
Transform3D::Transform3D | ( | const Transform3D & | rhs | ) |
Transform3D::Transform3D | ( | const float & | az, | |
const float & | alt, | |||
const float & | phi | |||
) |
Construct a Transform3D object describing a rotation, assuming the EMAN Euler type.
Definition at line 1217 of file transform.cpp.
References init(), and set_rotation().
01218 { 01219 init(); 01220 set_rotation(az,alt,phi); 01221 }
Transform3D::Transform3D | ( | const float & | az, | |
const float & | alt, | |||
const float & | phi, | |||
const Vec3f & | posttrans | |||
) |
Construct a Transform3D object describing a rotation (assuming the EMAN Euler type) and a post translation.
Definition at line 1225 of file transform.cpp.
References init(), set_posttrans(), and set_rotation().
01226 { 01227 init(); // This is called in set_rotation 01228 set_rotation(az,alt,phi); 01229 set_posttrans(posttrans); 01230 }
Transform3D::Transform3D | ( | const Vec3f & | pretrans, | |
const float & | az, | |||
const float & | alt, | |||
const float & | phi, | |||
const Vec3f & | posttrans | |||
) |
Construct a Transform3D object describing a pre trans, a rotation assuming the EMAN Euler type) and a post translation.
pretrans | the pre translation vector | |
az | EMAN - az | |
alt | EMAN - alt | |
phi | EMAN - phi | |
posttrans | the post translation vector |
Definition at line 1264 of file transform.cpp.
References init(), set_posttrans(), set_pretrans(), and set_rotation().
01265 { 01266 init(); 01267 set_pretrans(pretrans); 01268 set_rotation(az,alt,phi); 01269 set_posttrans(posttrans); 01270 }
Transform3D::Transform3D | ( | EulerType | euler_type, | |
const float & | a1, | |||
const float & | a2, | |||
const float & | a3 | |||
) |
Construct a Transform3D object describing a rotation, using a specific Euler type.
works for EMAN, SPIDER, MRC, IMAGIC and XYZ (Euler types required 3 parameters)
euler_type | the Euler type either EMAN, SPIDER, MRC, IMAGIC and XYZ | |
a1 | EMAN - az, SPIDER - phi, MRC - phi, IMAGIC - alpha, XYZ - xtilt | |
a2 | EMAN - alt, SPIDER - theta, MRC - theta, IMAGIC - beta, XYZ - ytilt | |
a3 | EMAN - phi, SPIDER - psi, MRC - omega, IMAGIC - gamma, XYZ - ztilt |
Definition at line 1241 of file transform.cpp.
References init(), and set_rotation().
01242 { 01243 init(); 01244 set_rotation(euler_type,a1,a2,a3); 01245 }
Transform3D::Transform3D | ( | EulerType | euler_type, | |
const float & | a1, | |||
const float & | a2, | |||
const float & | a3, | |||
const float & | a4 | |||
) |
Construct a Transform3D object describing a rotation, using a specific Euler type.
Works for Euler types that require 4 parameters
euler_type | the Euler type either QUATERNION, SPIN or SGIROT | |
a1 | QUATERNION - e0, SPN and SGIROT - Omega | |
a2 | QUATERNION - e1, SPN and SGIROT - n1 | |
a3 | QUATERNION - e2, SPN and SGIROT - n2 | |
a4 | QUATERNION - e3, SPN and SGIROT - n3 |
Definition at line 1247 of file transform.cpp.
References init(), and set_rotation().
01248 { 01249 init(); 01250 set_rotation(euler_type,a1,a2,a3,a4); 01251 }
Construct a Transform3D object consisting only of a rotation, using a specific Euler type.
Works for all Euler types
euler_type | any Euler type | |
rotation | a dictionary containing all key-entry pair required of the associated Euler type |
Definition at line 1255 of file transform.cpp.
References init(), and set_rotation().
01256 { 01257 init(); 01258 set_rotation(euler_type,rotation); 01259 }
Transform3D::Transform3D | ( | const float & | m11, | |
const float & | m12, | |||
const float & | m13, | |||
const float & | m21, | |||
const float & | m22, | |||
const float & | m23, | |||
const float & | m31, | |||
const float & | m32, | |||
const float & | m33 | |||
) |
Construct a Transform3D object consisting only of a rotation by initializing the internal rotation matrix component wise.
mij | the value to be placed in the internal transformation matrix at coordinate (i-1,j-1) |
Definition at line 1232 of file transform.cpp.
References init(), and set_rotation().
01235 { 01236 init(); 01237 set_rotation(m11,m12,m13,m21,m22,m23,m31,m32,m33); 01238 }
Transform3D::~Transform3D | ( | ) |
vector< Transform3D * > Transform3D::angles2tfvec | ( | EulerType | eulertype, | |
const vector< float > | angles | |||
) | [static] |
Convert a list of euler angles to a vector of Transform3D objects.
[in] | eulertype | The type of Euler angles that is being passed in. |
[in] | angles | A flat vector of angles. |
Definition at line 2360 of file transform.cpp.
02360 { 02361 int nangles = ang.size() / 3; 02362 vector<Transform3D*> tfvec; 02363 for (int i = 0; i < nangles; i++) { 02364 tfvec.push_back(new Transform3D(eulertype,ang[3*i],ang[3*i+1],ang[3*i+2])); 02365 } 02366 return tfvec; 02367 }
void Transform3D::apply_scale | ( | const float & | scale | ) |
FIXME insert comments.
Definition at line 1394 of file transform.cpp.
References matrix.
Referenced by inverseUsingAngs(), orthogonalize(), and set_scale().
01395 { 01396 for (int i = 0; i < 3; i++) { 01397 for (int j = 0; j < 4; j++) { 01398 matrix[i][j] *= scale; 01399 } 01400 } 01401 for (int j = 0; j < 3; j++) { 01402 matrix[3][j] *= scale; 01403 } 01404 }
float EMAN::Transform3D::at | ( | int | r, | |
int | c | |||
) | const [inline] |
Get the value stored in the internal transformation matrix at at coordinate (r,c).
Definition at line 790 of file transform.h.
References matrix.
Referenced by ali3d_d().
00790 { return matrix[r][c]; }
void EMAN::Transform3D::dsaw_zero_hack | ( | ) | [inline] |
This added by d.woolford, will eventually be removed by author.
Definition at line 841 of file transform.h.
References matrix.
00841 { 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 }
Vec3f Transform3D::get_center | ( | ) | const |
This doesn't do anything, it returns an empty vector.
Why is it being used?
Definition at line 1494 of file transform.cpp.
Referenced by EMAN::EMData::rotate_translate().
01495 { 01496 return Vec3f(); 01497 }
Vec3f Transform3D::get_finger | ( | ) | const |
returns the spin-axis (or finger) of the rotation
Definition at line 1443 of file transform.cpp.
References get_rotation(), and SPIN.
01444 { 01445 EulerType eulertype= SPIN ; 01446 Dict AA= get_rotation(eulertype); 01447 return Vec3f(AA["n1"],AA["n2"],AA["n3"]); 01448 }
float Transform3D::get_mag | ( | ) | const |
returns the magnitude of the rotation
Definition at line 1436 of file transform.cpp.
References get_rotation(), and SPIN.
01437 { 01438 EulerType eulertype= SPIN ; 01439 Dict AA= get_rotation(eulertype); 01440 return AA["Omega"]; 01441 }
Vec3f Transform3D::get_matrix3_col | ( | int | i | ) | const |
Vec3f Transform3D::get_matrix3_row | ( | int | i | ) | const |
int Transform3D::get_nsym | ( | const string & | sym | ) | [static] |
Definition at line 2293 of file transform.cpp.
References CSYM, DSYM, get_sym_type(), ICOS_SYM, InvalidValueException, ISYM, OCT_SYM, TET_SYM, and UNKNOWN_SYM.
Referenced by get_sym(), LBD_Cart(), recons3d_CGLS_mpi_Cart(), recons3d_HyBR_mpi_Cart(), recons3d_sirt_mpi(), recons3d_sirt_mpi_Cart(), and EMAN::PointArray::set_from().
02294 { 02295 string symname = name; 02296 02297 for (size_t i = 0; i < name.size(); i++) { 02298 if (isalpha(name[i])) { 02299 symname[i] = (char)tolower(name[i]); 02300 } 02301 } 02302 02303 SymType type = get_sym_type(symname); 02304 int nsym = 0; 02305 02306 switch (type) { 02307 case CSYM: 02308 nsym = atoi(symname.c_str() + 1); 02309 break; 02310 case DSYM: 02311 nsym = atoi(symname.c_str() + 1) * 2; 02312 break; 02313 case ICOS_SYM: 02314 nsym = 60; 02315 break; 02316 case OCT_SYM: 02317 nsym = 24; 02318 break; 02319 case TET_SYM: 02320 nsym = 12; 02321 break; 02322 case ISYM: 02323 nsym = 1; 02324 break; 02325 case UNKNOWN_SYM: 02326 default: 02327 throw InvalidValueException(type, name); 02328 } 02329 return nsym; 02330 }
bool EMAN::Transform3D::get_post_x_mirror | ( | ) | const [inline] |
Definition at line 822 of file transform.h.
References post_x_mirror.
00822 { return post_x_mirror; }
Vec3f Transform3D::get_posttrans | ( | int | flag = 0 |
) | const |
Gets one of two post translation vectors.
when the flag is 1 then the contents of the Transform3D matrix right column are returned
flag | if 0 returns the post translation vector, if 1 all translation is treated as post |
Definition at line 1450 of file transform.cpp.
References matrix().
Referenced by get_total_posttrans(), inverse(), inverseUsingAngs(), EMAN::EMData::rotate_translate(), and set_rotation().
01451 { 01452 if (flag==0){ 01453 return Vec3f(matrix[3][0], matrix[3][1], matrix[3][2]); 01454 } 01455 // otherwise as if all the translation was post 01456 return Vec3f(matrix[0][3], matrix[1][3], matrix[2][3]); 01457 }
Vec3f Transform3D::get_pretrans | ( | int | flag = 0 |
) | const |
Gets one of two pre translation vectors.
flag | if 0 returns the pre translation vector, if 1 all translation is treated as pre |
Definition at line 1468 of file transform.cpp.
References matrix, matrix(), and EMAN::Vec3< Type >::set_value_at().
Referenced by get_total_pretrans(), inverseUsingAngs(), set_posttrans(), and set_rotation().
01469 { 01470 // The expression is R^T(v_total - v_post); 01471 01472 Vec3f pretrans; 01473 Vec3f posttrans(matrix[3][0], matrix[3][1], matrix[3][2]); 01474 Vec3f tottrans(matrix[0][3], matrix[1][3], matrix[2][3]); 01475 Vec3f totminuspost; 01476 01477 totminuspost = tottrans; 01478 if (flag==0) { 01479 totminuspost = tottrans-posttrans; 01480 } 01481 01482 Transform3D Rinv = inverse(); 01483 for (int i=0; i<3; i++) { 01484 float ptnow=0; 01485 for (int j=0; j<3; j++) { 01486 ptnow += Rinv.matrix[i][j]* totminuspost[j] ; 01487 } 01488 pretrans.set_value_at(i,ptnow) ; // 01489 } 01490 return pretrans; 01491 }
Get a rotation in any Euler format.
euler_type | the requested Euler type |
Definition at line 1920 of file transform.cpp.
References EMAN, ERR_LIMIT, get_scale(), IMAGIC, InvalidValueException, MATRIX, matrix, max, MRC, phi, QUATERNION, EMAN::EMConsts::rad2deg, SGIROT, SPIDER, SPIN, sqrt(), and XYZ.
Referenced by ali3d_d(), get_finger(), get_mag(), inverseUsingAngs(), LBD_Cart(), recons3d_CGLS_mpi_Cart(), recons3d_sirt_mpi(), recons3d_sirt_mpi_Cart(), and EMAN::EMData::rotate_translate().
01921 { 01922 Dict result; 01923 01924 float max = 1 - ERR_LIMIT; 01925 float sca=get_scale(); 01926 float cosalt=matrix[2][2]/sca; 01927 01928 01929 float az=0; 01930 float alt = 0; 01931 float phi=0; 01932 float phiS = 0; // like az (but in SPIDER ZXZ) 01933 float psiS =0; // like phi (but in SPIDER ZYZ) 01934 01935 01936 // get alt, az, phi; EMAN 01937 01938 if (cosalt > max) { // that is, alt close to 0 01939 alt = 0; 01940 az=0; 01941 phi = (float)EMConsts::rad2deg*(float)atan2(matrix[0][1], matrix[0][0]); 01942 } 01943 else if (cosalt < -max) { // alt close to pi 01944 alt = 180; 01945 az=0; 01946 phi=360.0f-(float)EMConsts::rad2deg*(float)atan2(matrix[0][1], matrix[0][0]); 01947 } 01948 else { 01949 alt = (float)EMConsts::rad2deg*(float) acos(cosalt); 01950 az = 360.0f+(float)EMConsts::rad2deg*(float)atan2(matrix[2][0], -matrix[2][1]); 01951 phi = 360.0f+(float)EMConsts::rad2deg*(float)atan2(matrix[0][2], matrix[1][2]); 01952 } 01953 az=fmod(az+180.0f,360.0f)-180.0f; 01954 phi=fmod(phi+180.0f,360.0f)-180.0f; 01955 01956 // get phiS, psiS ; SPIDER 01957 if (fabs(cosalt) > max) { // that is, alt close to 0 01958 phiS=0; 01959 psiS = phi; 01960 } 01961 else { 01962 phiS = az - 90.0f; 01963 psiS = phi + 90.0f; 01964 } 01965 phiS = fmod((phiS + 360.0f ), 360.0f) ; 01966 psiS = fmod((psiS + 360.0f ), 360.0f) ; 01967 01968 // do some quaternionic stuff here 01969 01970 float nphi = (az-phi)/2.0f; 01971 // The next is also e0 01972 float cosOover2 = (cos((az+phi)*M_PI/360) * cos(alt*M_PI/360)) ; 01973 float sinOover2 = sqrt(1 -cosOover2*cosOover2); 01974 float cosnTheta = sin((az+phi)*M_PI/360) * cos(alt*M_PI/360) / sqrt(1-cosOover2*cosOover2) ; 01975 float sinnTheta = sqrt(1-cosnTheta*cosnTheta); 01976 float n1 = sinnTheta*cos(nphi*M_PI/180); 01977 float n2 = sinnTheta*sin(nphi*M_PI/180); 01978 float n3 = cosnTheta; 01979 float xtilt = 0; 01980 float ytilt = 0; 01981 float ztilt = 0; 01982 01983 01984 if (cosOover2<0) { 01985 cosOover2*=-1; n1 *=-1; n2*=-1; n3*=-1; 01986 } 01987 01988 01989 switch (euler_type) { 01990 case EMAN: 01991 result["az"] = az; 01992 result["alt"] = alt; 01993 result["phi"] = phi; 01994 break; 01995 01996 case IMAGIC: 01997 result["alpha"] = az; 01998 result["beta"] = alt; 01999 result["gamma"] = phi; 02000 break; 02001 02002 case SPIDER: 02003 result["phi"] = phiS; // The first Euler like az 02004 result["theta"] = alt; 02005 result["psi"] = psiS; 02006 break; 02007 02008 case MRC: 02009 result["phi"] = phiS; 02010 result["theta"] = alt; 02011 result["omega"] = psiS; 02012 break; 02013 02014 case XYZ: 02015 xtilt = atan2(-sin((M_PI/180.0f)*phiS)*sin((M_PI/180.0f)*alt),cos((M_PI/180.0f)*alt)); 02016 ytilt = asin( cos((M_PI/180.0f)*phiS)*sin((M_PI/180.0f)*alt)); 02017 ztilt = psiS*M_PI/180.0f - atan2(sin(xtilt), cos(xtilt) *sin(ytilt)); 02018 02019 xtilt=fmod(xtilt*180/M_PI+540.0f,360.0f) -180.0f; 02020 ztilt=fmod(ztilt*180/M_PI+540.0f,360.0f) -180.0f; 02021 02022 result["xtilt"] = xtilt; 02023 result["ytilt"] = ytilt*180/M_PI; 02024 result["ztilt"] = ztilt; 02025 break; 02026 02027 case QUATERNION: 02028 result["e0"] = cosOover2 ; 02029 result["e1"] = sinOover2 * n1 ; 02030 result["e2"] = sinOover2 * n2; 02031 result["e3"] = sinOover2 * n3; 02032 break; 02033 02034 case SPIN: 02035 result["Omega"] =360.0f* acos(cosOover2)/ M_PI ; 02036 result["n1"] = n1; 02037 result["n2"] = n2; 02038 result["n3"] = n3; 02039 break; 02040 02041 case SGIROT: 02042 result["q"] = 360.0f*acos(cosOover2)/M_PI ; 02043 result["n1"] = n1; 02044 result["n2"] = n2; 02045 result["n3"] = n3; 02046 break; 02047 02048 case MATRIX: 02049 result["m11"] = matrix[0][0] ; 02050 result["m12"] = matrix[0][1] ; 02051 result["m13"] = matrix[0][2] ; 02052 result["m21"] = matrix[1][0] ; 02053 result["m22"] = matrix[1][1] ; 02054 result["m23"] = matrix[1][2] ; 02055 result["m31"] = matrix[2][0] ; 02056 result["m32"] = matrix[2][1] ; 02057 result["m33"] = matrix[2][2] ; 02058 break; 02059 02060 default: 02061 throw InvalidValueException(euler_type, "unknown Euler Type"); 02062 } 02063 02064 return result; 02065 }
float Transform3D::get_scale | ( | ) | const |
Definition at line 1905 of file transform.cpp.
References matrix, and sqrt().
Referenced by ali3d_d(), get_rotation(), inverseUsingAngs(), orthogonalize(), EMAN::EMData::rotate_translate(), and set_scale().
01906 { 01907 // Assumes uniform scaling, calculation uses Z only. 01908 float scale =0; 01909 for (int i=0; i<3; i++) { 01910 for (int j=0; j<3; j++) { 01911 scale = scale + matrix[i][j]*matrix[i][j]; 01912 } 01913 } 01914 01915 return sqrt(scale/3); 01916 }
Transform3D Transform3D::get_sym | ( | const string & | sym, | |
int | n | |||
) | const |
Definition at line 2159 of file transform.cpp.
References CSYM, DSYM, get_nsym(), get_sym_type(), ICOS_SYM, InvalidValueException, ISYM, OCT_SYM, set_rotation(), and TET_SYM.
Referenced by LBD_Cart(), recons3d_CGLS_mpi_Cart(), recons3d_sirt_mpi(), recons3d_sirt_mpi_Cart(), and EMAN::PointArray::set_from().
02160 { 02161 int nsym = get_nsym(symname); 02162 02163 // Transform3D invalid; 02164 // invalid.set_rotation( -0.1f, -0.1f, -0.1f); 02165 02166 // see www.math.utah.edu/~alfeld/math/polyhedra/polyhedra.html for pictures 02167 // By default we will put largest symmetry along z-axis. 02168 02169 // Each Platonic Solid has 2E symmetry elements. 02170 02171 02172 // An icosahedron has m=5, n=3, F=20 E=30=nF/2, V=12=nF/m,since vertices shared by 5 triangles; 02173 // It is composed of 20 triangles. E=3*20/2; 02174 02175 02176 // An dodecahedron has m=3, n=5 F=12 E=30 V=20 02177 // It is composed of 12 pentagons. E=5*12/2; V= 5*12/3, since vertices shared by 3 pentagons; 02178 02179 02180 02181 // The ICOS symmetry group has the face along z-axis 02182 02183 float lvl0=0; // there is one pentagon on top; five-fold along z 02184 float lvl1= 63.4349f; // that is atan(2) // there are 5 pentagons with centers at this height (angle) 02185 float lvl2=116.5651f; //that is 180-lvl1 // there are 5 pentagons with centers at this height (angle) 02186 float lvl3=180.f; // there is one pentagon on the bottom 02187 // Notice that 63.439 is the angle between two faces of the dual object 02188 02189 static double ICOS[180] = { // This is with a pentagon normal to z 02190 0,lvl0,0, 0,lvl0,288, 0,lvl0,216, 0,lvl0,144, 0,lvl0,72, 02191 0,lvl1,36, 0,lvl1,324, 0,lvl1,252, 0,lvl1,180, 0,lvl1,108, 02192 72,lvl1,36, 72,lvl1,324, 72,lvl1,252, 72,lvl1,180, 72,lvl1,108, 02193 144,lvl1,36, 144,lvl1,324, 144,lvl1,252, 144,lvl1,180, 144,lvl1,108, 02194 216,lvl1,36, 216,lvl1,324, 216,lvl1,252, 216,lvl1,180, 216,lvl1,108, 02195 288,lvl1,36, 288,lvl1,324, 288,lvl1,252, 288,lvl1,180, 288,lvl1,108, 02196 36,lvl2,0, 36,lvl2,288, 36,lvl2,216, 36,lvl2,144, 36,lvl2,72, 02197 108,lvl2,0, 108,lvl2,288, 108,lvl2,216, 108,lvl2,144, 108,lvl2,72, 02198 180,lvl2,0, 180,lvl2,288, 180,lvl2,216, 180,lvl2,144, 180,lvl2,72, 02199 252,lvl2,0, 252,lvl2,288, 252,lvl2,216, 252,lvl2,144, 252,lvl2,72, 02200 324,lvl2,0, 324,lvl2,288, 324,lvl2,216, 324,lvl2,144, 324,lvl2,72, 02201 0,lvl3,0, 0,lvl3,288, 0,lvl3,216, 0,lvl3,144, 0,lvl3,72 02202 }; 02203 02204 02205 // A cube has m=3, n=4, F=6 E=12=nF/2, V=8=nF/m,since vertices shared by 3 squares; 02206 // It is composed of 6 squares. 02207 02208 02209 // An octahedron has m=4, n=3, F=8 E=12=nF/2, V=6=nF/m,since vertices shared by 4 triangles; 02210 // It is composed of 8 triangles. 02211 02212 // We have placed the OCT symmetry group with a face along the z-axis 02213 lvl0=0; 02214 lvl1=90; 02215 lvl2=180; 02216 02217 static float OCT[72] = {// This is with a face of a cube along z 02218 0,lvl0,0, 0,lvl0,90, 0,lvl0,180, 0,lvl0,270, 02219 0,lvl1,0, 0,lvl1,90, 0,lvl1,180, 0,lvl1,270, 02220 90,lvl1,0, 90,lvl1,90, 90,lvl1,180, 90,lvl1,270, 02221 180,lvl1,0, 180,lvl1,90, 180,lvl1,180, 180,lvl1,270, 02222 270,lvl1,0, 270,lvl1,90, 270,lvl1,180, 270,lvl1,270, 02223 0,lvl2,0, 0,lvl2,90, 0,lvl2,180, 0,lvl2,270 02224 }; 02225 // B^4=A^3=1; BABA=1; implies AA=BAB, ABA=B^3 , AB^2A = BBBABBB and 02226 // 20 words with at most a single A 02227 // 1 B BB BBB A BA AB BBA BAB ABB BBBA BBAB BABB ABBB BBBAB BBABB BABBB 02228 // BBBABB BBABBB BBBABBB 02229 // also ABBBA is distinct yields 4 more words 02230 // ABBBA BABBBA BBABBBA BBBABBBA 02231 // for a total of 24 words 02232 // Note A BBB A BBB A reduces to BBABB 02233 // and B A BBB A is the same as A BBB A BBB etc. 02234 02235 // The TET symmetry group has a face along the z-axis 02236 // It has n=m=3; F=4, E=6=nF/2, V=4=nF/m 02237 lvl0=0; // There is a face along z 02238 lvl1=109.4712f; // that is acos(-1/3) // There are 3 faces at this angle 02239 02240 static float TET[36] = {// This is with the face along z 02241 0,lvl0,0, 0,lvl0,120, 0,lvl0,240, 02242 0,lvl1,60, 0,lvl1,180, 0,lvl1,300, 02243 120,lvl1,60, 120,lvl1,180, 120,lvl1,300, 02244 240,lvl1,60, 240,lvl1,180, 240,lvl1,300 02245 }; 02246 // B^3=A^3=1; BABA=1; implies A^2=BAB, ABA=B^2 , AB^2A = B^2AB^2 and 02247 // 12 words with at most a single A 02248 // 1 B BB A BA AB BBA BAB ABB BBAB BABB BBABB 02249 // at most one A is necessary 02250 02251 Transform3D ret; 02252 SymType type = get_sym_type(symname); 02253 02254 switch (type) { 02255 case CSYM: 02256 ret.set_rotation( n * 360.0f / nsym, 0, 0); 02257 break; 02258 case DSYM: 02259 if (n >= nsym / 2) { 02260 ret.set_rotation((n - nsym/2) * 360.0f / (nsym / 2),180.0f, 0); 02261 } 02262 else { 02263 ret.set_rotation( n * 360.0f / (nsym / 2),0, 0); 02264 } 02265 break; 02266 case ICOS_SYM: 02267 ret.set_rotation((float)ICOS[n * 3 ], 02268 (float)ICOS[n * 3 + 1], 02269 (float)ICOS[n * 3 + 2] ); 02270 break; 02271 case OCT_SYM: 02272 ret.set_rotation((float)OCT[n * 3], 02273 (float)OCT[n * 3 + 1], 02274 (float)OCT[n * 3 + 2] ); 02275 break; 02276 case TET_SYM: 02277 ret.set_rotation((float)TET[n * 3 ], 02278 (float)TET[n * 3 + 1] , 02279 (float)TET[n * 3 + 2] ); 02280 break; 02281 case ISYM: 02282 ret.set_rotation(0, 0, 0); 02283 break; 02284 default: 02285 throw InvalidValueException(type, symname); 02286 } 02287 02288 ret = (*this) * ret; 02289 02290 return ret; 02291 }
Transform3D::SymType Transform3D::get_sym_type | ( | const string & | symname | ) | [static, protected] |
Definition at line 2334 of file transform.cpp.
References CSYM, DSYM, ICOS_SYM, ISYM, OCT_SYM, t, TET_SYM, and UNKNOWN_SYM.
Referenced by get_nsym(), and get_sym().
02335 { 02336 SymType t = UNKNOWN_SYM; 02337 02338 if (name[0] == 'c') { 02339 t = CSYM; 02340 } 02341 else if (name[0] == 'd') { 02342 t = DSYM; 02343 } 02344 else if (name == "icos") { 02345 t = ICOS_SYM; 02346 } 02347 else if (name == "oct") { 02348 t = OCT_SYM; 02349 } 02350 else if (name == "tet") { 02351 t = TET_SYM; 02352 } 02353 else if (name == "i" || name == "") { 02354 t = ISYM; 02355 } 02356 return t; 02357 }
Vec3f Transform3D::get_total_posttrans | ( | ) | const |
Get the total translation as a post translation.
Calls get_postrans(1)
Definition at line 1459 of file transform.cpp.
References get_posttrans().
01459 { 01460 return get_posttrans(1); 01461 }
Vec3f Transform3D::get_total_pretrans | ( | ) | const |
Get the total translation as a pre translation.
Calls get_pretrans(1)
Definition at line 1463 of file transform.cpp.
References get_pretrans().
01463 { 01464 return get_pretrans(1); 01465 }
void Transform3D::init | ( | ) | [protected] |
Definition at line 1325 of file transform.cpp.
References to_identity().
Referenced by set_rotation(), and Transform3D().
01326 { 01327 to_identity(); 01328 }
Transform3D Transform3D::inverse | ( | ) | const |
FIXME insert comments.
Definition at line 2104 of file transform.cpp.
References get_posttrans(), matrix, and v0.
Referenced by EMAN::EMData::rotate_translate().
02105 { 02106 // This assumes the matrix is 4 by 4 and the last row reads [0 0 0 1] 02107 02108 float m00 = matrix[0][0]; float m01=matrix[0][1]; float m02=matrix[0][2]; 02109 float m10 = matrix[1][0]; float m11=matrix[1][1]; float m12=matrix[1][2]; 02110 float m20 = matrix[2][0]; float m21=matrix[2][1]; float m22=matrix[2][2]; 02111 float v0 = matrix[0][3]; float v1 =matrix[1][3]; float v2 =matrix[2][3]; 02112 02113 float cof00 = m11*m22-m12*m21; 02114 float cof11 = m22*m00-m20*m02; 02115 float cof22 = m00*m11-m01*m10; 02116 float cof01 = m10*m22-m20*m12; 02117 float cof02 = m10*m21-m20*m11; 02118 float cof12 = m00*m21-m01*m20; 02119 float cof10 = m01*m22-m02*m21; 02120 float cof20 = m01*m12-m02*m11; 02121 float cof21 = m00*m12-m10*m02; 02122 02123 float Det = m00* cof00 + m02* cof02 -m01*cof01; 02124 02125 Transform3D invM; 02126 02127 invM.matrix[0][0] = cof00/Det; 02128 invM.matrix[0][1] = - cof10/Det; 02129 invM.matrix[0][2] = cof20/Det; 02130 invM.matrix[1][0] = - cof01/Det; 02131 invM.matrix[1][1] = cof11/Det; 02132 invM.matrix[1][2] = - cof21/Det; 02133 invM.matrix[2][0] = cof02/Det; 02134 invM.matrix[2][1] = - cof12/Det; 02135 invM.matrix[2][2] = cof22/Det; 02136 02137 invM.matrix[0][3] = (- cof00*v0 + cof10*v1 - cof20*v2 )/Det; 02138 invM.matrix[1][3] = ( cof01*v0 - cof11*v1 + cof21*v2 )/Det; 02139 invM.matrix[2][3] = (- cof02*v0 + cof12*v1 - cof22*v2 )/Det; 02140 02141 Vec3f postT = get_posttrans( ) ; 02142 Vec3f invMpre = - postT; 02143 Vec3f invMpost ; 02144 for ( int i = 0; i < 3; i++) { 02145 invMpost[i] = invM.matrix[i][3]; 02146 for ( int j = 0; j < 3; j++) { 02147 invMpost[i] += - invM.matrix[i][j]*invMpre[j]; 02148 } 02149 invM.matrix[3][i] = invMpost[i]; 02150 } 02151 02152 return invM; 02153 }
Transform3D Transform3D::inverseUsingAngs | ( | ) | const |
FIXME insert comments.
Definition at line 2067 of file transform.cpp.
References apply_scale(), EMAN, get_posttrans(), get_pretrans(), get_rotation(), get_scale(), set_posttrans(), set_pretrans(), and set_rotation().
02068 { 02069 // First Find the scale 02070 EulerType eE=EMAN; 02071 02072 02073 float scale = get_scale(); 02074 Vec3f preT = get_pretrans( ) ; 02075 Vec3f postT = get_posttrans( ) ; 02076 Dict angs = get_rotation(eE); 02077 Dict invAngs ; 02078 02079 invAngs["phi"] = 180.0f - (float) angs["az"] ; 02080 invAngs["az"] = 180.0f - (float) angs["phi"] ; 02081 invAngs["alt"] = angs["alt"] ; 02082 02083 // The inverse result 02084 // 02085 // Z_phi X_alt Z_az 02086 // is 02087 // Z_{pi-az} X_alt Z_{pi-phi} 02088 // The reason for the extra pi's, is because one would like to keep alt positive 02089 02090 float inverseScale= 1/scale ; 02091 02092 Transform3D invM; 02093 02094 invM.set_rotation(EMAN, invAngs); 02095 invM.apply_scale(inverseScale); 02096 invM.set_pretrans(-postT ); 02097 invM.set_posttrans(-preT ); 02098 02099 02100 return invM; 02101 02102 }
bool Transform3D::is_identity | ( | ) |
Definition at line 1303 of file transform.cpp.
References matrix.
01304 { 01305 for (int i=0; i<4; i++) { 01306 for (int j=0; j<4; j++) { 01307 if (i==j && matrix[i][j]!=1.0) return 0; 01308 if (i!=j && matrix[i][j]!=0.0) return 0; 01309 } 01310 } 01311 return 1; 01312 }
const float* EMAN::Transform3D::operator[] | ( | int | i | ) | const [inline] |
Operator[] convenience so Transform3D[2][2] etc terminology can be used.
Definition at line 804 of file transform.h.
References matrix.
00804 { return matrix[i]; }
float* EMAN::Transform3D::operator[] | ( | int | i | ) | [inline] |
Operator[] convenience so Transform3D[2][2] etc terminology can be used.
Definition at line 799 of file transform.h.
References matrix.
00799 { return matrix[i]; }
void Transform3D::orthogonalize | ( | ) |
Reorthogonalize the matrix.
Definition at line 1406 of file transform.cpp.
References apply_scale(), and get_scale().
01407 { 01408 //EulerType EMAN; 01409 float scale = get_scale() ; 01410 float inverseScale= 1/scale ; 01411 apply_scale(inverseScale); 01412 // Dict angs = get_rotation(EMAN); 01413 // set_Rotation(EMAN,angs); 01414 }
void EMAN::Transform3D::printme | ( | ) | const [inline] |
Print the Transform3D matrix.
Definition at line 779 of file transform.h.
References matrix.
00779 { 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 }
Rotate a Vec3f using the internal rotation matrix.
v3f | the vector to be rotated |
Definition at line 1522 of file transform.cpp.
References matrix(), x, and y.
01523 { 01524 // This is the rotation of a vector, v by a matrix M 01525 float x = matrix[0][0] * v3f[0] + matrix[0][1] * v3f[1] + matrix[0][2] * v3f[2] ; 01526 float y = matrix[1][0] * v3f[0] + matrix[1][1] * v3f[1] + matrix[1][2] * v3f[2] ; 01527 float z = matrix[2][0] * v3f[0] + matrix[2][1] * v3f[1] + matrix[2][2] * v3f[2] ; 01528 return Vec3f(x, y, z); 01529 }
void EMAN::Transform3D::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 794 of file transform.h.
References matrix.
00794 { matrix[r][c] = value; }
void Transform3D::set_center | ( | const Vec3f & | center | ) |
Set functions FIXME insert more comments from here down.
Definition at line 1315 of file transform.cpp.
References matrix, and set_pretrans().
Referenced by to_identity().
01316 { 01317 set_pretrans( Vec3f(0,0,0)-center); 01318 for (int i = 0; i < 3; i++) { 01319 matrix[i][3]=center[i]; 01320 } 01321 }
void EMAN::Transform3D::set_post_x_mirror | ( | const bool | b | ) | [inline] |
void Transform3D::set_posttrans | ( | const Vec2f & | posttrans | ) |
Definition at line 1369 of file transform.cpp.
References set_pretrans().
01370 { set_pretrans( Vec3f(posttrans[0],posttrans[1],0)); }
void Transform3D::set_posttrans | ( | const float & | dx, | |
const float & | dy | |||
) |
Definition at line 1366 of file transform.cpp.
References set_posttrans().
01367 { set_posttrans( Vec3f(dx,dy,0)); }
void Transform3D::set_posttrans | ( | const float & | dx, | |
const float & | dy, | |||
const float & | dz | |||
) |
Definition at line 1362 of file transform.cpp.
References set_posttrans().
01363 { set_posttrans( Vec3f(dx,dy,dz)); }
void Transform3D::set_posttrans | ( | const Vec3f & | posttrans | ) |
Definition at line 1372 of file transform.cpp.
References get_pretrans(), and matrix.
Referenced by ali3d_d(), inverseUsingAngs(), set_posttrans(), and Transform3D().
01373 { 01374 int flag=0; 01375 Vec3f preT = get_pretrans(0) ; 01376 for (int i = 0; i < 3; i++) { 01377 matrix[3][i] = posttrans[i]; 01378 } 01379 // transFinal = transPost + Rotation * transPre; 01380 // This will keep the old value of pretrans and change the value of posttrans and the total matrix 01381 if (flag==0) { 01382 matrix[0][3] = matrix[3][0] + matrix[0][0]*preT[0] + matrix[0][1]*preT[1] + matrix[0][2]*preT[2] ; 01383 matrix[1][3] = matrix[3][1] + matrix[1][0]*preT[0] + matrix[1][1]*preT[1] + matrix[1][2]*preT[2] ; 01384 matrix[2][3] = matrix[3][2] + matrix[2][0]*preT[0] + matrix[2][1]*preT[1] + matrix[2][2]*preT[2] ; 01385 } 01386 // This will keep the old value of the total matrix, and c 01387 if (flag==1) { // Don't do anything 01388 } 01389 }
void Transform3D::set_pretrans | ( | const Vec2f & | pretrans | ) |
Definition at line 1339 of file transform.cpp.
References set_pretrans().
01340 { set_pretrans( Vec3f(pretrans[0],pretrans[1],0)); }
void Transform3D::set_pretrans | ( | const float & | dx, | |
const float & | dy | |||
) |
Definition at line 1336 of file transform.cpp.
References set_pretrans().
01337 { set_pretrans( Vec3f(dx,dy,0)); }
void Transform3D::set_pretrans | ( | const float & | dx, | |
const float & | dy, | |||
const float & | dz | |||
) |
Definition at line 1332 of file transform.cpp.
References set_pretrans().
01333 { set_pretrans( Vec3f(dx,dy,dz)); }
void Transform3D::set_pretrans | ( | const Vec3f & | pretrans | ) |
Definition at line 1342 of file transform.cpp.
References matrix.
Referenced by EMAN::PointArray::align_2d(), inverseUsingAngs(), set_center(), set_posttrans(), set_pretrans(), and Transform3D().
01343 { 01344 int flag=0; 01345 01346 // transFinal = transPost + Rotation * transPre; 01347 // This will keep the old value of transPost and change the value of pretrans and the total matrix 01348 if (flag==0){ 01349 matrix[0][3] = matrix[3][0] + matrix[0][0]*preT[0] + matrix[0][1]*preT[1] + matrix[0][2]*preT[2] ; 01350 matrix[1][3] = matrix[3][1] + matrix[1][0]*preT[0] + matrix[1][1]*preT[1] + matrix[1][2]*preT[2] ; 01351 matrix[2][3] = matrix[3][2] + matrix[2][0]*preT[0] + matrix[2][1]*preT[1] + matrix[2][2]*preT[2] ; 01352 } 01353 // This will keep the old value of total translation and change the value of posttrans 01354 if (flag==1){ 01355 matrix[3][0] = matrix[0][3] - (matrix[0][0]*preT[0] + matrix[0][1]*preT[1] + matrix[0][2]*preT[2]) ; 01356 matrix[3][1] = matrix[1][3] - (matrix[1][0]*preT[0] + matrix[1][1]*preT[1] + matrix[1][2]*preT[2]) ; 01357 matrix[3][2] = matrix[2][3] - (matrix[2][0]*preT[0] + matrix[2][1]*preT[1] + matrix[2][2]*preT[2]) ; 01358 } 01359 }
void Transform3D::set_rotation | ( | const Vec3f & | eahat, | |
const Vec3f & | ebhat, | |||
const Vec3f & | eAhat, | |||
const Vec3f & | eBhat | |||
) |
returns a rotation that maps a pair of unit vectors, a,b to a second pair A,B
eahat,ebhat,eAhat,eBhat | are all unit vectors |
Definition at line 1848 of file transform.cpp.
References EMAN::Vec3< Type >::cross(), EMAN::Vec3< Type >::dot(), EMAN::Vec3< Type >::length(), EMAN::Vec3< Type >::normalize(), set_rotation(), and SPIN.
01850 {// this rotation rotates unit vectors a,b into A,B; 01851 // The program assumes a dot b must equal A dot B 01852 Vec3f eahatcp(eahat); 01853 Vec3f ebhatcp(ebhat); 01854 Vec3f eAhatcp(eAhat); 01855 Vec3f eBhatcp(eBhat); 01856 01857 eahatcp.normalize(); 01858 ebhatcp.normalize(); 01859 eAhatcp.normalize(); 01860 eBhatcp.normalize(); 01861 01862 Vec3f aMinusA(eahatcp); 01863 aMinusA -= eAhatcp; 01864 Vec3f bMinusB(ebhatcp); 01865 bMinusB -= eBhatcp; 01866 01867 01868 Vec3f nhat; 01869 float aAlength = aMinusA.length(); 01870 float bBlength = bMinusB.length(); 01871 if (aAlength==0){ 01872 nhat=eahatcp; 01873 }else if (bBlength==0){ 01874 nhat=ebhatcp; 01875 }else{ 01876 nhat= aMinusA.cross(bMinusB); 01877 nhat.normalize(); 01878 } 01879 01880 // printf("nhat=%f,%f,%f \n",nhat[0],nhat[1],nhat[2]); 01881 01882 Vec3f neahat = eahatcp.cross(nhat); 01883 Vec3f nebhat = ebhatcp.cross(nhat); 01884 Vec3f neAhat = eAhatcp.cross(nhat); 01885 Vec3f neBhat = eBhatcp.cross(nhat); 01886 01887 float cosOmegaA = (neahat.dot(neAhat)) / (neahat.dot(neahat)); 01888 // float cosOmegaB = (nebhat.dot(neBhat)) / (nebhat.dot(nebhat)); 01889 float sinOmegaA = (neahat.dot(eAhatcp)) / (neahat.dot(neahat)); 01890 // printf("cosOmegaA=%f \n",cosOmegaA); printf("sinOmegaA=%f \n",sinOmegaA); 01891 01892 float OmegaA = atan2(sinOmegaA,cosOmegaA); 01893 // printf("OmegaA=%f \n",OmegaA*180/M_PI); 01894 01895 EulerType euler_type=SPIN; 01896 Dict rotation; 01897 rotation["n1"]= nhat[0]; 01898 rotation["n2"]= nhat[1]; 01899 rotation["n3"]= nhat[2]; 01900 rotation["Omega"] =OmegaA*180.0/M_PI; 01901 set_rotation(euler_type, rotation); 01902 }
Set a rotation using a specific Euler type and the dictionary interface Works for all Euler types.
euler_type | any Euler type | |
rotation | a dictionary containing all key-entry pair required of the associated Euler type |
Definition at line 1699 of file transform.cpp.
References EMAN, get_posttrans(), get_pretrans(), IMAGIC, InvalidValueException, matrix, MATRIX, MRC, phi, QUATERNION, SGIROT, SPIDER, SPIN, and XYZ.
01700 { 01701 float e0 = 0;float e1=0; float e2=0; float e3=0; 01702 float Omega=0; 01703 float az = 0; 01704 float alt = 0; 01705 float phi = 0; 01706 float cxtilt = 0; 01707 float sxtilt = 0; 01708 float cytilt = 0; 01709 float sytilt = 0; 01710 bool is_quaternion = 0; 01711 bool is_matrix = 0; 01712 01713 switch(euler_type) { 01714 case EMAN: 01715 az = (float)rotation["az"] ; 01716 alt = (float)rotation["alt"] ; 01717 phi = (float)rotation["phi"] ; 01718 break; 01719 case IMAGIC: 01720 az = (float)rotation["alpha"] ; 01721 alt = (float)rotation["beta"] ; 01722 phi = (float)rotation["gamma"] ; 01723 break; 01724 01725 case SPIDER: 01726 az = (float)rotation["phi"] + 90.0f; 01727 alt = (float)rotation["theta"] ; 01728 phi = (float)rotation["psi"] - 90.0f; 01729 break; 01730 01731 case XYZ: 01732 cxtilt = cos( (M_PI/180.0f)*(float)rotation["xtilt"]); 01733 sxtilt = sin( (M_PI/180.0f)*(float)rotation["xtilt"]); 01734 cytilt = cos( (M_PI/180.0f)*(float)rotation["ytilt"]); 01735 sytilt = sin( (M_PI/180.0f)*(float)rotation["ytilt"]); 01736 az = (180.0f/M_PI)*atan2(-cytilt*sxtilt,sytilt) + 90.0f ; 01737 alt = (180.0f/M_PI)*acos(cytilt*cxtilt) ; 01738 phi = (float)rotation["ztilt"] +(180.0f/M_PI)*atan2(sxtilt,cxtilt*sytilt) - 90.0f ; 01739 break; 01740 01741 case MRC: 01742 az = (float)rotation["phi"] + 90.0f ; 01743 alt = (float)rotation["theta"] ; 01744 phi = (float)rotation["omega"] - 90.0f ; 01745 break; 01746 01747 case QUATERNION: 01748 is_quaternion = 1; 01749 e0 = (float)rotation["e0"]; 01750 e1 = (float)rotation["e1"]; 01751 e2 = (float)rotation["e2"]; 01752 e3 = (float)rotation["e3"]; 01753 break; 01754 01755 case SPIN: 01756 is_quaternion = 1; 01757 Omega = (float)rotation["Omega"]; 01758 e0 = cos(Omega*M_PI/360.0f); 01759 e1 = sin(Omega*M_PI/360.0f)* (float)rotation["n1"]; 01760 e2 = sin(Omega*M_PI/360.0f)* (float)rotation["n2"]; 01761 e3 = sin(Omega*M_PI/360.0f)* (float)rotation["n3"]; 01762 break; 01763 01764 case SGIROT: 01765 is_quaternion = 1; 01766 Omega = (float)rotation["q"] ; 01767 e0 = cos(Omega*M_PI/360.0f); 01768 e1 = sin(Omega*M_PI/360.0f)* (float)rotation["n1"]; 01769 e2 = sin(Omega*M_PI/360.0f)* (float)rotation["n2"]; 01770 e3 = sin(Omega*M_PI/360.0f)* (float)rotation["n3"]; 01771 break; 01772 01773 case MATRIX: 01774 is_matrix = 1; 01775 matrix[0][0] = (float)rotation["m11"] ; 01776 matrix[0][1] = (float)rotation["m12"] ; 01777 matrix[0][2] = (float)rotation["m13"] ; 01778 matrix[1][0] = (float)rotation["m21"] ; 01779 matrix[1][1] = (float)rotation["m22"] ; 01780 matrix[1][2] = (float)rotation["m23"] ; 01781 matrix[2][0] = (float)rotation["m31"] ; 01782 matrix[2][1] = (float)rotation["m32"] ; 01783 matrix[2][2] = (float)rotation["m33"] ; 01784 break; 01785 01786 default: 01787 throw InvalidValueException(euler_type, "unknown Euler Type"); 01788 } // ends switch euler_type 01789 01790 01791 Vec3f postT = get_posttrans( ) ; 01792 Vec3f preT = get_pretrans( ) ; 01793 01794 01795 float azp = fmod(az,360.0f)*M_PI/180.0f; 01796 float altp = alt*M_PI/180.0f; 01797 float phip = fmod(phi,360.0f)*M_PI/180.0f; 01798 01799 if (!is_quaternion && !is_matrix) { 01800 matrix[0][0] = cos(phip)*cos(azp) - cos(altp)*sin(azp)*sin(phip); 01801 matrix[0][1] = cos(phip)*sin(azp) + cos(altp)*cos(azp)*sin(phip); 01802 matrix[0][2] = sin(altp)*sin(phip); 01803 matrix[1][0] = -sin(phip)*cos(azp) - cos(altp)*sin(azp)*cos(phip); 01804 matrix[1][1] = -sin(phip)*sin(azp) + cos(altp)*cos(azp)*cos(phip); 01805 matrix[1][2] = sin(altp)*cos(phip); 01806 matrix[2][0] = sin(altp)*sin(azp); 01807 matrix[2][1] = -sin(altp)*cos(azp); 01808 matrix[2][2] = cos(altp); 01809 } 01810 if (is_quaternion){ 01811 matrix[0][0] = e0 * e0 + e1 * e1 - e2 * e2 - e3 * e3; 01812 matrix[0][1] = 2.0f * (e1 * e2 + e0 * e3); 01813 matrix[0][2] = 2.0f * (e1 * e3 - e0 * e2); 01814 matrix[1][0] = 2.0f * (e2 * e1 - e0 * e3); 01815 matrix[1][1] = e0 * e0 - e1 * e1 + e2 * e2 - e3 * e3; 01816 matrix[1][2] = 2.0f * (e2 * e3 + e0 * e1); 01817 matrix[2][0] = 2.0f * (e3 * e1 + e0 * e2); 01818 matrix[2][1] = 2.0f * (e3 * e2 - e0 * e1); 01819 matrix[2][2] = e0 * e0 - e1 * e1 - e2 * e2 + e3 * e3; 01820 // keep in mind matrix[0][2] is M13 gives an e0 e2 piece, etc 01821 } 01822 // Now do post and pretrans: vfinal = vpost + R vpre; 01823 01824 matrix[0][3] = postT[0] + matrix[0][0]*preT[0] + matrix[0][1]*preT[1] + matrix[0][2]*preT[2] ; 01825 matrix[1][3] = postT[1] + matrix[1][0]*preT[0] + matrix[1][1]*preT[1] + matrix[1][2]*preT[2] ; 01826 matrix[2][3] = postT[2] + matrix[2][0]*preT[0] + matrix[2][1]*preT[1] + matrix[2][2]*preT[2] ; 01827 }
void Transform3D::set_rotation | ( | const float & | m11, | |
const float & | m12, | |||
const float & | m13, | |||
const float & | m21, | |||
const float & | m22, | |||
const float & | m23, | |||
const float & | m31, | |||
const float & | m32, | |||
const float & | m33 | |||
) |
set the internal rotation matrix component wise
mij | the value to be placed in the internal transformation matrix at coordinate (i-1,j-1) |
Definition at line 1830 of file transform.cpp.
References MATRIX, and set_rotation().
01833 { 01834 EulerType euler_type = MATRIX; 01835 Dict rot; 01836 rot["m11"] = m11; 01837 rot["m12"] = m12; 01838 rot["m13"] = m13; 01839 rot["m21"] = m21; 01840 rot["m22"] = m22; 01841 rot["m23"] = m23; 01842 rot["m31"] = m31; 01843 rot["m32"] = m32; 01844 rot["m33"] = m33; 01845 set_rotation(euler_type, rot); // Or should it be &rot ? 01846 }
void Transform3D::set_rotation | ( | EulerType | euler_type, | |
const float & | a1, | |||
const float & | a2, | |||
const float & | a3, | |||
const float & | a4 | |||
) |
Set quaternion-based rotations Works for QUATERNION, SPIN and SGIROT.
euler_type | the Euler type either QUATERNION, SPIN or SGIROT | |
a1 | QUATERNION - e0, SPN and SGIROT - Omega | |
a2 | QUATERNION - e1, SPN and SGIROT - n1 | |
a3 | QUATERNION - e2, SPN and SGIROT - n2 | |
a4 | QUATERNION - e3, SPN and SGIROT - n3 |
Definition at line 1671 of file transform.cpp.
References init(), InvalidValueException, QUATERNION, set_rotation(), SGIROT, and SPIN.
01672 { 01673 init(); 01674 Dict rot; 01675 switch(euler_type) { 01676 case QUATERNION: 01677 rot["e0"] = a1; 01678 rot["e1"] = a2; 01679 rot["e2"] = a3; 01680 rot["e3"] = a4; 01681 break; 01682 case SGIROT: 01683 rot["q"] = a1; 01684 rot["n1"] = a2; 01685 rot["n2"] = a3; 01686 rot["n3"] = a4; 01687 case SPIN: 01688 rot["Omega"] = a1; 01689 rot["n1"] = a2; 01690 rot["n2"] = a3; 01691 rot["n3"] = a4; 01692 break; 01693 default: 01694 throw InvalidValueException(euler_type, "cannot instantiate this Euler Type"); 01695 } // ends switch euler_type 01696 set_rotation(euler_type, rot); 01697 }
void Transform3D::set_rotation | ( | EulerType | euler_type, | |
const float & | a1, | |||
const float & | a2, | |||
const float & | a3 | |||
) |
Sets the rotation as defined by the EulerType works for EMAN, SPIDER, MRC, IMAGIC and XYZ.
euler_type | the Euler type either EMAN, SPIDER, MRC, IMAGIC and XYZ | |
a1 | EMAN - az, SPIDER - phi, MRC - phi, IMAGIC - alpha, XYZ - xtilt | |
a2 | EMAN - alt, SPIDER - theta, MRC - theta, IMAGIC - beta, XYZ - ytilt | |
a3 | EMAN - phi, SPIDER - psi, MRC - omega, IMAGIC - gamma, XYZ - ztilt |
Definition at line 1634 of file transform.cpp.
References EMAN, IMAGIC, init(), InvalidValueException, MRC, set_rotation(), SPIDER, and XYZ.
01635 { 01636 init(); 01637 Dict rot; 01638 switch(euler_type) { 01639 case EMAN: 01640 rot["az"] = a1; 01641 rot["alt"] = a2; 01642 rot["phi"] = a3; 01643 break; 01644 case SPIDER: 01645 rot["phi"] = a1; 01646 rot["theta"] = a2; 01647 rot["psi"] = a3; 01648 break; 01649 case IMAGIC: 01650 rot["alpha"] = a1; 01651 rot["beta"] = a2; 01652 rot["gamma"] = a3; 01653 break; 01654 case MRC: 01655 rot["phi"] = a1; 01656 rot["theta"] = a2; 01657 rot["omega"] = a3; 01658 break; 01659 case XYZ: 01660 rot["xtilt"] = a1; 01661 rot["ytilt"] = a2; 01662 rot["ztilt"] = a3; 01663 break; 01664 default: 01665 throw InvalidValueException(euler_type, "cannot instantiate this Euler Type"); 01666 } // ends switch euler_type 01667 set_rotation(euler_type, rot); 01668 }
void Transform3D::set_rotation | ( | const float & | az, | |
const float & | alt, | |||
const float & | phi | |||
) |
A rotation is given by.
EMAN | cos phi sin phi 0 | | 1 0 0 | | cos az sin az 0 | |-sin phi cos phi 0 | | 0 cos alt sin alt | | -sin az cos az 0 | | 0 0 1 | | 0 -sin alt cos alt | | 0 0 1 |
---------------------------------------------------------------------------
SPIDER, FREEALIGN (th == theta) | cos psi sin psi 0 | | cos th 0 -sin th | | cos phi sin phi 0 | |-sin psi cos psi 0 | | 0 1 0 | | -sin phi cos phi 0 | | 0 0 1 | | sin th 0 cos th | | 0 0 1 |
Now this middle matrix is equal to
| 0 -1 0| |1 0 0 | | 0 1 0 | | 1 0 0| |0 cos th sin th | |-1 0 0 | | 0 0 1| |0 -sin th cos th | | 0 0 1 |
So we have
| sin psi -cos psi 0 | | 1 0 0 | | -sin phi cos phi 0 | | cos psi sin psi 0 | | 0 cos th sin th | | -cos phi -sin phi 0 | | 0 0 1 | | 0 -sin th cos th | | 0 0 1 |
so az = phi_SPIDER + pi/2 phi = psi - pi/2
---------------------------------------------------------------------------
MRC th=theta; om=omega ;
dwoolford says - this is wrong, the derivation of phi is the negative of the true result
| cos om sin om 0 | | cos th 0 -sin th | | cos phi sin phi 0 | |-sin om cos om 0 | | 0 1 0 | | -sin phi cos phi 0 | | 0 0 1 | | sin th 0 cos th | | 0 0 1 |
so az = phi + pi/2 alt = theta phi = omega - pi/2
--------------------------------------------------------------------------- For the quaternion type operations, we can start with
R = (1-nhat nhat) cos(Omega) - sin(Omega)nhat cross + nhat nhat Notice that this is a clockwise rotation( the xy component, for nhat=zhat, is calculated as - sin(Omega) xhat dot zhat cross yhat= sin(Omega): this is the correct sign for clockwise rotations). Now we develop
R = cos(Omega) one + nhat nhat (1-cos(Omega)) - sin(Omega) nhat cross = (cos^2(Omega/2) - sin^2(Omega/2)) one + 2 ((sin(Omega/2)nhat ) ((sin(Omega/2)nhat )
e0 = cos(Omega/2) vec{e} = sin(Omega/2) nhat
SGIrot is the same as SPIN (see paper) The update of rotations for quaternions is very easy.
Definition at line 1623 of file transform.cpp.
References EMAN.
Referenced by EMAN::PointArray::align_2d(), get_sym(), inverseUsingAngs(), set_rotation(), and Transform3D().
01624 { 01625 EulerType euler_type=EMAN; 01626 Dict rot; 01627 rot["az"] = az; 01628 rot["alt"] = alt; 01629 rot["phi"] = phi; 01630 set_rotation(euler_type, rot); 01631 }
void Transform3D::set_scale | ( | const float & | scale | ) |
FIXME insert comments.
Definition at line 1429 of file transform.cpp.
References apply_scale(), and get_scale().
Referenced by ali3d_d(), and EMAN::EMData::rotate_translate().
01430 { 01431 float OldScale= get_scale(); 01432 float Scale2Apply = scale/OldScale; 01433 apply_scale(Scale2Apply); 01434 }
void Transform3D::to_identity | ( | ) |
Definition at line 1281 of file transform.cpp.
References matrix, post_x_mirror, and set_center().
Referenced by init().
01282 { 01283 // for (int i = 0; i < 3; i++) { 01284 // matrix[i][i] = 1; 01285 // } 01286 01287 for(int i=0; i<4; ++i) { 01288 for(int j=0; j<4; ++j) { 01289 if(i==j) { 01290 matrix[i][j] = 1; 01291 } 01292 else { 01293 matrix[i][j] = 0; 01294 } 01295 } 01296 } 01297 post_x_mirror = false; 01298 set_center(Vec3f(0,0,0)); 01299 }
Perform a full transform a Vec3f using the internal transformation matrix.
v3f | the vector to be transformed |
Definition at line 1512 of file transform.cpp.
References matrix(), x, and y.
01513 { 01514 // This is the transformation of a vector, v by a matrix M 01515 float x = matrix[0][0] * v3f[0] + matrix[0][1] * v3f[1] + matrix[0][2] * v3f[2] + matrix[0][3] ; 01516 float y = matrix[1][0] * v3f[0] + matrix[1][1] * v3f[1] + matrix[1][2] * v3f[2] + matrix[1][3] ; 01517 float z = matrix[2][0] * v3f[0] + matrix[2][1] * v3f[1] + matrix[2][2] * v3f[2] + matrix[2][3] ; 01518 return Vec3f(x, y, z); 01519 }
void Transform3D::transpose | ( | ) |
create the transpose in place
Definition at line 1417 of file transform.cpp.
References matrix.
01418 { 01419 float tempij; 01420 for (int i = 0; i < 3; i++) { 01421 for (int j = 0; j < i; j++) { 01422 tempij= matrix[i][j]; 01423 matrix[i][j] = matrix[j][i]; 01424 matrix[j][i] = tempij; 01425 } 01426 } 01427 }
const float Transform3D::ERR_LIMIT = 0.000001f [static] |
float EMAN::Transform3D::matrix[4][4] [protected] |
Definition at line 866 of file transform.h.
Referenced by apply_scale(), at(), dsaw_zero_hack(), get_pretrans(), get_rotation(), get_scale(), inverse(), is_identity(), operator[](), printme(), set(), set_center(), set_posttrans(), set_pretrans(), set_rotation(), to_identity(), Transform3D(), and transpose().
bool EMAN::Transform3D::post_x_mirror [protected] |
Definition at line 868 of file transform.h.
Referenced by get_post_x_mirror(), set_post_x_mirror(), and to_identity().
Transform3D::EulerType EMAN::Transform3D::s [protected] |
Definition at line 870 of file transform.h.