Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

EMAN::Transform3D Class Reference
[unit test in Python]

Transform3D These are a collection of transformation tools: rotation, translation, and construction of symmetric objects. More...

#include <transform.h>

List of all members.

Public Types

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 &center)
 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

int get_nsym (const string &sym)
vector< Transform3D * > angles2tfvec (EulerType eulertype, const vector< float > angles)
 Convert a list of euler angles to a vector of Transform3D objects.

Static Public Attributes

const float ERR_LIMIT = 0.000001f

Protected Types

enum  SymType {
  CSYM, DSYM, TET_SYM, ICOS_SYM,
  OCT_SYM, ISYM, UNKNOWN_SYM
}

Protected Member Functions

void init ()

Static Protected Member Functions

SymType get_sym_type (const string &symname)

Protected Attributes

float matrix [4][4]
bool post_x_mirror
Transform3D::EulerType s


Detailed Description

Transform3D These are a collection of transformation tools: rotation, translation, and construction of symmetric objects.

Author:
Philip Baldwin <Philip.Baldwin@uth.tmc.edu> and Steven Ludtke
Date:
$Date: 2005/04/04 17:41pm
See also:
Phil's article Transform defines a transformation, which can be rotation, translation, scale, and their combinations.
Internally a transformation is stored in a 4x4 matrix. a b c d e f g h R v M= j k m n = vpre 1 , where R is 3by3, v is 3by1 p q r 1 The standard computer graphics convention is identical to ours after setting vpre to zero and can be found in many references including Frackowiak et al; Human Brain Function

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.


Member Enumeration Documentation

enum EMAN::Transform3D::EulerType
 

Enumeration values:
UNKNOWN 
EMAN 
IMAGIC 
SPIN 
QUATERNION 
SGIROT 
SPIDER 
MRC 
XYZ 
MATRIX 

Definition at line 554 of file transform.h.

Referenced by get_finger(), get_mag(), inverseUsingAngs(), and set_rotation().

00555                 {
00556                         UNKNOWN,
00557                         EMAN,
00558                         IMAGIC,
00559                         SPIN,
00560                         QUATERNION,
00561                         SGIROT,
00562                         SPIDER,
00563                         MRC,
00564                         XYZ,
00565                         MATRIX
00566                 };

enum EMAN::Transform3D::SymType [protected]
 

Enumeration values:
CSYM 
DSYM 
TET_SYM 
ICOS_SYM 
OCT_SYM 
ISYM 
UNKNOWN_SYM 

Definition at line 852 of file transform.h.

Referenced by get_nsym(), get_sym(), and get_sym_type().

00853                 {      CSYM,
00854                         DSYM,
00855                         TET_SYM,
00856                         ICOS_SYM,
00857                         OCT_SYM,
00858                         ISYM,
00859                         UNKNOWN_SYM
00860                 };


Constructor & Destructor Documentation

Transform3D::Transform3D  ) 
 

Default constructor Internal matrix is the identity.

Definition at line 1212 of file transform.cpp.

References init().

Referenced by angles2tfvec().

01213 {
01214         init();
01215 }

Transform3D::Transform3D const Transform3D rhs  ) 
 

Copy constructor.

Parameters:
rhs the object to be copied

Definition at line 1217 of file transform.cpp.

References matrix, and rhs.

01218 {
01219     for( int i=0; i < 4; ++i )
01220     {
01221         for( int j=0; j < 4; ++j )
01222         {
01223             matrix[i][j] = rhs.matrix[i][j];
01224         }
01225     }
01226 }

Transform3D::Transform3D const float &  az,
const float &  alt,
const float &  phi
 

Construct a Transform3D object describing a rotation, assuming the EMAN Euler type.

Parameters:
az EMAN - az
alt EMAN - alt
phi EMAN - phi

Definition at line 1229 of file transform.cpp.

References init(), phi, and set_rotation().

01230 {
01231         init();
01232         set_rotation(az,alt,phi);
01233 }

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.

Parameters:
az EMAN - az
alt EMAN - alt
phi EMAN - phi
posttrans the post translation vector

Definition at line 1237 of file transform.cpp.

References init(), phi, set_posttrans(), set_rotation(), and EMAN::Vec3f.

01238 {
01239         init(); // This is called in set_rotation
01240         set_rotation(az,alt,phi);
01241         set_posttrans(posttrans);
01242 }

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.

Parameters:
pretrans the pre translation vector
az EMAN - az
alt EMAN - alt
phi EMAN - phi
posttrans the post translation vector

Definition at line 1276 of file transform.cpp.

References init(), phi, set_posttrans(), set_pretrans(), set_rotation(), and EMAN::Vec3f.

01277 {
01278         init();
01279         set_pretrans(pretrans);
01280         set_rotation(az,alt,phi);
01281         set_posttrans(posttrans);
01282 }

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)

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 1253 of file transform.cpp.

References init(), and set_rotation().

01254 {
01255         init();
01256         set_rotation(euler_type,a1,a2,a3);
01257 }

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

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 1259 of file transform.cpp.

References init(), and set_rotation().

01260 {
01261         init();
01262         set_rotation(euler_type,a1,a2,a3,a4);
01263 }

Transform3D::Transform3D EulerType  euler_type,
const Dict rotation
 

Construct a Transform3D object consisting only of a rotation, using a specific Euler type.

Works for all Euler types

Parameters:
euler_type any Euler type
rotation a dictionary containing all key-entry pair required of the associated Euler type

Definition at line 1267 of file transform.cpp.

References init(), and set_rotation().

01268 {
01269         init();
01270         set_rotation(euler_type,rotation);
01271 }

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.

Parameters:
mij the value to be placed in the internal transformation matrix at coordinate (i-1,j-1)

Definition at line 1244 of file transform.cpp.

References init(), and set_rotation().

01247 {
01248         init();
01249         set_rotation(m11,m12,m13,m21,m22,m23,m31,m32,m33);
01250 }

Transform3D::~Transform3D  ) 
 

Destructor.

Definition at line 1287 of file transform.cpp.

01288 {
01289 }


Member Function Documentation

vector< Transform3D * > Transform3D::angles2tfvec EulerType  eulertype,
const vector< float >  angles
[static]
 

Convert a list of euler angles to a vector of Transform3D objects.

Parameters:
[in] eulertype The type of Euler angles that is being passed in.
[in] angles A flat vector of angles.
Returns:
Vector of pointers to Transform3D objects.

Definition at line 2372 of file transform.cpp.

References Transform3D().

02372                                                                       {
02373         int nangles = ang.size() / 3;
02374         vector<Transform3D*> tfvec;
02375         for (int i = 0; i < nangles; i++) {
02376                 tfvec.push_back(new Transform3D(eulertype,ang[3*i],ang[3*i+1],ang[3*i+2]));
02377         }
02378         return tfvec;
02379 }

void Transform3D::apply_scale const float &  scale  ) 
 

FIXME insert comments.

Definition at line 1406 of file transform.cpp.

References matrix.

Referenced by inverseUsingAngs(), orthogonalize(), and set_scale().

01407 {
01408         for (int i = 0; i < 3; i++) {
01409                 for (int j = 0; j < 4; j++) {
01410                         matrix[i][j] *= scale;
01411                 }
01412         }
01413         for (int j = 0; j < 3; j++) {
01414                 matrix[3][j] *= scale;
01415         }
01416 }

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 1506 of file transform.cpp.

