00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef TOON_INCLUDE_SO2_H
00032 #define TOON_INCLUDE_SO2_H
00033
00034 #include <TooN/TooN.h>
00035 #include <TooN/helpers.h>
00036
00037 namespace TooN {
00038
00039 template<typename Precision> class SO2;
00040 template <typename Precision> class SE2;
00041
00042 template<typename Precision> inline std::istream & operator>>(std::istream &, SO2<Precision> & );
00043 template<typename Precision> inline std::istream & operator>>(std::istream &, SE2<Precision> & );
00044
00049 template<typename Precision = double>
00050 class SO2 {
00051 friend std::istream& operator>> <Precision>(std::istream&, SO2& );
00052 friend std::istream& operator>> <Precision>(std::istream&, SE2<Precision>& );
00053
00054 public:
00056 SO2() : my_matrix(Identity) {}
00057
00059 SO2(const Matrix<2,2,Precision>& rhs) { *this = rhs; }
00060
00062 SO2(const Precision l) { *this = exp(l); }
00063
00066 template <int R, int C, typename P, typename A>
00067 inline SO2& operator=(const Matrix<R,C,P,A>& rhs){
00068 my_matrix = rhs;
00069 coerce();
00070 return *this;
00071 }
00072
00074 void coerce(){
00075 my_matrix[0] = unit(my_matrix[0]);
00076 my_matrix[1] -= my_matrix[0] * (my_matrix[0]*my_matrix[1]);
00077 my_matrix[1] = unit(my_matrix[1]);
00078 }
00079
00081 inline static SO2 exp(const Precision & d){
00082 SO2<Precision> result;
00083 result.my_matrix[0][0] = result.my_matrix[1][1] = cos(d);
00084 result.my_matrix[1][0] = sin(d);
00085 result.my_matrix[0][1] = -result.my_matrix[1][0];
00086 return result;
00087 }
00088
00090 Precision ln() const { return atan2(my_matrix[1][0], my_matrix[0][0]); }
00091
00093 SO2 inverse() const { return SO2(*this, Invert()); }
00094
00096 SO2& operator *=(const SO2& rhs){
00097 my_matrix=my_matrix*rhs.my_matrix;
00098 return *this;
00099 }
00100
00102 SO2 operator *(const SO2& rhs) const { return SO2(*this,rhs); }
00103
00105 const Matrix<2,2,Precision>& get_matrix() const {return my_matrix;}
00106
00108 static Matrix<2,2,Precision> generator() {
00109 Matrix<2,2,Precision> result;
00110 result[0] = makeVector(0,-1);
00111 result[1] = makeVector(1,0);
00112 return result;
00113 }
00114
00115 private:
00116 struct Invert {};
00117 inline SO2(const SO2& so2, const Invert&) : my_matrix(so2.my_matrix.T()) {}
00118 inline SO2(const SO2& a, const SO2& b) : my_matrix(a.my_matrix*b.my_matrix) {}
00119
00120 Matrix<2,2,Precision> my_matrix;
00121 };
00122
00125 template <typename Precision>
00126 inline std::ostream& operator<< (std::ostream& os, const SO2<Precision> & rhs){
00127 return os << rhs.get_matrix();
00128 }
00129
00132 template <typename Precision>
00133 inline std::istream& operator>>(std::istream& is, SO2<Precision>& rhs){
00134 return is >> rhs.my_matrix;
00135 rhs.coerce();
00136 }
00137
00140 template<int D, typename P1, typename PV, typename Accessor>
00141 inline Vector<2, typename Internal::MultiplyType<P1, PV>::type> operator*(const SO2<P1> & lhs, const Vector<D, PV, Accessor> & rhs){
00142 return lhs.get_matrix() * rhs;
00143 }
00144
00147 template<int D, typename P1, typename PV, typename Accessor>
00148 inline Vector<2, typename Internal::MultiplyType<PV,P1>::type> operator*(const Vector<D, PV, Accessor>& lhs, const SO2<P1> & rhs){
00149 return lhs * rhs.get_matrix();
00150 }
00151
00154 template <int R, int C, typename P1, typename P2, typename Accessor>
00155 inline Matrix<2,C,typename Internal::MultiplyType<P1,P2>::type> operator*(const SO2<P1> & lhs, const Matrix<R,C,P2,Accessor>& rhs){
00156 return lhs.get_matrix() * rhs;
00157 }
00158
00161 template <int R, int C, typename P1, typename P2, typename Accessor>
00162 inline Matrix<R,2,typename Internal::MultiplyType<P1,P2>::type> operator*(const Matrix<R,C,P1,Accessor>& lhs, const SO2<P2>& rhs){
00163 return lhs * rhs.get_matrix();
00164 }
00165
00166 }
00167
00168 #endif