123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- #ifndef SOPHUS_ROTATION_MATRIX_HPP
- #define SOPHUS_ROTATION_MATRIX_HPP
- #include <eigen3/Eigen/Dense>
- #include <eigen3/Eigen/SVD>
- #include "types.hpp"
- namespace Sophus {
- template <class D>
- SOPHUS_FUNC bool isOrthogonal(Eigen::MatrixBase<D> const& R) {
- using Scalar = typename D::Scalar;
- static int const N = D::RowsAtCompileTime;
- static int const M = D::ColsAtCompileTime;
- static_assert(N == M, "must be a square matrix");
- static_assert(N >= 2, "must have compile time dimension >= 2");
- return (R * R.transpose() - Matrix<Scalar, N, N>::Identity()).norm() <
- Constants<Scalar>::epsilon();
- }
- template <class D>
- SOPHUS_FUNC bool isScaledOrthogonalAndPositive(Eigen::MatrixBase<D> const& sR) {
- using Scalar = typename D::Scalar;
- static int const N = D::RowsAtCompileTime;
- static int const M = D::ColsAtCompileTime;
- using std::pow;
- using std::sqrt;
- Scalar det = sR.determinant();
- if (det <= Scalar(0)) {
- return false;
- }
- Scalar scale_sqr = pow(det, Scalar(2. / N));
- static_assert(N == M, "must be a square matrix");
- static_assert(N >= 2, "must have compile time dimension >= 2");
- return (sR * sR.transpose() - scale_sqr * Matrix<Scalar, N, N>::Identity())
- .template lpNorm<Eigen::Infinity>() <
- sqrt(Constants<Scalar>::epsilon());
- }
- template <class D>
- SOPHUS_FUNC enable_if_t<
- std::is_floating_point<typename D::Scalar>::value,
- Matrix<typename D::Scalar, D::RowsAtCompileTime, D::RowsAtCompileTime>>
- makeRotationMatrix(Eigen::MatrixBase<D> const& R) {
- using Scalar = typename D::Scalar;
- static int const N = D::RowsAtCompileTime;
- static int const M = D::ColsAtCompileTime;
- static_assert(N == M, "must be a square matrix");
- static_assert(N >= 2, "must have compile time dimension >= 2");
- Eigen::JacobiSVD<Matrix<Scalar, N, N>> svd(
- R, Eigen::ComputeFullU | Eigen::ComputeFullV);
-
- Scalar d = (svd.matrixU() * svd.matrixV().transpose()).determinant();
-
-
- Matrix<Scalar, N, N> Diag = Matrix<Scalar, N, N>::Identity();
- Diag(N - 1, N - 1) = d;
- return svd.matrixU() * Diag * svd.matrixV().transpose();
- }
- }
- #endif
|