References EMAN::Vec3f.

Referenced by EMAN::EMData::rotate_translate().

01507  {
01508         return Vec3f();
01509  }

Vec3f Transform3D::get_finger  )  const
 

returns the spin-axis (or finger) of the rotation

Definition at line 1455 of file transform.cpp.

References EulerType, get_rotation(), and EMAN::Vec3f.

01456 {
01457         EulerType eulertype= SPIN ;
01458         Dict AA= get_rotation(eulertype);
01459         return Vec3f(AA["n1"],AA["n2"],AA["n3"]);
01460 }

float Transform3D::get_mag  )  const
 

returns the magnitude of the rotation

Definition at line 1448 of file transform.cpp.

References EulerType, and get_rotation().

01449 {
01450         EulerType eulertype= SPIN ;
01451         Dict AA= get_rotation(eulertype);
01452         return AA["Omega"];
01453 }

Vec3f Transform3D::get_matrix3_col int  i  )  const
 

Get a matrix column as a Vec3f.

Parameters:
i the column number (starting at 0)
Returns:
the ith column

Definition at line 1513 of file transform.cpp.

References matrix(), and EMAN::Vec3f.

01514 {
01515         return Vec3f(matrix[0][i], matrix[1][i], matrix[2][i]);
01516 }

Vec3f Transform3D::get_matrix3_row int  i  )  const
 

Get a matrix row as a Vec3f.

Parameters:
i the row number (starting at 0)
Returns:
the ith row

Definition at line 1519 of file transform.cpp.

References matrix(), and EMAN::Vec3f.

01520 {
01521         return Vec3f(matrix[i][0], matrix[i][1], matrix[i][2]);
01522 }

int Transform3D::get_nsym const string &  sym  )  [static]
 

Definition at line 2305 of file transform.cpp.

References CSYM, DSYM, get_sym_type(), ICOS_SYM, InvalidValueException, ISYM, OCT_SYM, SymType, 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().

02306 {
02307         string symname = name;
02308 
02309         for (size_t i = 0; i < name.size(); i++) {
02310                 if (isalpha(name[i])) {
02311                         symname[i] = (char)tolower(name[i]);
02312                 }
02313         }
02314 
02315         SymType type = get_sym_type(symname);
02316         int nsym = 0;
02317 
02318         switch (type) {
02319         case CSYM:
02320                 nsym = atoi(symname.c_str() + 1);
02321                 break;
02322         case DSYM:
02323                 nsym = atoi(symname.c_str() + 1) * 2;
02324                 break;
02325         case ICOS_SYM:
02326                 nsym = 60;
02327                 break;
02328         case OCT_SYM:
02329                 nsym = 24;
02330                 break;
02331         case TET_SYM:
02332                 nsym = 12;
02333                 break;
02334         case ISYM:
02335                 nsym = 1;
02336                 break;
02337         case UNKNOWN_SYM:
02338         default:
02339                 throw InvalidValueException(type, name);
02340         }
02341         return nsym;
02342 }

bool EMAN::Transform3D::get_post_x_mirror  )  const [inline]
 

Definition at line 822 of file transform.h.

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

Parameters:
flag if 0 returns the post translation vector, if 1 all translation is treated as post
Returns:
the translation vector

Definition at line 1462 of file transform.cpp.

References flag, matrix(), and EMAN::Vec3f.

Referenced by get_total_posttrans(), inverse(), inverseUsingAngs(), EMAN::EMData::rotate_translate(), and set_rotation().

01463 {
01464         if (flag==0){
01465                 return Vec3f(matrix[3][0], matrix[3][1], matrix[3][2]);
01466         }
01467         // otherwise as if all the translation was post
01468         return Vec3f(matrix[0][3], matrix[1][3], matrix[2][3]);
01469 }

Vec3f Transform3D::get_pretrans int  flag = 0  )  const
 

Gets one of two pre translation vectors.

Parameters:
flag if 0 returns the pre translation vector, if 1 all translation is treated as pre
Returns:
the translation vector

Definition at line 1480 of file transform.cpp.

References flag, matrix, matrix(), EMAN::Vec3< Type >::set_value_at(), and EMAN::Vec3f.

Referenced by get_total_pretrans(), inverseUsingAngs(), set_posttrans(), and set_rotation().

01481 {
01482 //      The expression is R^T(v_total - v_post);
01483 
01484         Vec3f pretrans;
01485         Vec3f posttrans(matrix[3][0], matrix[3][1], matrix[3][2]);
01486         Vec3f tottrans(matrix[0][3], matrix[1][3], matrix[2][3]);
01487         Vec3f totminuspost;
01488 
01489         totminuspost = tottrans;
01490         if (flag==0) {
01491                 totminuspost = tottrans-posttrans;
01492         }
01493 
01494         Transform3D Rinv = inverse();
01495         for (int i=0; i<3; i++) {
01496                 float ptnow=0;
01497                 for (int j=0; j<3; j++) {
01498                         ptnow +=   Rinv.matrix[i][j]* totminuspost[j] ;
01499                 }
01500                 pretrans.set_value_at(i,ptnow) ;  //
01501         }
01502         return pretrans;
01503 }

Dict Transform3D::get_rotation EulerType  euler_type = EMAN  )  const
 

Get a rotation in any Euler format.

Parameters:
euler_type the requested Euler type
Returns:
a dictionary containing the key-entry pairs describing the rotations in terms of the requested Euler type

Definition at line 1932 of file transform.cpp.

References EMAN, get_scale(), IMAGIC, InvalidValueException, MATRIX, matrix, max, MRC, phi, QUATERNION, 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().

