transform2D.h

Go to the documentation of this file.
00001 
00015 #ifndef _DLR_TRANSFORM2D_H_
00016 #define _DLR_TRANSFORM2D_H_
00017 
00018 #include <dlrNumeric/array2D.h>
00019 #include <dlrNumeric/vector2D.h>
00020 
00021 namespace dlr {
00022 
00023   namespace numeric {
00024     
00025     // Forward declaration.
00026     class Transform2DFunctor;
00027 
00028   
00034     class Transform2D {
00035     public:
00039       inline
00040       Transform2D()
00041         : m_00(1.0), m_01(0.0), m_02(0.0),
00042           m_10(0.0), m_11(1.0), m_12(0.0),
00043           m_20(0.0), m_21(0.0) {}
00044 
00062       inline
00063       Transform2D(double a00, double a01, double a02,
00064                   double a10, double a11, double a12,
00065                   double a20, double a21, double a22)
00066         : m_00(a00), m_01(a01), m_02(a02),
00067           m_10(a10), m_11(a11), m_12(a12),
00068           m_20(a20), m_21(a21) {
00069         this->normalize(a22);
00070       }
00071 
00078       Transform2D(const Array2D<double>& source);
00079 
00085       inline
00086       Transform2D(const Transform2D& src)
00087         : m_00(src.m_00), m_01(src.m_01), m_02(src.m_02),
00088           m_10(src.m_10), m_11(src.m_11), m_12(src.m_12),
00089           m_20(src.m_20), m_21(src.m_21) {}
00090 
00094       ~Transform2D() {}
00095 
00096 
00112       Transform2DFunctor
00113       getFunctor() const;
00114     
00115     
00122       Transform2D
00123       invert() const;
00124 
00125     
00143       void
00144       setTransform(double a00, double a01, double a02,
00145                    double a10, double a11, double a12,
00146                    double a20, double a21, double a22);
00147 
00170       void
00171       setValue(size_t row, size_t column, double value);
00172 
00188       template <size_t row, size_t column>
00189       void
00190       setValue(double value);
00191 
00201       template <size_t row, size_t column>
00202       double
00203       value() const;
00204 
00215       double
00216       operator()(size_t row, size_t column) const;
00217 
00225       Vector2D
00226       operator*(const Vector2D& vector0) const;
00227 
00234       Transform2D&
00235       operator=(const Transform2D& source);
00236 
00237     private:
00238       void normalize(double scaleFactor);
00239       
00240       double m_00, m_01, m_02;
00241       double m_10, m_11, m_12;
00242       double m_20, m_21;
00243 
00244     }; // class Transform2D
00245 
00246 
00247     /* ============== Helper classes ============== */
00248 
00249 
00253     class Transform2DFunctor
00254       : public std::unary_function<Vector2D, Vector2D> {
00255 
00256     public:
00257 
00263       Transform2DFunctor(const Transform2D& transform)
00264         : m_transform(transform) {}
00265 
00266     
00274       inline Vector2D
00275       operator()(const Vector2D& vec) const {return m_transform * vec;}
00276     
00277     private:
00278       Transform2D m_transform;
00279     };
00280   
00281   
00282     /* ============== Non-member functions ============== */
00283   
00299     Transform2D
00300     operator*(const Transform2D& transform0, const Transform2D& transform1);
00301 
00302   
00318     std::ostream&
00319     operator<<(std::ostream& stream, const Transform2D& transform0);
00320 
00321   
00334     std::istream&
00335     operator>>(std::istream& stream, Transform2D& transform0);
00336 
00337   } // namespace numeric
00338 
00339 } // namespace dlr
00340 
00341 
00342 /* ======= Declarations to maintain compatibility with legacy code. ======= */
00343 
00344 namespace dlr {
00345 
00346   using numeric::Transform2D;
00347   using numeric::Transform2DFunctor;
00348 
00349 } // namespace dlr
00350 
00351 
00352 /*******************************************************************
00353  * Member function definitions follow.  This would be a .C file
00354  * if it weren't templated.
00355  *******************************************************************/
00356 
00357 namespace dlr {
00358 
00359   namespace numeric {
00360     
00361     // This operator sets one element of the matrix representation of
00362     // the coordinate transform.  The case statements should optimize
00363     // away, since row and column are both known at compile time.
00364     template <size_t ROW, size_t COLUMN>
00365     void
00366     Transform2D::
00367     setValue(double value)
00368     {
00369       switch(ROW) {
00370       case 0:
00371         switch(COLUMN) {
00372         case 0: m_00 = value; return; break;
00373         case 1: m_01 = value; return; break;
00374         case 2: m_02 = value; return; break;
00375         default: break;
00376         }
00377         break;
00378       case 1:
00379         switch(COLUMN) {
00380         case 0: m_10 = value; return; break;
00381         case 1: m_11 = value; return; break;
00382         case 2: m_12 = value; return; break;
00383         default: break;
00384         }
00385         break;
00386       case 2:
00387         switch(COLUMN) {
00388         case 0: m_20 = value; return; break;
00389         case 1: m_21 = value; return; break;
00390         default: break;
00391         }
00392         break;
00393       default:
00394         break;
00395       }
00396       std::ostringstream message;
00397       message << "Indices (" << ROW << ", " << COLUMN << ") are out of bounds.";
00398       DLR_THROW(IndexException, "Transform2D::setValue<size_t, size_t>(double)",
00399                 message.str().c_str());
00400     }
00401 
00402   
00403     // This operator returns one element from the matrix
00404     // representation of the coordinate transform by value.
00405     // The case statements should optimize away, since row and column
00406     // are both known at compile time.
00407     template <size_t ROW, size_t COLUMN>
00408     double
00409     Transform2D::
00410     value() const
00411     {
00412       // // Avoid ugly duplication of code using ugly const_cast.
00413       // return const_cast<Transform2D*>(this)->value<ROW, COLUMN>();
00414       switch(ROW) {
00415       case 0:
00416         switch(COLUMN) {
00417         case 0: return m_00; break;
00418         case 1: return m_01; break;
00419         case 2: return m_02; break;
00420         default: break;
00421         }
00422         break;
00423       case 1:
00424         switch(COLUMN) {
00425         case 0: return m_10; break;
00426         case 1: return m_11; break;
00427         case 2: return m_12; break;
00428         default: break;
00429         }
00430         break;
00431       case 2:
00432         switch(COLUMN) {
00433         case 0: return m_20; break;
00434         case 1: return m_21; break;
00435         case 2: return 1.0; break;
00436         default: break;
00437         }
00438         break;
00439       default:
00440         break;
00441       }
00442       std::ostringstream message;
00443       message << "Index (" << ROW << ", " << COLUMN << ") out of bounds.";
00444       DLR_THROW3(IndexException, "Transform2D::value<>()",
00445                  message.str().c_str());
00446       return 0.0; // Dummy return to keep the compiler happy.
00447     }
00448 
00449   } // namespace numeric
00450 
00451 } // namespace dlr
00452   
00453 #endif // #ifndef _DLR_TRANSFORM2D_H_

Generated on Wed Nov 25 00:42:43 2009 for dlrUtilities Utility Library by  doxygen 1.5.8