Эх сурвалжийг харах

more templates, conformalized style

Former-commit-id: cec8ba94ab98ae1c26bd20a28e5c4c9d5bb18603
Alec Jacobson 10 жил өмнө
parent
commit
7fc3b097b9

+ 1 - 0
include/igl/fit_rigid.cpp

@@ -14,6 +14,7 @@ IGL_INLINE void igl::fit_rigid(
   Eigen::Rotation2Dd & R,
   Eigen::RowVector2d & t)
 {
+  using namespace Eigen;
   Matrix2d Rmat;
   procrustes(A,B,Rmat,t);
   R.fromRotationMatrix(Rmat);

+ 83 - 56
include/igl/procrustes.cpp

@@ -9,86 +9,108 @@
 #include "polar_svd.h"
 #include "polar_dec.h"
  
-template <typename DerivedV, typename Scalar, typename DerivedR, typename DerivedT>
+template <
+  typename DerivedX, 
+  typename DerivedY, 
+  typename Scalar, 
+  typename DerivedR, 
+  typename DerivedT>
 IGL_INLINE void igl::procrustes(
-    const Eigen::PlainObjectBase<DerivedV>& X,
-    const Eigen::PlainObjectBase<DerivedV>& Y,
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
     bool includeScaling,
     bool includeReflections,
     Scalar& scale,
     Eigen::PlainObjectBase<DerivedR>& R,
     Eigen::PlainObjectBase<DerivedT>& t)
 {
-   using namespace Eigen;
-   assert (X.rows() == Y.rows() && "Same number of points");
-   assert(X.cols() == Y.cols() && "Points have same dimensions");
+  using namespace Eigen;
+  assert (X.rows() == Y.rows() && "Same number of points");
+  assert(X.cols() == Y.cols() && "Points have same dimensions");
 
-   // Center data
-   const VectorXd Xmean = X.colwise().mean();      
-   const VectorXd Ymean = Y.colwise().mean();      
-   MatrixXd XC = X.rowwise() - Xmean.transpose();
-   MatrixXd YC = Y.rowwise() - Ymean.transpose();
+  // Center data
+  const VectorXd Xmean = X.colwise().mean();      
+  const VectorXd Ymean = Y.colwise().mean();      
+  MatrixXd XC = X.rowwise() - Xmean.transpose();
+  MatrixXd YC = Y.rowwise() - Ymean.transpose();
 
-   // Scale
-   scale = 1.;
-   if (includeScaling)
-   {
-       double scaleX = XC.norm() / XC.rows();
-       double scaleY = YC.norm() / YC.rows();
-       scale = scaleY/scaleX;
-       XC *= scale;
-       assert (abs(XC.norm() / XC.rows() - scaleY) < 1e-8);
-   }
+  // Scale
+  scale = 1.;
+  if (includeScaling)
+  {
+     double scaleX = XC.norm() / XC.rows();
+     double scaleY = YC.norm() / YC.rows();
+     scale = scaleY/scaleX;
+     XC *= scale;
+     assert (abs(XC.norm() / XC.rows() - scaleY) < 1e-8);
+  }
 
-   // Rotation 
-   MatrixXd S = XC.transpose() * YC; 
-   MatrixXd T;
-   if (includeReflections)
-     polar_dec(S,R,T);
-   else
-     polar_svd(S,R,T);
-   R.transposeInPlace();
+  // Rotation 
+  MatrixXd S = XC.transpose() * YC; 
+  MatrixXd T;
+  if (includeReflections)
+  {
+    polar_dec(S,R,T);
+  }else
+  {
+    polar_svd(S,R,T);
+  }
+  R.transposeInPlace();
 
-   // Translation
-   t = Ymean - scale*R.transpose()*Xmean;
+  // Translation
+  t = Ymean - scale*R.transpose()*Xmean;
 }
 
-template <typename DerivedV, typename DerivedR, typename DerivedT>
+
+template <
+  typename DerivedX, 
+  typename DerivedY, 
+  typename Scalar, 
+  int DIM, 
+  int TType>
 IGL_INLINE void igl::procrustes(
-    const Eigen::PlainObjectBase<DerivedV>& X,
-    const Eigen::PlainObjectBase<DerivedV>& Y,
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
     bool includeScaling,
     bool includeReflections,
-    Eigen::PlainObjectBase<DerivedR>& S,
-    Eigen::PlainObjectBase<DerivedT>& t)
+    Eigen::Transform<Scalar,DIM,TType>& T)
 {
+  using namespace Eigen;
   double scale;
-  procrustes(X,Y,includeScaling,includeReflections,scale,S,t);
-  S *= scale;
-}
+  MatrixXd R;
+  VectorXd t;
+  procrustes(X,Y,includeScaling,includeReflections,scale,R,t);
 