01933 {
01934         Dict result;
01935 
01936         float max = 1 - ERR_LIMIT;
01937         float sca=get_scale();
01938         float cosalt=matrix[2][2]/sca;
01939 
01940 
01941         float az=0;
01942         float alt = 0;
01943         float phi=0;
01944         float phiS = 0; // like az   (but in SPIDER ZXZ)
01945         float psiS =0;  // like phi  (but in SPIDER ZYZ)
01946 
01947 
01948 // get alt, az, phi;  EMAN
01949 
01950         if (cosalt > max) {  // that is, alt close to 0
01951                 alt = 0;
01952                 az=0;
01953                 phi = (float)EMConsts::rad2deg*(float)atan2(matrix[0][1], matrix[0][0]);
01954         }
01955         else if (cosalt < -max) { // alt close to pi
01956                 alt = 180;
01957                 az=0;
01958                 phi=360.0f-(float)EMConsts::rad2deg*(float)atan2(matrix[0][1], matrix[0][0]);
01959         }
01960         else {
01961                 alt = (float)EMConsts::rad2deg*(float) acos(cosalt);
01962                 az  = 360.0f+(float)EMConsts::rad2deg*(float)atan2(matrix[2][0], -matrix[2][1]);
01963                 phi = 360.0f+(float)EMConsts::rad2deg*(float)atan2(matrix[0][2], matrix[1][2]);
01964         }
01965         az=fmod(az+180.0f,360.0f)-180.0f;
01966         phi=fmod(phi+180.0f,360.0f)-180.0f;
01967 
01968 //   get phiS, psiS ; SPIDER
01969         if (fabs(cosalt) > max) {  // that is, alt close to 0
01970                 phiS=0;
01971                 psiS = az+phi;
01972         }
01973         else {
01974                 phiS = az   - 90.0f;
01975                 psiS = phi  + 90.0f;
01976         }
01977         phiS = fmod((phiS   + 360.0f ), 360.0f) ;
01978         psiS = fmod((psiS   + 360.0f ), 360.0f) ;
01979 
01980 //   do some quaternionic stuff here
01981 
01982         float nphi = (az-phi)/2.0f;
01983     // The next is also e0
01984         float cosOover2 = (cos((az+phi)*M_PI/360) * cos(alt*M_PI/360)) ;
01985         float sinOover2 = sqrt(1 -cosOover2*cosOover2);
01986         float cosnTheta = sin((az+phi)*M_PI/360) * cos(alt*M_PI/360) / sqrt(1-cosOover2*cosOover2) ;
01987         float sinnTheta = sqrt(1-cosnTheta*cosnTheta);
01988         float n1 = sinnTheta*cos(nphi*M_PI/180);
01989         float n2 = sinnTheta*sin(nphi*M_PI/180);
01990         float n3 = cosnTheta;
01991         float xtilt = 0;
01992         float ytilt = 0;
01993         float ztilt = 0;
01994 
01995 
01996         if (cosOover2<0) {
01997                 cosOover2*=-1; n1 *=-1; n2*=-1; n3*=-1;
01998         }
01999 
02000 
02001         switch (euler_type) {
02002         case EMAN:
02003                 result["az"]  = az;
02004                 result["alt"] = alt;
02005                 result["phi"] = phi;
02006                 break;
02007 
02008         case IMAGIC:
02009                 result["alpha"] = az;
02010                 result["beta"] = alt;
02011                 result["gamma"] = phi;
02012                 break;
02013 
02014         case SPIDER:
02015                 result["phi"]   = phiS;  // The first Euler like az
02016                 result["theta"] = alt;
02017                 result["psi"]   = psiS;
02018                 break;
02019 
02020         case MRC:
02021                 result["phi"]   = phiS;
02022                 result["theta"] = alt;
02023                 result["omega"] = psiS;
02024                 break;
02025 
02026         case XYZ:
02027                 xtilt = atan2(-sin((M_PI/180.0f)*phiS)*sin((M_PI/180.0f)*alt),cos((M_PI/180.0f)*alt));
02028                 ytilt = asin(  cos((M_PI/180.0f)*phiS)*sin((M_PI/180.0f)*alt));
02029                 ztilt = psiS*M_PI/180.0f - atan2(sin(xtilt), cos(xtilt) *sin(ytilt));
02030 
02031                 xtilt=fmod(xtilt*180/M_PI+540.0f,360.0f) -180.0f;
02032                 ztilt=fmod(ztilt*180/M_PI+540.0f,360.0f) -180.0f;
02033 
02034                 result["xtilt"]  = xtilt;
02035                 result["ytilt"]  = ytilt*180/M_PI;
02036                 result["ztilt"]  = ztilt;
02037                 break;
02038 
02039         case QUATERNION:
02040                 result["e0"] = cosOover2 ;
02041                 result["e1"] = sinOover2 * n1 ;
02042                 result["e2"] = sinOover2 * n2;
02043                 result["e3"] = sinOover2 * n3;
02044                 break;
02045 
02046         case SPIN:
02047                 result["Omega"] =360.0f* acos(cosOover2)/ M_PI ;
02048                 result["n1"] = n1;
02049                 result["n2"] = n2;
02050                 result["n3"] = n3;
02051                 break;
02052 
02053         case SGIROT:
02054                 result["q"] = 360.0f*acos(cosOover2)/M_PI ;
02055                 result["n1"] = n1;
02056                 result["n2"] = n2;
02057                 result["n3"] = n3;
02058                 break;
02059 
02060         case MATRIX:
02061                 result["m11"] = matrix[0][0] ;
02062                 result["m12"] = matrix[0][1] ;
02063                 result["m13"] = matrix[0][2] ;
02064                 result["m21"] = matrix[1][0] ;
02065                 result["m22"] = matrix[1][1] ;
02066                 result["m23"] = matrix[1][2] ;
02067                 result["m31"] = matrix[2][0] ;
02068                 result["m32"] = matrix[2][1] ;
02069                 result["m33"] = matrix[2][2] ;
02070                 break;
02071 
02072         default:
02073                 throw InvalidValueException(euler_type, "unknown Euler Type");
02074         }
02075 
02076         return result;
02077 }

float Transform3D::get_scale  )  const
 

Definition at line 1917 of file transform.cpp.

References matrix, and sqrt().

Referenced by ali3d_d(), get_rotation(), inverseUsingAngs(), orthogonalize(), EMAN::EMData::rotate_translate(), and set_scale().

01918 {
01919         // Assumes uniform scaling, calculation uses Z only.
01920         float scale =0;
01921         for (int i=0; i<3; i++) {
01922                 for (int j=0; j<3; j++) {
01923                         scale = scale + matrix[i][j]*matrix[i][j];
01924                 }
01925         }
01926 
01927         return sqrt(scale/3);
01928 }

Transform3D Transform3D::get_sym const string &  sym,
int  n
const
 

Definition at line 2171 of file transform.cpp.

References CSYM, DSYM, get_nsym(), get_sym_type(), ICOS_SYM, InvalidValueException, ISYM, OCT_SYM, set_rotation(), SymType, and TET_SYM.

Referenced by LBD_Cart(), recons3d_CGLS_mpi_Cart(), recons3d_sirt_mpi(), recons3d_sirt_mpi_Cart(), and EMAN::PointArray::set_from().

