// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2019 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #include "rigid_alignment.h" #include "polar_svd.h" #include "matlab_format.h" #include #include #include #include template < typename DerivedX, typename DerivedP, typename DerivedN, typename DerivedR, typename Derivedt > IGL_INLINE void igl::rigid_alignment( const Eigen::MatrixBase & _X, const Eigen::MatrixBase & P, const Eigen::MatrixBase & N, Eigen::PlainObjectBase & R, Eigen::PlainObjectBase & t) { typedef typename DerivedX::Scalar Scalar; typedef Eigen::Matrix MatrixXS; typedef Eigen::Matrix VectorXS; typedef Eigen::Matrix Matrix3S; const int k = _X.rows(); VectorXS Z = VectorXS::Zero(k,1); VectorXS I = VectorXS::Ones(k,1); DerivedX X = _X; R = DerivedR::Identity(3,3); t = Derivedt::Zero(1,3); // See gptoolbox, each iter could be O(1) instead of O(k) const int max_iters = 5; for(int iters = 0;iters > NNIJV; for(int i = 0;i NN(k,k*3); NN.setFromTriplets(NNIJV.begin(),NNIJV.end()); A = (NN * A).eval(); B = (NN * B).eval(); VectorXS u = (A.transpose() * A).ldlt().solve(A.transpose() * B); Derivedt ti = u.tail(3).transpose(); Matrix3S W; W<< 0, u(2),-u(1), -u(2), 0, u(0), u(1),-u(0), 0; // strayed from a perfect rotation. Correct it. const double x = u.head(3).stableNorm(); DerivedR Ri; if(x == 0) { Ri = DerivedR::Identity(3,3); }else { Ri = DerivedR::Identity(3,3) + sin(x)/x*W + (1.0-cos(x))/(x*x)*W*W; } R = (R*Ri).eval(); t = (t*Ri + ti).eval(); X = ((_X*R).rowwise()+t).eval(); } } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation template void igl::rigid_alignment, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix, Eigen::Matrix >(Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #endif