+  // Combine
+  T = Translation<Scalar,DIM>(t) * R * Scaling(scale);
+}
 
-template <typename DerivedV, typename Scalar, int DIM, int TType>
+template <
+  typename DerivedX, 
+  typename DerivedY, 
+  typename DerivedR, 
+  typename DerivedT>
 IGL_INLINE void igl::procrustes(
-    const Eigen::PlainObjectBase<DerivedV>& X,
-    const Eigen::PlainObjectBase<DerivedV>& Y,
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
     bool includeScaling,
     bool includeReflections,
-    Eigen::Transform<Scalar,DIM,TType>& T)
+    Eigen::PlainObjectBase<DerivedR>& S,
+    Eigen::PlainObjectBase<DerivedT>& t)
 {
   double scale;
-  MatrixXd R;
-  VectorXd t;
-  procrustes(X,Y,includeScaling,includeReflections,scale,R,t);
-
-   // Combine
-   T = Translation<Scalar,DIM>(t) * R * Scaling(scale);
+  procrustes(X,Y,includeScaling,includeReflections,scale,S,t);
+  S *= scale;
 }
 
-template <typename DerivedV, typename DerivedR, typename DerivedT>
+template <
+  typename DerivedX, 
+  typename DerivedY, 
+  typename DerivedR, 
+  typename DerivedT>
 IGL_INLINE void igl::procrustes(
-    const Eigen::PlainObjectBase<DerivedV>& X,
-    const Eigen::PlainObjectBase<DerivedV>& Y,
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
     Eigen::PlainObjectBase<DerivedR>& R,
     Eigen::PlainObjectBase<DerivedT>& t)
 {
@@ -96,15 +118,20 @@ IGL_INLINE void igl::procrustes(
   procrustes(X,Y,false,false,R,t);
 }
 
-template <typename DerivedV, typename Scalar, typename DerivedT>
+template <
+  typename DerivedX, 
+  typename DerivedY, 
+  typename Scalar, 
+  typename DerivedT>
 IGL_INLINE void igl::procrustes(
-    const Eigen::PlainObjectBase<DerivedV>& X,
-    const Eigen::PlainObjectBase<DerivedV>& Y,
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
     Eigen::Rotation2D<Scalar>& R,
     Eigen::PlainObjectBase<DerivedT>& t)
 {
+  using namespace Eigen;
   assert (X.cols() == 2 && Y.cols() == 2 && "Points must have dimension 2");
   Matrix2d Rmat;
   procrustes(X,Y,false,false,Rmat,t);
   R.fromRotationMatrix(Rmat);
-}
+}

+ 111 - 90
include/igl/procrustes.h

