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

References init().

Referenced by angles2tfvec().

01201 {
01202         init();
01203 }

Transform3D::Transform3D const Transform3D rhs  ) 
 

Copy constructor.

Parameters:
rhs the object to be copied

Definition at line 1205 of file transform.cpp.

References matrix, and rhs.

01206 {
01207     for( int i=0; i < 4; ++i )
01208     {
01209         for( int j=0; j < 4; ++j )
01210         {
01211             matrix[i][j] = rhs.matrix[i][j];
01212         }
01213     }
01214 }

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

References init(), phi, 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.

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

Definition at line 1225 of file transform.cpp.

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

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.

Parameters:
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(), phi, set_posttrans(), set_pretrans(), set_rotation(), and EMAN::Vec3f.

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)

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

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 }

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 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.

Parameters:
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  ) 
 

Destructor.

Definition at line 1275 of file transform.cpp.

01276 {
01277 }


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

References Transform3D().

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.

References EMAN::Vec3f.

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 EulerType, get_rotation(), and EMAN::Vec3f.

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 EulerType, and get_rotation().

01437 {
01438         EulerType eulertype= SPIN ;
01439         Dict AA= get_rotation(eulertype);
01440         return AA["Omega"];
01441 }

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

References matrix(), and EMAN::Vec3f.

01502 {
01503         return Vec3f(matrix[0][i], matrix[1][i], matrix[2][i]);
01504 }

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

References matrix(), and EMAN::Vec3f.

01508 {
01509         return Vec3f(matrix[i][0], matrix[i][1], matrix[i][2]);
01510 }

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, 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().

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.

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

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

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.

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

Definition at line 1468 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().

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 }

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 1920 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().

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(), SymType, 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 SymType, and t.

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)

Returns:
the translation vector

Definition at line 1459 of file transform.cpp.

References get_posttrans(), and EMAN::Vec3f.

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)

Returns:
the translation vector

Definition at line 1463 of file transform.cpp.

References get_pretrans(), and EMAN::Vec3f.

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, v0, and EMAN::Vec3f.

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, EulerType, get_posttrans(), get_pretrans(), get_rotation(), get_scale(), set_posttrans(), set_pretrans(), set_rotation(), and EMAN::Vec3f.

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                 }

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

References matrix(), EMAN::Vec3f, 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, set_pretrans(), and EMAN::Vec3f.

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]
 

Definition at line 821 of file transform.h.

00821 { post_x_mirror = b; }

void Transform3D::set_posttrans const Vec2f posttrans  ) 
 

Definition at line 1369 of file transform.cpp.

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

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(), and EMAN::Vec3f.

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(), and EMAN::Vec3f.

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

void Transform3D::set_posttrans const Vec3f posttrans  ) 
 

Definition at line 1372 of file transform.cpp.

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

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(), EMAN::Vec2f, and EMAN::Vec3f.

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(), and EMAN::Vec3f.

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(), and EMAN::Vec3f.

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

void Transform3D::set_pretrans const Vec3f pretrans  ) 
 

Definition at line 1342 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().

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

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

Definition at line 1848 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.

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 }

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

References EMAN, get_posttrans(), get_pretrans(), IMAGIC, InvalidValueException, matrix, MATRIX, MRC, phi, QUATERNION, SGIROT, SPIDER, SPIN, EMAN::Vec3f, 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

Parameters:
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 EulerType, 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.

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 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.

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

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

References EulerType.

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(), main(), 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, set_center(), and EMAN::Vec3f.

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 }

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

References matrix(), EMAN::Vec3f, 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 }


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 Fri Apr 30 15:39:35 2010 for EMAN2 by  doxygen 1.3.9.1