Rosetta
Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
numeric::HomogeneousTransform< T > Class Template Reference

#include <HomogeneousTransform.hh>

Public Types

typedef T value_type
 

Public Member Functions

 HomogeneousTransform ()
 Default constructor: axis aligned with the global coordinate frame and the point located at the origin. More...
 
 HomogeneousTransform (xyzVector< T > const &p1, xyzVector< T > const &p2, xyzVector< T > const &p3)
 Construct the coordinate frame from the points defined such that. More...
 
 HomogeneousTransform (xyzVector< T > const &xaxis, xyzVector< T > const &yaxis, xyzVector< T > const &zaxis, xyzVector< T > const &point)
 Constructor from xyzVectors: trust that the axis are indeed orthoganol. More...
 
 HomogeneousTransform (xyzMatrix< T > const &axes, xyzVector< T > const &point)
 Constructor from an xyzMatrix and xyzVectors: trust that the axis are indeed orthoganol. More...
 
bool is_close (HomogeneousTransform< T > const &other, platform::Real const threshold=1.0e-6)
 
value_type xx () const
 
value_type xy () const
 
value_type xz () const
 
value_type yx () const
 
value_type yy () const
 
value_type yz () const
 
value_type zx () const
 
value_type zy () const
 
value_type zz () const
 
value_type px () const
 
value_type py () const
 
value_type pz () const
 
xyzVector< Txaxis () const
 
xyzVector< Tyaxis () const
 
xyzVector< Tzaxis () const
 
xyzVector< Tpoint () const
 
xyzMatrix< Trotation_matrix () const
 
void set_identity_rotation ()
 Mutators. More...
 
void set_identity_transform ()
 
void set_identity ()
 
void set_xaxis_rotation_deg (T angle)
 
void set_yaxis_rotation_deg (T angle)
 
void set_zaxis_rotation_deg (T angle)
 
void set_xaxis_rotation_rad (T angle)
 
void set_yaxis_rotation_rad (T angle)
 
void set_zaxis_rotation_rad (T angle)
 
void set_transform (xyzVector< T > const &t)
 Set this HT to describe a transformation along the three axes. This has the size effect of setting the axes to the global axes. More...
 
void set_point (xyzVector< T > const &p)
 Set the point that this HT is centered at. This leaves the axes untouched. More...
 
void walk_along_x (T delta)
 Right multiply this coordinate frame by the frame 1 0 0 delta 0 1 0 0 0 0 1 0. More...
 
void walk_along_y (T delta)
 Right multiply this coordinate frame by the frame 1 0 0 0 0 1 0 delta 0 0 1 0. More...
 
void walk_along_z (T delta)
 Right multiply this coordinate frame by the frame 1 0 0 0 0 1 0 0 0 0 1 delta. More...
 
HomogeneousTransform< Toperator* (HomogeneousTransform< T > const &rmat) const
 Multiplication. More...
 
xyzVector< Toperator* (xyzVector< T > const &vect) const
 Transform a point. The input point is a location in this coordinate frame the output point is the location in global coordinate frame. More...
 
HomogeneousTransform< Tinverse () const
 Invert this matrix. More...
 
xyzVector< Tto_local_coordinate (xyzVector< T > const &v) const
 Convert a point in the global coordinate system to a point in this coordinate frame. If this frame is F and the point is p, then this solves for x st: F x = p. Equivalent to computing (F.inverse() * p).point(). More...
 
xyzVector< Teuler_angles_rad () const
 Return the three euler angles (in radians) that describe this HomogeneousTransform as the series of a Z axis rotation by the angle phi (returned in position 1 of the output vector), followed by an X axis rotation by the angle theta (returned in position 3 of the output vector), followed by another Z axis rotation by the angle psi (returned in position 2 of the output vector). This code is a modified version of Alex Z's code from r++. More...
 