02172 {
02173         int nsym = get_nsym(symname);
02174 
02175 //      Transform3D invalid;
02176 //      invalid.set_rotation( -0.1f, -0.1f, -0.1f);
02177 
02178         // see www.math.utah.edu/~alfeld/math/polyhedra/polyhedra.html for pictures
02179         // By default we will put largest symmetry along z-axis.
02180 
02181         // Each Platonic Solid has 2E symmetry elements.
02182 
02183 
02184         // An icosahedron has   m=5, n=3, F=20 E=30=nF/2, V=12=nF/m,since vertices shared by 5 triangles;
02185         // It is composed of 20 triangles. E=3*20/2;
02186 
02187 
02188         // An dodecahedron has m=3, n=5   F=12 E=30  V=20
02189         // It is composed of 12 pentagons. E=5*12/2;   V= 5*12/3, since vertices shared by 3 pentagons;
02190 
02191 
02192 
02193     // The ICOS symmetry group has the face along z-axis
02194 
02195         float lvl0=0;                             //  there is one pentagon on top; five-fold along z
02196         float lvl1= 63.4349f; // that is atan(2)  // there are 5 pentagons with centers at this height (angle)
02197         float lvl2=116.5651f; //that is 180-lvl1  // there are 5 pentagons with centers at this height (angle)
02198         float lvl3=180.f;                           // there is one pentagon on the bottom
02199              // Notice that 63.439 is the angle between two faces of the dual object
02200 
02201         static double ICOS[180] = { // This is with a pentagon normal to z
02202                   0,lvl0,0,    0,lvl0,288,   0,lvl0,216,   0,lvl0,144,  0,lvl0,72,
02203                   0,lvl1,36,   0,lvl1,324,   0,lvl1,252,   0,lvl1,180,  0,lvl1,108,
02204                  72,lvl1,36,  72,lvl1,324,  72,lvl1,252,  72,lvl1,180,  72,lvl1,108,
02205                 144,lvl1,36, 144,lvl1,324, 144,lvl1,252, 144,lvl1,180, 144,lvl1,108,
02206                 216,lvl1,36, 216,lvl1,324, 216,lvl1,252, 216,lvl1,180, 216,lvl1,108,
02207                 288,lvl1,36, 288,lvl1,324, 288,lvl1,252, 288,lvl1,180, 288,lvl1,108,
02208                  36,lvl2,0,   36,lvl2,288,  36,lvl2,216,  36,lvl2,144,  36,lvl2,72,
02209                 108,lvl2,0,  108,lvl2,288, 108,lvl2,216, 108,lvl2,144, 108,lvl2,72,
02210                 180,lvl2,0,  180,lvl2,288, 180,lvl2,216, 180,lvl2,144, 180,lvl2,72,
02211                 252,lvl2,0,  252,lvl2,288, 252,lvl2,216, 252,lvl2,144, 252,lvl2,72,
02212                 324,lvl2,0,  324,lvl2,288, 324,lvl2,216, 324,lvl2,144, 324,lvl2,72,
02213                   0,lvl3,0,    0,lvl3,288,   0,lvl3,216,   0,lvl3,144,   0,lvl3,72
02214         };
02215 
02216 
02217         // A cube has   m=3, n=4, F=6 E=12=nF/2, V=8=nF/m,since vertices shared by 3 squares;
02218         // It is composed of 6 squares.
02219 
02220 
02221         // An octahedron has   m=4, n=3, F=8 E=12=nF/2, V=6=nF/m,since vertices shared by 4 triangles;
02222         // It is composed of 8 triangles.
02223 
02224     // We have placed the OCT symmetry group with a face along the z-axis
02225         lvl0=0;
02226         lvl1=90;
02227         lvl2=180;
02228 
02229         static float OCT[72] = {// This is with a face of a cube along z
02230                       0,lvl0,0,   0,lvl0,90,    0,lvl0,180,    0,lvl0,270,
02231                       0,lvl1,0,   0,lvl1,90,    0,lvl1,180,    0,lvl1,270,
02232                      90,lvl1,0,  90,lvl1,90,   90,lvl1,180,   90,lvl1,270,
02233                     180,lvl1,0, 180,lvl1,90,  180,lvl1,180,  180,lvl1,270,
02234                     270,lvl1,0, 270,lvl1,90,  270,lvl1,180,  270,lvl1,270,
02235                       0,lvl2,0,   0,lvl2,90,    0,lvl2,180,    0,lvl2,270
02236         };
02237         // B^4=A^3=1;  BABA=1; implies   AA=BAB, ABA=B^3 , AB^2A = BBBABBB and
02238         //   20 words with at most a single A
02239     //   1 B BB BBB A  BA AB BBA BAB ABB BBBA BBAB BABB ABBB BBBAB BBABB BABBB
02240     //                        BBBABB BBABBB BBBABBB
02241      // also     ABBBA is distinct yields 4 more words
02242      //    ABBBA   BABBBA BBABBBA BBBABBBA
02243      // for a total of 24 words
02244      // Note A BBB A BBB A  reduces to BBABB
02245      //  and  B A BBB A is the same as A BBB A BBB etc.
02246 
02247     // The TET symmetry group has a face along the z-axis
02248     // It has n=m=3; F=4, E=6=nF/2, V=4=nF/m
02249         lvl0=0;         // There is a face along z
02250         lvl1=109.4712f;  //  that is acos(-1/3)  // There  are 3 faces at this angle
02251 
02252         static float TET[36] = {// This is with the face along z
02253               0,lvl0,0,   0,lvl0,120,    0,lvl0,240,
02254               0,lvl1,60,   0,lvl1,180,    0,lvl1,300,
02255             120,lvl1,60, 120,lvl1,180,  120,lvl1,300,
02256             240,lvl1,60, 240,lvl1,180,  240,lvl1,300
02257         };
02258         // B^3=A^3=1;  BABA=1; implies   A^2=BAB, ABA=B^2 , AB^2A = B^2AB^2 and
02259         //   12 words with at most a single A
02260     //   1 B BB  A  BA AB BBA BAB ABB BBAB BABB BBABB
02261     // at most one A is necessary
02262 
02263         Transform3D ret;
02264         SymType type = get_sym_type(symname);
02265 
02266         switch (type) {
02267         case CSYM:
02268                 ret.set_rotation( n * 360.0f / nsym, 0, 0);
02269                 break;
02270         case DSYM:
02271                 if (n >= nsym / 2) {
02272                         ret.set_rotation((n - nsym/2) * 360.0f / (nsym / 2),180.0f, 0);
02273                 }
02274                 else {
02275                         ret.set_rotation( n * 360.0f / (nsym / 2),0, 0);
02276                 }
02277                 break;
02278         case ICOS_SYM:
02279                 ret.set_rotation((float)ICOS[n * 3 ],
02280                                  (float)ICOS[n * 3 + 1],
02281                                  (float)ICOS[n * 3 + 2] );
02282                 break;
02283         case OCT_SYM:
02284                 ret.set_rotation((float)OCT[n * 3],
02285                                  (float)OCT[n * 3 + 1],
02286                                  (float)OCT[n * 3 + 2] );
02287                 break;
02288         case TET_SYM:
02289                 ret.set_rotation((float)TET[n * 3 ],
02290                                  (float)TET[n * 3 + 1] ,
02291                                  (float)TET[n * 3 + 2] );
02292                 break;
02293         case ISYM:
02294                 ret.set_rotation(0, 0, 0);
02295                 break;
02296         default:
02297                 throw InvalidValueException(type, symname);
02298         }
02299 
02300         ret = (*this) * ret;
02301 
02302         return ret;
02303 }

Transform3D::SymType Transform3D::get_sym_type const string &  symname  )  [static, protected]
 

Definition at line 2346 of file transform.cpp.

References SymType, and t.

Referenced by get_nsym(), and get_sym().

02347 {
02348         SymType t = UNKNOWN_SYM;
02349 
02350         if (name[0] == 'c') {
02351                 t = CSYM;
02352         }
02353         else if (name[0] == 'd') {
02354                 t = DSYM;
02355         }
02356         else if (name == "icos") {
02357                 t = ICOS_SYM;
02358         }
02359         else if (name == "oct") {
02360                 t = OCT_SYM;
02361         }
02362         else if (name == "tet") {
02363                 t = TET_SYM;
02364         }
02365         else if (name == "i" || name == "") {
02366                 t = ISYM;
02367         }
02368         return t;
02369 }

Vec3f Transform3D::get_total_posttrans  )  const
 

Get the total translation as a post translation.

Calls get_postrans(1)

Returns:
the translation vector

Definition at line 1471 of file transform.cpp.

References get_posttrans(), and EMAN::Vec3f.

01471                                              {
01472         return get_posttrans(1);
01473 }

Vec3f Transform3D::get_total_pretrans  )  const
 

