gtsam/gtsam/geometry/Rot2.cpp

132 lines
3.6 KiB
C++

/* ----------------------------------------------------------------------------
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
* Atlanta, Georgia 30332-0415
* All Rights Reserved
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
* See LICENSE for the license information
* -------------------------------------------------------------------------- */
/**
* @file Rot2.cpp
* @date Dec 9, 2009
* @author Frank Dellaert
* @brief 2D Rotations
*/
#include <gtsam/geometry/Rot2.h>
#include <iostream>
using namespace std;
namespace gtsam {
/* ************************************************************************* */
Rot2 Rot2::fromCosSin(double c, double s) {
if (fabs(c * c + s * s - 1.0) > 1e-9) {
double norm_cs = sqrt(c*c + s*s);
c = c/norm_cs;
s = s/norm_cs;
}
return Rot2(c, s);
}
/* ************************************************************************* */
Rot2 Rot2::atan2(double y, double x) {
Rot2 R(x, y);
return R.normalize();
}
/* ************************************************************************* */
void Rot2::print(const string& s) const {
cout << s << ": " << theta() << endl;
}
/* ************************************************************************* */
bool Rot2::equals(const Rot2& R, double tol) const {
return fabs(c_ - R.c_) <= tol && fabs(s_ - R.s_) <= tol;
}
/* ************************************************************************* */
Rot2& Rot2::normalize() {
double scale = c_*c_ + s_*s_;
if(fabs(scale-1.0)>1e-10) {
scale = pow(scale, -0.5);
c_ *= scale;
s_ *= scale;
}
return *this;
}
/* ************************************************************************* */
Rot2 Rot2::Expmap(const Vector1& v, OptionalJacobian<1, 1> H) {
if (H)
*H = I_1x1;
if (v.isZero())
return (Rot2());
else
return Rot2::fromAngle(v(0));
}
/* ************************************************************************* */
Vector1 Rot2::Logmap(const Rot2& r, OptionalJacobian<1, 1> H) {
if (H)
*H = I_1x1;
Vector1 v;
v << r.theta();
return v;
}
/* ************************************************************************* */
Matrix2 Rot2::matrix() const {
Matrix2 rvalue_;
rvalue_ << c_, -s_, s_, c_;
return rvalue_;
}
/* ************************************************************************* */
Matrix2 Rot2::transpose() const {
Matrix2 rvalue_;
rvalue_ << c_, s_, -s_, c_;
return rvalue_;
}
/* ************************************************************************* */
// see doc/math.lyx, SO(2) section
Point2 Rot2::rotate(const Point2& p, OptionalJacobian<2, 1> H1,
OptionalJacobian<2, 2> H2) const {
const Point2 q = Point2(c_ * p.x() + -s_ * p.y(), s_ * p.x() + c_ * p.y());
if (H1) *H1 << -q.y(), q.x();
if (H2) *H2 = matrix();
return q;
}
/* ************************************************************************* */
// see doc/math.lyx, SO(2) section
Point2 Rot2::unrotate(const Point2& p,
OptionalJacobian<2, 1> H1, OptionalJacobian<2, 2> H2) const {
const Point2 q = Point2(c_ * p.x() + s_ * p.y(), -s_ * p.x() + c_ * p.y());
if (H1) *H1 << q.y(), -q.x();
if (H2) *H2 = transpose();
return q;
}
/* ************************************************************************* */
Rot2 Rot2::relativeBearing(const Point2& d, OptionalJacobian<1, 2> H) {
double x = d.x(), y = d.y(), d2 = x * x + y * y, n = sqrt(d2);
if(fabs(n) > 1e-5) {
if (H) {
*H << -y / d2, x / d2;
}
return Rot2::fromCosSin(x / n, y / n);
} else {
if (H) *H << 0.0, 0.0;
return Rot2();
}
}
/* ************************************************************************* */
} // gtsam