8 #ifndef IMPALGEBRA_GEOMETRIC_ALIGNMENT_H
9 #define IMPALGEBRA_GEOMETRIC_ALIGNMENT_H
11 #include <IMP/algebra/algebra_config.h>
21 IMPALGEBRA_BEGIN_NAMESPACE
40 template <
class Vector3DsOrXYZs0,
class Vector3DsOrXYZs1>
43 const Vector3DsOrXYZs1& target) {
44 using algebra::get_vector_geometry;
50 Vector3D center_source(0, 0, 0), center_target(0, 0, 0);
51 for (
unsigned int i = 0; i < source.size(); ++i) {
53 center_source += get_vector_geometry(source[i]);
54 center_target += get_vector_geometry(target[i]);
56 << get_vector_geometry(target[i]) <<
")\n");
58 center_source = center_source / source.size();
59 center_target = center_target / target.size();
61 IMP_LOG_VERBOSE(
"Centers are (" << center_source <<
") (" << center_target
63 Vector3Ds shifted_source(source.size()), shifted_target(target.size());
64 for (
unsigned int i = 0; i < source.size(); ++i) {
65 shifted_source[i] = get_vector_geometry(source[i]) - center_source;
66 shifted_target[i] = get_vector_geometry(target[i]) - center_target;
70 IMP_Eigen::Matrix3d H;
71 for (
int i = 0; i < 3; i++) {
72 for (
int j = 0; j < 3; j++) {
76 for (
unsigned int i = 0; i < source.size(); i++) {
77 for (
int j = 0; j < 3; j++) {
78 for (
int k = 0; k < 3; k++) {
79 H(j, k) += shifted_source[i][j] * shifted_target[i][k];
85 IMP_Eigen::JacobiSVD<IMP_Eigen::Matrix3d> svd =
86 H.jacobiSvd(IMP_Eigen::ComputeFullV | IMP_Eigen::ComputeFullU);
87 IMP_Eigen::Matrix3d U = svd.matrixU(), V = svd.matrixV();
88 IMP_Eigen::Vector3d SV = svd.singularValues();
91 double det = SV[0] * SV[1] * SV[2];
95 for (
unsigned int i = 0; i < source.size(); ++i) {
99 for (
unsigned int i = 0; i < source.size(); ++i) {
103 IMP_WARN(
"Degenerate point set. I may not be able to align them."
109 IMP_Eigen::Matrix3d Sigma = IMP_Eigen::Matrix3d::Zero();
111 for (
int i = 0; i < 3; ++i) {
120 IMP_Eigen::Matrix3d rot = V * U.transpose();
123 if (rot.determinant() < 0) {
125 IMP_Eigen::Matrix3d S = IMP_Eigen::Matrix3d::Zero();
126 S(0, 0) = S(1, 1) = 1;
127 S(2, 2) = (U * V.transpose()).determinant();
128 rot = U * S * V.transpose();
147 IMPALGEBRAEXPORT Transformation2D
153 IMPALGEBRA_END_NAMESPACE
Vector3D get_rotated(const Vector3D &o) const
Rotate a vector around the origin.
Transformation2D get_transformation_aligning_pair(const Vector2Ds &set_from, const Vector2Ds &set_to)
#define IMP_WARN(expr)
Write a warning to a log.
base::Vector< VectorD< 2 > > Vector2Ds
#define IMP_LOG_TERSE(expr)
IMP::algebra::Transformation3D get_transformation_aligning_first_to_second(const Vector3DsOrXYZs0 &source, const Vector3DsOrXYZs1 &target)
Compute the rigid transform bringing the first point set to the second.
#define IMP_INTERNAL_CHECK(expr, message)
An assertion to check for internal errors in IMP. An IMP::ErrorException will be thrown.
Logging and error reporting support.
#define IMP_IF_CHECK(level)
Execute the code block if a certain level checks are on.
Simple 3D rotation class.
Rotation3D get_rotation_from_matrix(double m00, double m01, double m02, double m10, double m11, double m12, double m20, double m21, double m22)
Generate a Rotation3D object from a rotation matrix.
Logging and error reporting support.
Exception definitions and assertions.
#define IMP_IF_LOG(level)
Execute the code block if a certain level of logging is on.
#define IMP_LOG_VERBOSE(expr)