Get the total translation as a pre translation.

Calls get_pretrans(1)

Returns:
the translation vector

Definition at line 1475 of file transform.cpp.

References get_pretrans(), and EMAN::Vec3f.

01475                                             {
01476         return get_pretrans(1);
01477 }

void Transform3D::init  )  [protected]
 

Definition at line 1337 of file transform.cpp.

References to_identity().

Referenced by set_rotation(), and Transform3D().

01338 {
01339         to_identity();
01340 }

Transform3D Transform3D::inverse  )  const
 

FIXME insert comments.

Definition at line 2116 of file transform.cpp.

References get_posttrans(), matrix, v0, and EMAN::Vec3f.

Referenced by EMAN::EMData::rotate_translate().

02117 {
02118         // This assumes the matrix is 4 by 4 and the last row reads [0 0 0 1]
02119 
02120         float m00 = matrix[0][0]; float m01=matrix[0][1]; float m02=matrix[0][2];
02121         float m10 = matrix[1][0]; float m11=matrix[1][1]; float m12=matrix[1][2];
02122         float m20 = matrix[2][0]; float m21=matrix[2][1]; float m22=matrix[2][2];
02123         float v0  = matrix[0][3]; float v1 =matrix[1][3]; float v2 =matrix[2][3];
02124 
02125     float cof00 = m11*m22-m12*m21;
02126     float cof11 = m22*m00-m20*m02;
02127     float cof22 = m00*m11-m01*m10;
02128     float cof01 = m10*m22-m20*m12;
02129     float cof02 = m10*m21-m20*m11;
02130     float cof12 = m00*m21-m01*m20;
02131     float cof10 = m01*m22-m02*m21;
02132     float cof20 = m01*m12-m02*m11;
02133     float cof21 = m00*m12-m10*m02;
02134 
02135     float Det = m00* cof00 + m02* cof02 -m01*cof01;
02136 
02137     Transform3D invM;
02138 
02139     invM.matrix[0][0] =   cof00/Det;
02140     invM.matrix[0][1] = - cof10/Det;
02141     invM.matrix[0][2] =   cof20/Det;
02142     invM.matrix[1][0] = - cof01/Det;
02143     invM.matrix[1][1] =   cof11/Det;
02144     invM.matrix[1][2] = - cof21/Det;
02145     invM.matrix[2][0] =   cof02/Det;
02146     invM.matrix[2][1] = - cof12/Det;
02147     invM.matrix[2][2] =   cof22/Det;
02148 
02149     invM.matrix[0][3] =  (- cof00*v0 + cof10*v1 - cof20*v2 )/Det;
02150     invM.matrix[1][3] =  (  cof01*v0 - cof11*v1 + cof21*v2 )/Det;
02151     invM.matrix[2][3] =  (- cof02*v0 + cof12*v1 - cof22*v2 )/Det;
02152 
02153         Vec3f postT   = get_posttrans( ) ;
02154         Vec3f invMpre   = - postT;
02155         Vec3f invMpost   ;
02156         for ( int i = 0; i < 3; i++) {
02157                 invMpost[i] = invM.matrix[i][3];
02158                 for ( int j = 0; j < 3; j++) {
02159                         invMpost[i] += - invM.matrix[i][j]*invMpre[j];
02160                 }
02161                 invM.matrix[3][i] = invMpost[i];
02162         }
02163 
02164         return invM;
02165 }

Transform3D Transform3D::inverseUsingAngs  )  const
 

FIXME insert comments.

Definition at line 2079 of file transform.cpp.

References apply_scale(), EMAN, EulerType, get_posttrans(), get_pretrans(), get_rotation(), get_scale(), set_posttrans(), set_pretrans(), set_rotation(), and EMAN::Vec3f.

02080 {
02081         // First Find the scale
02082         EulerType eE=EMAN;
02083 
02084 
02085         float scale   = get_scale();
02086         Vec3f preT   = get_pretrans( ) ;
02087         Vec3f postT   = get_posttrans( ) ;
02088         Dict angs     = get_rotation(eE);
02089         Dict invAngs  ;
02090 
02091         invAngs["phi"]   = 180.0f - (float) angs["az"] ;
02092         invAngs["az"]    = 180.0f - (float) angs["phi"] ;
02093         invAngs["alt"]   = angs["alt"] ;
02094 
02095 //    The inverse result
02096 //
02097 //           Z_phi   X_alt     Z_az
02098 //                 is
02099 //       Z_{pi-az}   X_alt  Z_{pi-phi}
02100 //      The reason for the extra pi's, is because one would like to keep alt positive
02101 
02102         float inverseScale= 1/scale ;
02103 
02104         Transform3D invM;
02105 
02106         invM.set_rotation(EMAN, invAngs);
02107         invM.apply_scale(inverseScale);
02108         invM.set_pretrans(-postT );
02109         invM.set_posttrans(-preT );
02110 
02111 
02112         return invM;
02113 
02114 }

bool Transform3D::is_identity  ) 
 

Definition at line 1315 of file transform.cpp.

References matrix.

01316 {
01317         for (int i=0; i<4; i++) {
01318                 for (int j=0; j<4; j++) {
01319                         if (i==j && matrix[i][j]!=1.0) return 0;
01320                         if (i!=j && matrix[i][j]!=0.0) return 0;
01321                 }
01322         }
01323         return 1;
01324 }

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 1418 of file transform.cpp.

References apply_scale(), and get_scale().

01419 {
01420         //EulerType EMAN;
01421         float scale = get_scale() ;
01422         float inverseScale= 1/scale ;
01423         apply_scale(inverseScale);
01424 //      Dict angs = get_rotation(EMAN);
01425 //      set_Rotation(EMAN,angs);
01426 }

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                 }

Vec3f Transform3D::rotate const Vec3f v3f  )  const
 

Rotate a Vec3f using the internal rotation matrix.

Parameters:
v3f the vector to be rotated
Returns:
the rotated vector

Definition at line 1534 of file transform.cpp.

References matrix(), EMAN::Vec3f, x, and y.

01535 {
01536 //      This is the rotation of a vector, v by a matrix M
01537         float x = matrix[0][0] * v3f[0] + matrix[0][1] * v3f[1] + matrix[0][2] * v3f[2]  ;
01538         float y = matrix[1][0] * v3f[0] + matrix[1][1] * v3f[1] + matrix[1][2] * v3f[2]  ;
01539         float z = matrix[2][0] * v3f[0] + matrix[2][1] * v3f[1] + matrix[2][2] * v3f[2]  ;
01540         return Vec3f(x, y, z);
01541 }

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 1327 of file transform.cpp.

References matrix, set_pretrans(), and EMAN::Vec3f.

Referenced by to_identity().

01328 {
01329         set_pretrans( Vec3f(0,0,0)-center);
01330         for (int i = 0; i < 3; i++) {
01331                 matrix[i][3]=center[i];
01332         }
01333 }

void EMAN::Transform3D::set_post_x_mirror const bool  b  )  [inline]
 

Definition at line 821 of file transform.h.

00821 { post_x_mirror = b; }

void Transform3D::set_posttrans const Vec2f posttrans  ) 
 

Definition at line 1381 of file transform.cpp.

References set_pretrans(), EMAN::Vec2f, and EMAN::Vec3f.