@@ -14,102 +14,123 @@
 
 namespace igl
 {
-    // Solve Procrustes problem in d dimensions.
-    // Given two point sets X,Y in R^d find best scale s, orthogonal R  and translation t 
-    // s.t. |s*X*R + t - Y|^2 is minimized.
-    //
-    // Example:
-    // MatrixXd X, Y; (containing 3d points as rows)
-    // double scale;
-    // MatrixXd R;
-    // VectorXd t;
-    // igl::procrustes(X,Y,true,false,scale,R,t);
-    // R *= scale;
-    // MatrixXd Xprime = (X * R).rowwise() + t.transpose();
-    //
-    // Templates:
-    //    DerivedV point type
-    //    Scalar   scalar type
-    //    DerivedR type of R
-    //    DerivedT type of t
-    // Inputs:
-    //    X  #V by DIM first list of points
-    //    Y  #V by DIM second list of points
-    //    includeScaling  if scaling should be allowed
-    //    includeReflections  if R is allowed to be a reflection
-    // Outputs:
-    //    scale  scaling
-    //    R      orthogonal matrix
-    //    t      translation
-    template <typename DerivedV, typename Scalar, typename DerivedR, typename DerivedT>
-    IGL_INLINE void procrustes(
-        const Eigen::PlainObjectBase<DerivedV>& X,
-        const Eigen::PlainObjectBase<DerivedV>& Y,
-        bool includeScaling,
-        bool includeReflections,
-        Scalar& scale,
-        Eigen::PlainObjectBase<DerivedR>& R,
-        Eigen::PlainObjectBase<DerivedT>& t);
+  // Solve Procrustes problem in d dimensions.  Given two point sets X,Y in R^d
+  // find best scale s, orthogonal R  and translation t s.t. |s*X*R + t - Y|^2
+  // is minimized.
+  //
+  // Templates:
+  //    DerivedV point type
+  //    Scalar   scalar type
+  //    DerivedR type of R
+  //    DerivedT type of t
+  // Inputs:
+  //    X  #V by DIM first list of points
+  //    Y  #V by DIM second list of points
+  //    includeScaling  if scaling should be allowed
+  //    includeReflections  if R is allowed to be a reflection
+  // Outputs:
+  //    scale  scaling
+  //    R      orthogonal matrix
+  //    t      translation
+  //
+  // Example:
+  //   MatrixXd X, Y; (containing 3d points as rows)
+  //   double scale;
+  //   MatrixXd R;
+  //   VectorXd t;
+  //   igl::procrustes(X,Y,true,false,scale,R,t);
+  //   R *= scale;
+  //   MatrixXd Xprime = (X * R).rowwise() + t.transpose();
+  //
+  template <
+    typename DerivedX, 
+    typename DerivedY, 
+    typename Scalar, 
+    typename DerivedR, 
+    typename DerivedT>
+  IGL_INLINE void procrustes(
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
+    bool includeScaling,
+    bool includeReflections,
+    Scalar& scale,
+    Eigen::PlainObjectBase<DerivedR>& R,
+    Eigen::PlainObjectBase<DerivedT>& t);
+  // Same as above but returns Eigen transformation object.
+  //
+  // Templates:
+  //    DerivedV point type
+  //    Scalar   scalar type
+  //    DIM      point dimension
+  //    TType    type of transformation
+  //             (Isometry,Affine,AffineCompact,Projective)
+  // Inputs:
+  //    X  #V by DIM first list of points
+  //    Y  #V by DIM second list of points
+  //    includeScaling  if scaling should be allowed
+  //    includeReflections  if R is allowed to be a reflection
+  // Outputs:
+  //    T  transformation that minimizes error    
+  //
+  // Example:
+  //   MatrixXd X, Y; (containing 3d points as rows)
+  //   AffineCompact3d T;
+  //   igl::procrustes(X,Y,true,false,T);
+  //   MatrixXd Xprime = (X * T.linear()).rowwise() + T.translation().transpose();
+  template <
+    typename DerivedV, 
+    typename Scalar, 
+    int DIM, 
+    int TType>
+  IGL_INLINE void procrustes(
+    const Eigen::PlainObjectBase<DerivedV>& X,
+    const Eigen::PlainObjectBase<DerivedV>& Y,
+    bool includeScaling,
+    bool includeReflections,
+    Eigen::Transform<Scalar,DIM,TType>& T);
 
 
-    // Same as above but returns Eigen transformation object.
-    //
-    // Example:
-    // MatrixXd X, Y; (containing 3d points as rows)
-    // AffineCompact3d T;
-    // igl::procrustes(X,Y,true,false,T);
-    // MatrixXd Xprime = (X * T.linear()).rowwise() + T.translation().transpose();
-    // Templates:
-    //    DerivedV point type
-    //    Scalar   scalar type
-    //    DIM      point dimension
-    //    TType    type of transformation (Isometry,Affine,AffineCompact,Projective)
-    // Inputs:
-    //    X  #V by DIM first list of points
-    //    Y  #V by DIM second list of points
-    //    includeScaling  if scaling should be allowed
-    //    includeReflections  if R is allowed to be a reflection
-    // Outputs:
-    //    T  transformation that minimizes error    
-    template <typename DerivedV, typename Scalar, int DIM, int TType>
-    IGL_INLINE void procrustes(
-        const Eigen::PlainObjectBase<DerivedV>& X,
-        const Eigen::PlainObjectBase<DerivedV>& Y,
-        bool includeScaling,
-        bool includeReflections,
-        Eigen::Transform<Scalar,DIM,TType>& T);
+  // Convenient wrapper that returns S=scale*R instead of scale and R separately
+  template <
+    typename DerivedX, 
+    typename DerivedY, 
+    typename DerivedR, 
+    typename DerivedT>
+  IGL_INLINE void procrustes(
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
+    bool includeScaling,
+    bool includeReflections,
+    Eigen::PlainObjectBase<DerivedR>& S,
+    Eigen::PlainObjectBase<DerivedT>& t);
 
+  // Convenient wrapper for rigid case (no scaling, no reflections)
+  template <
+    typename DerivedX, 
+    typename DerivedY, 
+    typename DerivedR, 
+    typename DerivedT>
+  IGL_INLINE void procrustes(
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
+    Eigen::PlainObjectBase<DerivedR>& R,
+    Eigen::PlainObjectBase<DerivedT>& t);
 
-    // Convenient wrapper that returns S=scale*R instead of scale and R separately
-    template <typename DerivedV, typename DerivedR, typename DerivedT>
-    IGL_INLINE void procrustes(
-        const Eigen::PlainObjectBase<DerivedV>& X,
-        const Eigen::PlainObjectBase<DerivedV>& Y,
-        bool includeScaling,
-        bool includeReflections,
-        Eigen::PlainObjectBase<DerivedR>& S,
-        Eigen::PlainObjectBase<DerivedT>& t);
-
-    // Convenient wrapper for rigid case (no scaling, no reflections)
-    template <typename DerivedV, typename DerivedR, typename DerivedT>
-    IGL_INLINE void procrustes(
-        const Eigen::PlainObjectBase<DerivedV>& X,
-        const Eigen::PlainObjectBase<DerivedV>& Y,
-        Eigen::PlainObjectBase<DerivedR>& R,
-        Eigen::PlainObjectBase<DerivedT>& t);
-
-    // Convenient wrapper for 2D case.
-    template <typename DerivedV, typename Scalar, typename DerivedT>
-    IGL_INLINE void procrustes(
-        const Eigen::PlainObjectBase<DerivedV>& X,
-        const Eigen::PlainObjectBase<DerivedV>& Y,
-        Eigen::Rotation2D<Scalar>& R,
-        Eigen::PlainObjectBase<DerivedT>& t);
-
+  // Convenient wrapper for 2D case.
+  template <
+    typename DerivedX, 
+    typename DerivedY, 
+    typename Scalar, 
+    typename DerivedT>
+  IGL_INLINE void procrustes(
+    const Eigen::PlainObjectBase<DerivedX>& X,
+    const Eigen::PlainObjectBase<DerivedY>& Y,
+    Eigen::Rotation2D<Scalar>& R,
+    Eigen::PlainObjectBase<DerivedT>& t);
 }
 
 #ifndef IGL_STATIC_LIBRARY
-    #include "procrustes.cpp"
+  #include "procrustes.cpp"
 #endif
 
-#endif
+#endif