xyzVector< Teuler_angles_ZYX_rad () const
 Return the three euler angles (in radians) that describe this HomogeneousTransform as the series of a Z axis rotation by the angle psi (returned in position 1 of the output vector), followed by an Y axis rotation by the angle theta (returned in position 2 of the output vector), followed by an X axis rotation by the angle phi (returned in position 3 of the output vector). This convention of Euler angles is added for use in iterative algorithms that aim to minimize Euler angle errors. When Euler angle error between two vectors approaches zero, the three Euler axes of that error become increasingly orthogonal, which benefits stability and speed of conversion Equations adopted from http://web.mit.edu/2.05/www/Handout/HO2.PDF (by Olivier Chocron) More...
 
xyzVector< Teuler_angles_deg () const
 
void from_euler_angles_rad (xyzVector< T > const &euler)
 Construct the coordinate frame from three euler angles that describe the frame. Keep the point fixed. See the description for euler_angles_rad() to understand the Z-X-Z transformation convention. More...
 
void from_euler_angles_deg (xyzVector< T > const &euler)
 
T xform_magnitude (T radius_of_gyration)
 Less accurate functions. More...
 
std::ostream & show (std::ostream &stream=std::cout) const
 

Private Member Functions

bool orthonormal () const
 
bool orthoganol () const
 Are the axis orthoganol. More...
 
bool normal () const
 Are the axis of unit length? More...
 

Private Attributes

value_type xx_
 For axis Q, the R component is named qr_; e.g. The Z component of the Y axis is yz_;. More...
 
value_type yx_
 
value_type zx_
 
value_type px_
 
value_type xy_
 
value_type yy_
 
value_type zy_
 
value_type py_
 
value_type xz_
 
value_type yz_
 
value_type zz_
 
value_type pz_
 

Member Typedef Documentation

◆ value_type

template<class T >
typedef T numeric::HomogeneousTransform< T >::value_type

Constructor & Destructor Documentation

◆ HomogeneousTransform() [1/4]

template<class T >
numeric::HomogeneousTransform< T >::HomogeneousTransform ( )
inline

Default constructor: axis aligned with the global coordinate frame and the point located at the origin.

◆ HomogeneousTransform() [2/4]

template<class T >
numeric::HomogeneousTransform< T >::HomogeneousTransform ( xyzVector< T > const &  p1,
xyzVector< T > const &  p2,
xyzVector< T > const &  p3 
)
inline

◆ HomogeneousTransform() [3/4]

template<class T >
numeric::HomogeneousTransform< T >::HomogeneousTransform ( xyzVector< T > const &  xaxis,
xyzVector< T > const &  yaxis,
xyzVector< T > const &  zaxis,
xyzVector< T > const &  point 
)
inline

Constructor from xyzVectors: trust that the axis are indeed orthoganol.

References numeric::HomogeneousTransform< T >::orthonormal().

◆ HomogeneousTransform() [4/4]

template<class T >
numeric::HomogeneousTransform< T >::HomogeneousTransform ( xyzMatrix< T > const &  axes,
xyzVector< T > const &  point 
)
inline

Constructor from an xyzMatrix and xyzVectors: trust that the axis are indeed orthoganol.

Note that variable naming scheme (e.g. xy) is oposite of that in the xyzMatrix.

References numeric::HomogeneousTransform< T >::orthonormal().

Member Function Documentation

◆ euler_angles_deg()

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::euler_angles_deg ( ) const
inline

◆ euler_angles_rad()

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::euler_angles_rad ( ) const
inline

Return the three euler angles (in radians) that describe this HomogeneousTransform as the series of a Z axis rotation by the angle phi (returned in position 1 of the output vector), followed by an X axis rotation by the angle theta (returned in position 3 of the output vector), followed by another Z axis rotation by the angle psi (returned in position 2 of the output vector). This code is a modified version of Alex Z's code from r++.

The range of phi is [ -pi, pi ]; The range of psi is [ -pi, pi ]; The range of theta is [ 0, pi ];

The function pretends that this HomogeneousTransform is the result of these three transformations; if it were, then the rotation matrix would be