01382 {    set_pretrans( Vec3f(posttrans[0],posttrans[1],0)); }

void Transform3D::set_posttrans const float &  dx,
const float &  dy
 

Definition at line 1378 of file transform.cpp.

References set_posttrans(), and EMAN::Vec3f.

01379 {    set_posttrans( Vec3f(dx,dy,0)); }

void Transform3D::set_posttrans const float &  dx,
const float &  dy,
const float &  dz
 

Definition at line 1374 of file transform.cpp.

References set_posttrans(), and EMAN::Vec3f.

01375 {    set_posttrans( Vec3f(dx,dy,dz)); }

void Transform3D::set_posttrans const Vec3f posttrans  ) 
 

Definition at line 1384 of file transform.cpp.

References flag, get_pretrans(), matrix, and EMAN::Vec3f.

Referenced by ali3d_d(), inverseUsingAngs(), set_posttrans(), and Transform3D().

01385 {
01386         int flag=0;
01387     Vec3f preT   = get_pretrans(0) ;
01388         for (int i = 0; i < 3; i++) {
01389                 matrix[3][i] = posttrans[i];
01390         }
01391 //     transFinal = transPost +  Rotation * transPre;
01392 //   This will keep the old value of pretrans and change the value of posttrans and the total matrix
01393         if (flag==0) {
01394                 matrix[0][3] = matrix[3][0] + matrix[0][0]*preT[0] + matrix[0][1]*preT[1] + matrix[0][2]*preT[2]  ;
01395                 matrix[1][3] = matrix[3][1] + matrix[1][0]*preT[0] + matrix[1][1]*preT[1] + matrix[1][2]*preT[2]  ;
01396                 matrix[2][3] = matrix[3][2] + matrix[2][0]*preT[0] + matrix[2][1]*preT[1] + matrix[2][2]*preT[2]  ;
01397         }
01398 //   This will keep the old value of the total matrix, and c
01399         if (flag==1) { // Don't do anything
01400         }
01401 }

void Transform3D::set_pretrans const Vec2f pretrans  ) 
 

Definition at line 1351 of file transform.cpp.

References set_pretrans(), EMAN::Vec2f, and EMAN::Vec3f.

01352 {    set_pretrans( Vec3f(pretrans[0],pretrans[1],0)); }

void Transform3D::set_pretrans const float &  dx,
const float &  dy
 

Definition at line 1348 of file transform.cpp.

References set_pretrans(), and EMAN::Vec3f.

01349 {    set_pretrans( Vec3f(dx,dy,0)); }

void Transform3D::set_pretrans const float &  dx,
const float &  dy,
const float &  dz
 

Definition at line 1344 of file transform.cpp.

References set_pretrans(), and EMAN::Vec3f.

01345 {    set_pretrans( Vec3f(dx,dy,dz)); }

void Transform3D::set_pretrans const Vec3f pretrans  ) 
 

Definition at line 1354 of file transform.cpp.

References flag, matrix, and EMAN::Vec3f.

Referenced by EMAN::PointArray::align_2d(), inverseUsingAngs(), set_center(), set_posttrans(), set_pretrans(), and Transform3D().

01355 {
01356                 int flag=0;
01357 
01358 //     transFinal = transPost +  Rotation * transPre;
01359 //    This will keep the old value of transPost and change the value of pretrans and the total matrix
01360     if (flag==0){
01361                 matrix[0][3] = matrix[3][0] + matrix[0][0]*preT[0] + matrix[0][1]*preT[1] + matrix[0][2]*preT[2]  ;
01362                 matrix[1][3] = matrix[3][1] + matrix[1][0]*preT[0] + matrix[1][1]*preT[1] + matrix[1][2]*preT[2]  ;
01363                 matrix[2][3] = matrix[3][2] + matrix[2][0]*preT[0] + matrix[2][1]*preT[1] + matrix[2][2]*preT[2]  ;
01364         }
01365 //    This will keep the old value of total translation and change the value of posttrans
01366     if (flag==1){
01367                 matrix[3][0] = matrix[0][3] - (matrix[0][0]*preT[0] + matrix[0][1]*preT[1] + matrix[0][2]*preT[2])  ;
01368                 matrix[3][1] = matrix[1][3] - (matrix[1][0]*preT[0] + matrix[1][1]*preT[1] + matrix[1][2]*preT[2])  ;
01369                 matrix[3][2] = matrix[2][3] - (matrix[2][0]*preT[0] + matrix[2][1]*preT[1] + matrix[2][2]*preT[2])  ;
01370         }
01371 }

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

Parameters:
eahat,ebhat,eAhat,eBhat are all unit vectors
Returns:
a transform3D rotation

Definition at line 1860 of file transform.cpp.

References EMAN::Vec3< Type >::cross(), EMAN::Vec3< Type >::dot(), EulerType, EMAN::Vec3< Type >::length(), EMAN::Vec3< Type >::normalize(), set_rotation(), and EMAN::Vec3f.

01862 {// this rotation rotates unit vectors a,b into A,B;
01863 //    The program assumes a dot b must equal A dot B
01864         Vec3f eahatcp(eahat);
01865         Vec3f ebhatcp(ebhat);
01866         Vec3f eAhatcp(eAhat);
01867         Vec3f eBhatcp(eBhat);
01868 
01869         eahatcp.normalize();
01870         ebhatcp.normalize();
01871         eAhatcp.normalize();
01872         eBhatcp.normalize();
01873 
01874         Vec3f aMinusA(eahatcp);
01875         aMinusA  -= eAhatcp;
01876         Vec3f bMinusB(ebhatcp);
01877         bMinusB  -= eBhatcp;
01878 
01879 
01880         Vec3f  nhat;
01881         float aAlength = aMinusA.length();
01882         float bBlength = bMinusB.length();
01883         if (aAlength==0){
01884                 nhat=eahatcp;
01885         }else if (bBlength==0){
01886                 nhat=ebhatcp;
01887         }else{
01888                 nhat= aMinusA.cross(bMinusB);
01889                 nhat.normalize();
01890         }
01891 
01892 //              printf("nhat=%f,%f,%f \n",nhat[0],nhat[1],nhat[2]);
01893 
01894         Vec3f neahat  = eahatcp.cross(nhat);
01895         Vec3f nebhat  = ebhatcp.cross(nhat);
01896         Vec3f neAhat  = eAhatcp.cross(nhat);
01897         Vec3f neBhat  = eBhatcp.cross(nhat);
01898 
01899         float cosOmegaA = (neahat.dot(neAhat))  / (neahat.dot(neahat));
01900 //      float cosOmegaB = (nebhat.dot(neBhat))  / (nebhat.dot(nebhat));
01901         float sinOmegaA = (neahat.dot(eAhatcp)) / (neahat.dot(neahat));
01902 //      printf("cosOmegaA=%f \n",cosOmegaA);    printf("sinOmegaA=%f \n",sinOmegaA);
01903 
01904         float OmegaA = atan2(sinOmegaA,cosOmegaA);
01905 //      printf("OmegaA=%f \n",OmegaA*180/M_PI);
01906 
01907         EulerType euler_type=SPIN;
01908         Dict rotation;
01909         rotation["n1"]= nhat[0];
01910         rotation["n2"]= nhat[1];
01911         rotation["n3"]= nhat[2];
01912         rotation["Omega"] =OmegaA*180.0/M_PI;
01913         set_rotation(euler_type,  rotation);
01914 }

