diff --git a/gtsam/geometry/Rot2.cpp b/gtsam/geometry/Rot2.cpp index d43b9b12d..9bf631e50 100644 --- a/gtsam/geometry/Rot2.cpp +++ b/gtsam/geometry/Rot2.cpp @@ -131,11 +131,14 @@ Rot2 Rot2::relativeBearing(const Point2& d, OptionalJacobian<1, 2> H) { /* ************************************************************************* */ Rot2 Rot2::ClosestTo(const Matrix2& M) { - double c = M(0, 0); - double s = M(1, 0); - double theta_rad = std::atan2(s, c); - c = cos(theta_rad); - s = sin(theta_rad); + Eigen::JacobiSVD svd(M, Eigen::ComputeFullU | Eigen::ComputeFullV); + const Matrix2& U = svd.matrixU(); + const Matrix2& V = svd.matrixV(); + const double det = (U * V.transpose()).determinant(); + Matrix2 M_prime = (U * Vector2(1, det).asDiagonal() * V.transpose()); + + double c = M_prime(0, 0); + double s = M_prime(1, 0); return Rot2::fromCosSin(c, s); }