FIGURE 1: R = [ cos(psi)cos(phi)-cos(theta)sin(phi)sin(psi) cos(psi)sin(phi)+cos(theta)cos(phi)sin(psi) sin(psi)sin(theta) -sin(psi)cos(phi)-cos(theta)sin(phi)cos(psi) -sin(psi)sin(phi)+cos(theta)cos(phi)cos(psi) cos(psi)sin(theta) sin(theta)sin(phi) -sin(theta)cos(phi) cos(theta) ]

where each axis above is represented as a ROW VECTOR (to be distinguished from the HomogeneousTransform's representation of axes as COLUMN VECTORS).

The zz_ coordinate gives away theta. Theta may be computed as acos( zz_ ), or, as Alex does it, asin( sqrt( 1 - zz^2)) Since there is redundancy in theta, this function chooses a theta with a positive sin(theta): i.e. quadrants I and II. Assuming we have a positive sin theta pushes phi and psi into conforming angles.

NOTE on theta: asin returns a value in the range [ -pi/2, pi/2 ], and we have artificially created a positive sin(theta), so we will get a asin( pos_sin_theta ), we have a value in the range [ 0, pi/2 ]. To convert this into the actual angle theta, we examine the zz sign. If zz is negative, we chose the quadrant II theta. That is, asin( pos_sin_theta) returned an angle, call it theta'. Now, if cos( theta ) is negative, then we want to choose the positive x-axis rotation that's equivalent to -theta'. To do so, we reflect q through the y axis (See figure 2 below) to get p and then measure theta as pi - theta'.

FIGURE 2:

II | I | p. | .q (cos(-theta'), std::abs(sin(theta'))) . | .