void Transform3D::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.

Parameters:
euler_type any Euler type
rotation a dictionary containing all key-entry pair required of the associated Euler type

Definition at line 1711 of file transform.cpp.

References EMAN, get_posttrans(), get_pretrans(), IMAGIC, InvalidValueException, matrix, MATRIX, MRC, phi, QUATERNION, SGIROT, SPIDER, SPIN, EMAN::Vec3f, and XYZ.

01712 {
01713         float e0  = 0;float e1=0; float e2=0; float e3=0;
01714         float Omega=0;
01715         float az  = 0;
01716         float alt = 0;
01717         float phi = 0;
01718         float cxtilt = 0;
01719         float sxtilt = 0;
01720         float cytilt = 0;
01721         float sytilt = 0;
01722         bool is_quaternion = 0;
01723         bool is_matrix = 0;
01724 
01725         switch(euler_type) {
01726         case EMAN:
01727                 az  = (float)rotation["az"] ;
01728                 alt = (float)rotation["alt"]  ;
01729                 phi = (float)rotation["phi"] ;
01730                 break;
01731         case IMAGIC:
01732                 az  = (float)rotation["alpha"] ;
01733                 alt = (float)rotation["beta"]  ;
01734                 phi = (float)rotation["gamma"] ;
01735                 break;
01736 
01737         case SPIDER:
01738                 az =  (float)rotation["phi"]    + 90.0f;
01739                 alt = (float)rotation["theta"] ;
01740                 phi = (float)rotation["psi"]    - 90.0f;
01741                 break;
01742 
01743         case XYZ:
01744                 cxtilt = cos( (M_PI/180.0f)*(float)rotation["xtilt"]);
01745                 sxtilt = sin( (M_PI/180.0f)*(float)rotation["xtilt"]);
01746                 cytilt = cos( (M_PI/180.0f)*(float)rotation["ytilt"]);
01747                 sytilt = sin( (M_PI/180.0f)*(float)rotation["ytilt"]);
01748                 az =  (180.0f/M_PI)*atan2(-cytilt*sxtilt,sytilt)   + 90.0f ;
01749                 alt = (180.0f/M_PI)*acos(cytilt*cxtilt)  ;
01750                 phi = (float)rotation["ztilt"] +(180.0f/M_PI)*atan2(sxtilt,cxtilt*sytilt)   - 90.0f ;
01751                 break;
01752 
01753         case MRC:
01754                 az  = (float)rotation["phi"]   + 90.0f ;
01755                 alt = (float)rotation["theta"] ;
01756                 phi = (float)rotation["omega"] - 90.0f ;
01757                 break;
01758 
01759         case QUATERNION:
01760                 is_quaternion = 1;
01761                 e0 = (float)rotation["e0"];
01762                 e1 = (float)rotation["e1"];
01763                 e2 = (float)rotation["e2"];
01764                 e3 = (float)rotation["e3"];
01765                 break;
01766 
01767         case SPIN:
01768                 is_quaternion = 1;
01769                 Omega = (float)rotation["Omega"];
01770                 e0 = cos(Omega*M_PI/360.0f);
01771                 e1 = sin(Omega*M_PI/360.0f)* (float)rotation["n1"];
01772                 e2 = sin(Omega*M_PI/360.0f)* (float)rotation["n2"];
01773                 e3 = sin(Omega*M_PI/360.0f)* (float)rotation["n3"];
01774                 break;
01775 
01776         case SGIROT:
01777                 is_quaternion = 1;
01778                 Omega = (float)rotation["q"]  ;
01779                 e0 = cos(Omega*M_PI/360.0f);
01780                 e1 = sin(Omega*M_PI/360.0f)* (float)rotation["n1"];
01781                 e2 = sin(Omega*M_PI/360.0f)* (float)rotation["n2"];
01782                 e3 = sin(Omega*M_PI/360.0f)* (float)rotation["n3"];
01783                 break;
01784 
01785         case MATRIX:
01786                 is_matrix = 1;
01787                 matrix[0][0] = (float)rotation["m11"]  ;
01788                 matrix[0][1] = (float)rotation["m12"]  ;
01789                 matrix[0][2] = (float)rotation["m13"]  ;
01790                 matrix[1][0] = (float)rotation["m21"]  ;
01791                 matrix[1][1] = (float)rotation["m22"]  ;
01792                 matrix[1][2] = (float)rotation["m23"]  ;
01793                 matrix[2][0] = (float)rotation["m31"]  ;
01794                 matrix[2][1] = (float)rotation["m32"]  ;
01795                 matrix[2][2] = (float)rotation["m33"]  ;
01796                 break;
01797 
01798         default:
01799                 throw InvalidValueException(euler_type, "unknown Euler Type");
01800         }  // ends switch euler_type
01801 
01802 
01803         Vec3f postT  = get_posttrans( ) ;
01804         Vec3f preT   = get_pretrans( ) ;
01805 
01806 
01807         float azp  = fmod(az,360.0f)*M_PI/180.0f;
01808         float altp  = alt*M_PI/180.0f;
01809         float phip = fmod(phi,360.0f)*M_PI/180.0f;
01810 
01811         if (!is_quaternion && !is_matrix) {
01812                 matrix[0][0] =  cos(phip)*cos(azp) - cos(altp)*sin(azp)*sin(phip);
01813                 matrix[0][1] =  cos(phip)*sin(azp) + cos(altp)*cos(azp)*sin(phip);
01814                 matrix[0][2] =  sin(altp)*sin(phip);
01815                 matrix[1][0] = -sin(phip)*cos(azp) - cos(altp)*sin(azp)*cos(phip);
01816                 matrix[1][1] = -sin(phip)*sin(azp) + cos(altp)*cos(azp)*cos(phip);
01817                 matrix[1][2] =  sin(altp)*cos(phip);
01818                 matrix[2][0] =  sin(altp)*sin(azp);
01819                 matrix[2][1] = -sin(altp)*cos(azp);
01820                 matrix[2][2] =  cos(altp);
01821         }
01822         if (is_quaternion){
01823                 matrix[0][0] = e0 * e0 + e1 * e1 - e2 * e2 - e3 * e3;
01824                 matrix[0][1] = 2.0f * (e1 * e2 + e0 * e3);
01825                 matrix[0][2] = 2.0f * (e1 * e3 - e0 * e2);
01826                 matrix[1][0] = 2.0f * (e2 * e1 - e0 * e3);
01827                 matrix[1][1] = e0 * e0 - e1 * e1 + e2 * e2 - e3 * e3;
01828                 matrix[1][2] = 2.0f * (e2 * e3 + e0 * e1);
01829                 matrix[2][0] = 2.0f * (e3 * e1 + e0 * e2);
01830                 matrix[2][1] = 2.0f * (e3 * e2 - e0 * e1);
01831                 matrix[2][2] = e0 * e0 - e1 * e1 - e2 * e2 + e3 * e3;
01832                 // keep in mind matrix[0][2] is M13 gives an e0 e2 piece, etc
01833         }
01834         // Now do post and pretrans: vfinal = vpost + R vpre;
01835 
01836         matrix[0][3] = postT[0] + matrix[0][0]*preT[0] + matrix[0][1]*preT[1] + matrix[0][2]*preT[2]  ;
01837         matrix[1][3] = postT[1] + matrix[1][0]*preT[0] + matrix[1][1]*preT[1] + matrix[1][2]*preT[2]  ;
01838         matrix[2][3] = postT[2] + matrix[2][0]*preT[0] + matrix[2][1]*preT[1] + matrix[2][2]*preT[2]  ;
01839 }

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

