procrustes.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Stefan Brugger <stefanbrugger@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #ifndef IGL_PROCRUSTES_H
  9. #define IGL_PROCRUSTES_H
  10. #include "igl_inline.h"
  11. #include <Eigen/Dense>
  12. #include <Eigen/Geometry>
  13. namespace igl
  14. {
  15. // Solve Procrustes problem in d dimensions. Given two point sets X,Y in R^d
  16. // find best scale s, orthogonal R and translation t s.t. |s*X*R + t - Y|^2
  17. // is minimized.
  18. //
  19. // Templates:
  20. // DerivedV point type
  21. // Scalar scalar type
  22. // DerivedR type of R
  23. // DerivedT type of t
  24. // Inputs:
  25. // X #V by DIM first list of points
  26. // Y #V by DIM second list of points
  27. // includeScaling if scaling should be allowed
  28. // includeReflections if R is allowed to be a reflection
  29. // Outputs:
  30. // scale scaling
  31. // R orthogonal matrix
  32. // t translation
  33. //
  34. // Example:
  35. // MatrixXd X, Y; (containing 3d points as rows)
  36. // double scale;
  37. // MatrixXd R;
  38. // VectorXd t;
  39. // igl::procrustes(X,Y,true,false,scale,R,t);
  40. // R *= scale;
  41. // MatrixXd Xprime = (X * R).rowwise() + t.transpose();
  42. //
  43. template <
  44. typename DerivedX,
  45. typename DerivedY,
  46. typename Scalar,
  47. typename DerivedR,
  48. typename DerivedT>
  49. IGL_INLINE void procrustes(
  50. const Eigen::PlainObjectBase<DerivedX>& X,
  51. const Eigen::PlainObjectBase<DerivedY>& Y,
  52. bool includeScaling,
  53. bool includeReflections,
  54. Scalar& scale,
  55. Eigen::PlainObjectBase<DerivedR>& R,
  56. Eigen::PlainObjectBase<DerivedT>& t);
  57. // Same as above but returns Eigen transformation object.
  58. //
  59. // Templates:
  60. // DerivedV point type
  61. // Scalar scalar type
  62. // DIM point dimension
  63. // TType type of transformation
  64. // (Isometry,Affine,AffineCompact,Projective)
  65. // Inputs:
  66. // X #V by DIM first list of points
  67. // Y #V by DIM second list of points
  68. // includeScaling if scaling should be allowed
  69. // includeReflections if R is allowed to be a reflection
  70. // Outputs:
  71. // T transformation that minimizes error
  72. //
  73. // Example:
  74. // MatrixXd X, Y; (containing 3d points as rows)
  75. // AffineCompact3d T;
  76. // igl::procrustes(X,Y,true,false,T);
  77. // MatrixXd Xprime = (X * T.linear()).rowwise() + T.translation().transpose();
  78. template <
  79. typename DerivedX,
  80. typename DerivedY,
  81. typename Scalar,
  82. int DIM,
  83. int TType>
  84. IGL_INLINE void procrustes(
  85. const Eigen::PlainObjectBase<DerivedX>& X,
  86. const Eigen::PlainObjectBase<DerivedY>& Y,
  87. bool includeScaling,
  88. bool includeReflections,
  89. Eigen::Transform<Scalar,DIM,TType>& T);
  90. // Convenient wrapper that returns S=scale*R instead of scale and R separately
  91. template <
  92. typename DerivedX,
  93. typename DerivedY,
  94. typename DerivedR,
  95. typename DerivedT>
  96. IGL_INLINE void procrustes(
  97. const Eigen::PlainObjectBase<DerivedX>& X,
  98. const Eigen::PlainObjectBase<DerivedY>& Y,
  99. bool includeScaling,
  100. bool includeReflections,
  101. Eigen::PlainObjectBase<DerivedR>& S,
  102. Eigen::PlainObjectBase<DerivedT>& t);
  103. // Convenient wrapper for rigid case (no scaling, no reflections)
  104. template <
  105. typename DerivedX,
  106. typename DerivedY,
  107. typename DerivedR,
  108. typename DerivedT>
  109. IGL_INLINE void procrustes(
  110. const Eigen::PlainObjectBase<DerivedX>& X,
  111. const Eigen::PlainObjectBase<DerivedY>& Y,
  112. Eigen::PlainObjectBase<DerivedR>& R,
  113. Eigen::PlainObjectBase<DerivedT>& t);
  114. // Convenient wrapper for 2D case.
  115. template <
  116. typename DerivedX,
  117. typename DerivedY,
  118. typename Scalar,
  119. typename DerivedT>
  120. IGL_INLINE void procrustes(
  121. const Eigen::PlainObjectBase<DerivedX>& X,
  122. const Eigen::PlainObjectBase<DerivedY>& Y,
  123. Eigen::Rotation2D<Scalar>& R,
  124. Eigen::PlainObjectBase<DerivedT>& t);
  125. }
  126. #ifndef IGL_STATIC_LIBRARY
  127. #include "procrustes.cpp"
  128. #endif
  129. #endif