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