Parameters:
mij the value to be placed in the internal transformation matrix at coordinate (i-1,j-1)

Definition at line 1842 of file transform.cpp.

References EulerType, and set_rotation().

01845 {
01846         EulerType euler_type = MATRIX;
01847         Dict rot;
01848         rot["m11"]  = m11;
01849         rot["m12"]  = m12;
01850         rot["m13"]  = m13;
01851         rot["m21"]  = m21;
01852         rot["m22"]  = m22;
01853         rot["m23"]  = m23;
01854         rot["m31"]  = m31;
01855         rot["m32"]  = m32;
01856         rot["m33"]  = m33;
01857         set_rotation(euler_type, rot);  // Or should it be &rot ?
01858 }

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.

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 1683 of file transform.cpp.

References init(), InvalidValueException, QUATERNION, set_rotation(), SGIROT, and SPIN.

01684 {
01685         init();
01686         Dict rot;
01687         switch(euler_type) {
01688                 case QUATERNION:
01689                         rot["e0"]  = a1;
01690                         rot["e1"] = a2;
01691                         rot["e2"] = a3;
01692                         rot["e3"] = a4;
01693                         break;
01694                 case SGIROT:
01695                         rot["q"]  = a1;
01696                         rot["n1"] = a2;
01697                         rot["n2"] = a3;
01698                         rot["n3"] = a4;
01699                 case SPIN:
01700                         rot["Omega"]  = a1;
01701                         rot["n1"] = a2;
01702                         rot["n2"] = a3;
01703                         rot["n3"] = a4;
01704                         break;
01705                 default:
01706                         throw InvalidValueException(euler_type, "cannot instantiate this Euler Type");
01707         }  // ends switch euler_type
01708         set_rotation(euler_type, rot);
01709 }

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.

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 1646 of file transform.cpp.

References EMAN, IMAGIC, init(), InvalidValueException, MRC, set_rotation(), SPIDER, and XYZ.

01647 {
01648         init();
01649         Dict rot;
01650         switch(euler_type) {
01651                 case EMAN:
01652                         rot["az"]  = a1;
01653                         rot["alt"] = a2;
01654                         rot["phi"] = a3;
01655                         break;
01656                 case SPIDER:
01657                         rot["phi"]   = a1;
01658                         rot["theta"] = a2;
01659                         rot["psi"]   = a3;
01660                         break;
01661                 case IMAGIC:
01662                         rot["alpha"]   = a1;
01663                         rot["beta"] = a2;
01664                         rot["gamma"]   = a3;
01665                         break;
01666                 case MRC:
01667                         rot["phi"]   = a1;
01668                         rot["theta"] = a2;
01669                         rot["omega"]   = a3;
01670                         break;
01671                 case XYZ:
01672                         rot["xtilt"]   = a1;
01673                         rot["ytilt"] = a2;
01674                         rot["ztilt"]   = a3;
01675                         break;
01676                 default:
01677                 throw InvalidValueException(euler_type, "cannot instantiate this Euler Type");
01678         }  // ends switch euler_type
01679         set_rotation(euler_type, rot);
01680 }

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 )

  • 2 cos(Omega/2) ((sin(Omega/2)nhat ) cross = (e0^2 - evec^2) one + 2 (evec evec ) - 2 e0 evec cross

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 1635 of file transform.cpp.

References EulerType.

Referenced by EMAN::PointArray::align_2d(), get_sym(), inverseUsingAngs(), set_rotation(), and Transform3D().

01636 {
01637         EulerType euler_type=EMAN;
01638         Dict rot;
01639         rot["az"]  = az;
01640         rot["alt"] = alt;
01641         rot["phi"] = phi;
01642         set_rotation(euler_type, rot);
01643 }

void Transform3D::set_scale const float &  scale  ) 
 

FIXME insert comments.

Definition at line 1441 of file transform.cpp.

References apply_scale(), and get_scale().

Referenced by ali3d_d(), main(), and EMAN::EMData::rotate_translate().

01442 {
01443         float OldScale= get_scale();
01444         float Scale2Apply = scale/OldScale;
01445         apply_scale(Scale2Apply);
01446 }

void Transform3D::to_identity  ) 
 

Definition at line 1293 of file transform.cpp.

References matrix, post_x_mirror, set_center(), and EMAN::Vec3f.

Referenced by init().

01294 {
01295 //      for (int i = 0; i < 3; i++) {
01296 //              matrix[i][i] = 1;
01297 //      }
01298 
01299         for(int i=0; i<4; ++i) {
01300                 for(int j=0; j<4; ++j) {
01301                         if(i==j) {
01302                                 matrix[i][j] = 1;
01303                         }
01304                         else {
01305                                 matrix[i][j] = 0;
01306                         }
01307                 }
01308         }
01309         post_x_mirror = false;
01310         set_center(Vec3f(0,0,0));
01311 }

Vec3f Transform3D::transform const Vec3f v3f  )  const
 

Perform a full transform a Vec3f using the internal transformation matrix.

Parameters:
v3f the vector to be transformed
Returns:
the transformed vector

Definition at line 1524 of file transform.cpp.

References matrix(), EMAN::Vec3f, x, and y.

01525 {
01526 //      This is the transformation of a vector, v by a matrix M
01527         float x = matrix[0][0] * v3f[0] + matrix[0][1] * v3f[1] + matrix[0][2] * v3f[2] + matrix[0][3] ;
01528         float y = matrix[1][0] * v3f[0] + matrix[1][1] * v3f[1] + matrix[1][2] * v3f[2] + matrix[1][3] ;
01529         float z = matrix[2][0] * v3f[0] + matrix[2][1] * v3f[1] + matrix[2][2] * v3f[2] + matrix[2][3] ;
01530         return Vec3f(x, y, z);
01531 }

void Transform3D::transpose  ) 
 

create the transpose in place

Definition at line 1429 of file transform.cpp.

References matrix.

01430 {
01431         float tempij;
01432         for (int i = 0; i < 3; i++) {
01433                 for (int j = 0; j < i; j++) {
01434                         tempij= matrix[i][j];
01435                         matrix[i][j] = matrix[j][i];
01436                         matrix[j][i] = tempij;
01437                 }
01438         }
01439 }


Member Data Documentation

const float Transform3D::ERR_LIMIT = 0.000001f [static]
 

Definition at line 59 of file transform.cpp.

float EMAN::Transform3D::matrix[4][4] [protected]
 

Definition at line 866 of file transform.h.

Referenced by apply_scale(), get_pretrans(), get_rotation(), get_scale(), inverse(), is_identity(), 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 to_identity().

Transform3D::EulerType EMAN::Transform3D::s [protected]
 

Definition at line 870 of file transform.h.


The documentation for this class was generated from the following files:
Generated on Thu Dec 9 13:48:55 2010 for EMAN2 by  doxygen 1.3.9.1