theta'( . | . ) theta' = asin( std::abs(sin(theta))

III | IV | The angle between the positive x axis and p is pi - theta'.

Since zx and zy contain only phi terms and a constant sin( theta ) term, phi is given by atan2( sin_phi, cos_phi ) = atan2( c*sin_phi, c*cos_phi ) = atan2( zx, -zy ) for c positive and non-zero. If sin_theta is zero, or very close to zero, we're at gimbal lock.

Moreover, since xz and yz contain only psi terms, psi may also be deduced using atan2.

There are 2 degenerate cases (gimbal lock)

  1. theta close to 0 (North Pole singularity), or
  2. theta close to pi (South Pole singularity) For these, we take: phi=acos(xx), theta = 0 (resp. Pi/2), psi = 0

References test.T009_Exceptions::e, numeric::constants::d::pi, numeric::sin_cos_range(), pyrosetta.distributed.cluster.exceptions::T, numeric::HomogeneousTransform< T >::xx_, numeric::HomogeneousTransform< T >::xz_, numeric::HomogeneousTransform< T >::yx_, numeric::HomogeneousTransform< T >::yz_, numeric::HomogeneousTransform< T >::zx_, numeric::HomogeneousTransform< T >::zy_, and numeric::HomogeneousTransform< T >::zz_.

Referenced by numeric::HomogeneousTransform< T >::euler_angles_deg(), and ClosabilityScore::get_rt_over_leap().

◆ euler_angles_ZYX_rad()

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::euler_angles_ZYX_rad ( ) const
inline

Return the three euler angles (in radians) that describe this HomogeneousTransform as the series of a Z axis rotation by the angle psi (returned in position 1 of the output vector), followed by an Y axis rotation by the angle theta (returned in position 2 of the output vector), followed by an X axis rotation by the angle phi (returned in position 3 of the output vector). This convention of Euler angles is added for use in iterative algorithms that aim to minimize Euler angle errors. When Euler angle error between two vectors approaches zero, the three Euler axes of that error become increasingly orthogonal, which benefits stability and speed of conversion Equations adopted from http://web.mit.edu/2.05/www/Handout/HO2.PDF (by Olivier Chocron)

The range of psi is [ -pi, pi ]; The range of theta is [ -pi/2, pi/2 ]; The range of phi is [ -pi, pi ];

FIGURE 1: R = [ cos(psi)cos(theta) cos(psi)sin(theta)sin(phi)-sin(psi)cos(phi) cos(psi)sin(theta)cos(phi)+sin(psi)sin(phi) sin(psi)cos(theta) sin(psi)sin(theta)sin(phi)+cos(psi)cos(phi) sin(psi)sin(theta)cos(phi)-cos(psi)sin(phi) -sin(theta) cos(theta)sin(phi) cos(theta)cos(phi) ]

xz_ gives away theta. Theta may be computed as -asin( xz_ ), or, as done by Olivier Choocron, as atan2(-xz_,sqrt(xx_^2+xy_^2)) where atan2 is considered to be more computationally efficient

Since xx_ and xy_ contain only psi terms and a shared cos( theta ) term, psi is given by atan2( cos_theta*sin_psi, cos_theta*cos_psi ) = atan2( c*sin_psi, c*cos_psi ) = atan2( xy_, xx_ ) for c positive and non-zero. If cos_theta is zero, or very close to zero, we're at gimbal lock.

There are 2 degenerate cases (gimbal lock)

  1. theta close to -pi/2 (North Pole singularity), or
  2. theta close to pi/2 (South Pole singularity) For these, we take: psi = 0, and detect whether theta = -pi/2 or pi/2 phi can be calculated as usual, because cos(theta) will be -1 or 1.

References test.T009_Exceptions::e, numeric::constants::d::pi_over_2, numeric::HomogeneousTransform< T >::xx_, numeric::HomogeneousTransform< T >::xy_, numeric::HomogeneousTransform< T >::xz_, numeric::HomogeneousTransform< T >::yz_, and numeric::HomogeneousTransform< T >::zz_.

◆ from_euler_angles_deg()

template<class T >
void numeric::HomogeneousTransform< T >::from_euler_angles_deg ( xyzVector< T > const &  euler)
inline

◆ from_euler_angles_rad()

template<class T >
void numeric::HomogeneousTransform< T >::from_euler_angles_rad ( xyzVector< T > const &  euler)
inline

◆ inverse()

template<class T >
HomogeneousTransform< T > numeric::HomogeneousTransform< T >::inverse ( ) const
inline

◆ is_close()

template<class T >
bool numeric::HomogeneousTransform< T >::is_close ( HomogeneousTransform< T > const &  other,
platform::Real const  threshold = 1.0e-6 
)
inline

◆ normal()

template<class T >
bool numeric::HomogeneousTransform< T >::normal ( ) const
inlineprivate

◆ operator*() [1/2]

template<class T >
HomogeneousTransform< T > numeric::HomogeneousTransform< T >::operator* ( HomogeneousTransform< T > const &  rmat) const
inline

◆ operator*() [2/2]

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::operator* ( xyzVector< T > const &  vect) const
inline

◆ orthoganol()

template<class T >
bool numeric::HomogeneousTransform< T >::orthoganol ( ) const
inlineprivate

◆ orthonormal()

template<class T >
bool numeric::HomogeneousTransform< T >::orthonormal ( ) const
inlineprivate

◆ point()

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::point ( ) const
inline

◆ px()

template<class T >
value_type numeric::HomogeneousTransform< T >::px ( ) const
inline

◆ py()

template<class T >
value_type numeric::HomogeneousTransform< T >::py ( ) const
inline

◆ pz()

template<class T >
value_type numeric::HomogeneousTransform< T >::pz ( ) const
inline

◆ rotation_matrix()

template<class T >
xyzMatrix< T > numeric::HomogeneousTransform< T >::rotation_matrix ( ) const
inline

◆ set_identity()

template<class T >
void numeric::HomogeneousTransform< T >::set_identity ( )
inline

◆ set_identity_rotation()

template<class T >
void numeric::HomogeneousTransform< T >::set_identity_rotation ( )
inline

◆ set_identity_transform()

template<class T >
void numeric::HomogeneousTransform< T >::set_identity_transform ( )
inline

◆ set_point()

template<class T >
void numeric::HomogeneousTransform< T >::set_point ( xyzVector< T > const &  p)
inline

◆ set_transform()

template<class T >
void numeric::HomogeneousTransform< T >::set_transform ( xyzVector< T > const &  t)
inline

Set this HT to describe a transformation along the three axes. This has the size effect of setting the axes to the global axes.

References numeric::HomogeneousTransform< T >::px_, numeric::HomogeneousTransform< T >::py_, numeric::HomogeneousTransform< T >::pz_, numeric::HomogeneousTransform< T >::set_identity_rotation(), and predPRE::t.

◆ set_xaxis_rotation_deg()

template<class T >
void numeric::HomogeneousTransform< T >::set_xaxis_rotation_deg ( T  angle)
inline

◆ set_xaxis_rotation_rad()

template<class T >
void numeric::HomogeneousTransform< T >::set_xaxis_rotation_rad ( T  angle)
inline

◆ set_yaxis_rotation_deg()

template<class T >
void numeric::HomogeneousTransform< T >::set_yaxis_rotation_deg ( T  angle)
inline

◆ set_yaxis_rotation_rad()

template<class T >
void numeric::HomogeneousTransform< T >::set_yaxis_rotation_rad ( T  angle)
inline

◆ set_zaxis_rotation_deg()

template<class T >
void numeric::HomogeneousTransform< T >::set_zaxis_rotation_deg ( T  angle)
inline

◆ set_zaxis_rotation_rad()

template<class T >
void numeric::HomogeneousTransform< T >::set_zaxis_rotation_rad ( T  angle)
inline

◆ show()

template<class T >
std::ostream& numeric::HomogeneousTransform< T >::show ( std::ostream &  stream = std::cout) const
inline

◆ to_local_coordinate()

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::to_local_coordinate ( xyzVector< T > const &  v) const
inline

Convert a point in the global coordinate system to a point in this coordinate frame. If this frame is F and the point is p, then this solves for x st: F x = p. Equivalent to computing (F.inverse() * p).point().

References numeric::dot(), numeric::HomogeneousTransform< T >::point(), kmeans_adaptive_kernel_density_bb_dependent_rotlib::v, numeric::HomogeneousTransform< T >::xaxis(), numeric::HomogeneousTransform< T >::yaxis(), and numeric::HomogeneousTransform< T >::zaxis().

◆ walk_along_x()

template<class T >
void numeric::HomogeneousTransform< T >::walk_along_x ( T  delta)
inline

◆ walk_along_y()

template<class T >
void numeric::HomogeneousTransform< T >::walk_along_y ( T  delta)
inline

◆ walk_along_z()

template<class T >
void numeric::HomogeneousTransform< T >::walk_along_z ( T  delta)
inline

◆ xaxis()

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::xaxis ( ) const
inline

◆ xform_magnitude()

template<class T >
T numeric::HomogeneousTransform< T >::xform_magnitude ( T  radius_of_gyration)
inline

Less accurate functions.

Used to calculate no-alignment "RMSD" of two identical poses using transforms

For this to work, the two poses must be identical, but with different orientations. Here are the steps to use this:

  1. The radius of gyration of the pose must be calculated (see core/pose/util.hh )
  2. There must be an archetype pose with its center of mass at the origin (this can be imaginary)
  3. The relative transform of each of the two poses relative to the archetype must be calculated. (i.e. What transform you would apply to the archetype to move it to where the pose is.)
  4. RMSD = ( xform1.inverse() * xform2 ).xform_magnitude( radius_of_gyration )

References max(), numeric::HomogeneousTransform< T >::px_, numeric::HomogeneousTransform< T >::py_, numeric::HomogeneousTransform< T >::pz_, numeric::HomogeneousTransform< T >::xx_, numeric::HomogeneousTransform< T >::yy_, and numeric::HomogeneousTransform< T >::zz_.

◆ xx()

template<class T >
value_type numeric::HomogeneousTransform< T >::xx ( ) const
inline

◆ xy()

template<class T >
value_type numeric::HomogeneousTransform< T >::xy ( ) const
inline

◆ xz()

template<class T >
value_type numeric::HomogeneousTransform< T >::xz ( ) const
inline

◆ yaxis()

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::yaxis ( ) const
inline

◆ yx()

template<class T >
value_type numeric::HomogeneousTransform< T >::yx ( ) const
inline

◆ yy()

template<class T >
value_type numeric::HomogeneousTransform< T >::yy ( ) const
inline

◆ yz()

template<class T >
value_type numeric::HomogeneousTransform< T >::yz ( ) const
inline

◆ zaxis()

template<class T >
xyzVector< T > numeric::HomogeneousTransform< T >::zaxis ( ) const
inline

◆ zx()

template<class T >
value_type numeric::HomogeneousTransform< T >::zx ( ) const
inline

◆ zy()

template<class T >
value_type numeric::HomogeneousTransform< T >::zy ( ) const
inline

◆ zz()

template<class T >
value_type numeric::HomogeneousTransform< T >::zz ( ) const
inline

Member Data Documentation

◆ px_

template<class T >
value_type numeric::HomogeneousTransform< T >::px_
private

◆ py_

template<class T >
value_type numeric::HomogeneousTransform< T >::py_
private

◆ pz_

template<class T >
value_type numeric::HomogeneousTransform< T >::pz_
private

◆ xx_

template<class T >
value_type numeric::HomogeneousTransform< T >::xx_
private

For axis Q, the R component is named qr_; e.g. The Z component of the Y axis is yz_;.

Variables below are allocated in an intentionally visually pleasing order for a code reader, not necessarily for performance. The homogenous matrix is a 4 x 3 matrix, with a pseudo row-major ordering of data. Naming scheme: Column 1 is the x axis as a column vector Column 2 is the y axis as a column vector Column 3 is the z axis as a column vector Column 4 is the location of the point, as a column vector. Row 1 is the x coordinate of the three axes and the point Row 2 is the y coordinate of the three axes and the point Row 3 is the z coordinate of the three axes and the point Row 4 is not explicitly represented, but is always [ 0, 0, 0, 1 ] Note: This naming scheme is different from the one that Stuart uses in the xyzMatrix class.

Referenced by numeric::HomogeneousTransform< T >::euler_angles_rad(), numeric::HomogeneousTransform< T >::euler_angles_ZYX_rad(), numeric::HomogeneousTransform< T >::from_euler_angles_rad(), numeric::HomogeneousTransform< T >::HomogeneousTransform(), numeric::HomogeneousTransform< T >::inverse(), numeric::HomogeneousTransform< T >::is_close(), numeric::HomogeneousTransform< T >::normal(), numeric::HomogeneousTransform< T >::operator*(), numeric::HomogeneousTransform< T >::orthoganol(), numeric::HomogeneousTransform< T >::rotation_matrix(), numeric::HomogeneousTransform< T >::set_identity_rotation(), numeric::HomogeneousTransform< T >::walk_along_x(), numeric::HomogeneousTransform< T >::xaxis(), numeric::HomogeneousTransform< T >::xform_magnitude(), and numeric::HomogeneousTransform< T >::xx().

◆ xy_

template<class T >
value_type numeric::HomogeneousTransform< T >::xy_
private

◆ xz_

template<class T >
value_type numeric::HomogeneousTransform< T >::xz_
private

◆ yx_

template<class T >
value_type numeric::HomogeneousTransform< T >::yx_
private

◆ yy_

template<class T >
value_type numeric::HomogeneousTransform< T >::yy_
private

◆ yz_

template<class T >
value_type numeric::HomogeneousTransform< T >::yz_
private

◆ zx_

template<class T >
value_type numeric::HomogeneousTransform< T >::zx_
private

◆ zy_

template<class T >
value_type numeric::HomogeneousTransform< T >::zy_
private

◆ zz_

template<class T >
value_type numeric::HomogeneousTransform< T >::zz_
private

The documentation for this class was generated from the following files: