transform3DTo2D.h

Go to the documentation of this file.
00001 
00015 #ifndef _DLR_TRANSFORM3DTO2D_H_
00016 #define _DLR_TRANSFORM3DTO2D_H_
00017 
00018 #include <dlrNumeric/array2D.h>
00019 #include <dlrNumeric/transform3D.h>
00020 #include <dlrNumeric/vector2D.h>
00021 #include <dlrNumeric/vector3D.h>
00022 
00023 namespace dlr {
00024 
00025   namespace numeric {
00026     
00027     // Forward declaration.
00028     class Transform3DTo2DFunctor;
00029 
00030 
00036     class Transform3DTo2D {
00037     public:
00041       Transform3DTo2D()
00042         : m_00(1.0), m_01(0.0), m_02(0.0), m_03(0.0),
00043           m_10(0.0), m_11(1.0), m_12(0.0), m_13(0.0),
00044           m_20(0.0), m_21(0.0), m_22(1.0), m_23(1.0)
00045         {}
00046 
00067       inline
00068       Transform3DTo2D(double a00, double a01, double a02, double a03,
00069                       double a10, double a11, double a12, double a13,
00070                       double a20, double a21, double a22, double a23)
00071         : m_00(a00), m_01(a01), m_02(a02), m_03(a03),
00072           m_10(a10), m_11(a11), m_12(a12), m_13(a13),
00073           m_20(a20), m_21(a21), m_22(a22), m_23(a23) {
00074       }
00075 
00082       Transform3DTo2D(const Array2D<double>& source);
00083 
00089       inline
00090       Transform3DTo2D(const Transform3DTo2D& src)
00091         : m_00(src.m_00), m_01(src.m_01), m_02(src.m_02), m_03(src.m_03),
00092           m_10(src.m_10), m_11(src.m_11), m_12(src.m_12), m_13(src.m_13),
00093           m_20(src.m_20), m_21(src.m_21), m_22(src.m_22), m_23(src.m_23) {
00094       }
00095 
00099       ~Transform3DTo2D() {}
00100 
00101 
00117       Transform3DTo2DFunctor
00118       getFunctor() const;
00119     
00120     
00141       void
00142       setTransform(double a00, double a01, double a02, double a03,
00143                    double a10, double a11, double a12, double a13,
00144                    double a20, double a21, double a22, double a23);
00145 
00155       // John Culbertson argues convincingly that this breaks the
00156       // abstraction, so we remove it for now.
00157       // 
00158       // template <size_t row, size_t column>
00159       // double&
00160       // value();
00161 
00171       template <size_t row, size_t column>
00172       double
00173       value() const;
00174 
00185       // John Culbertson argues convincingly that this breaks the
00186       // abstraction, so we remove it for now.
00187       // 
00188       // double&
00189       // operator()(size_t row, size_t column);
00190 
00201       double
00202       operator()(size_t row, size_t column) const;
00203 
00211       Vector2D
00212       operator*(const Vector3D& vector0) const;
00213 
00220       Transform3DTo2D&
00221       operator=(const Transform3DTo2D& source);
00222 
00223     private:
00224       void normalize(double scaleFactor);
00225 
00226       double m_00, m_01, m_02, m_03;
00227       double m_10, m_11, m_12, m_13;
00228       double m_20, m_21, m_22, m_23;
00229 
00230     }; // class Transform3DTo2D
00231 
00232 
00233     /* ============== Helper classes ============== */
00234 
00235 
00239     class Transform3DTo2DFunctor
00240       : public std::unary_function<Vector3D, Vector2D> {
00241 
00242     public:
00243 
00249       Transform3DTo2DFunctor(const Transform3DTo2D& transform)
00250         : m_transform(transform) {}
00251 
00252     
00260       inline Vector2D
00261       operator()(const Vector3D& vec) const {return m_transform * vec;}
00262     
00263     private:
00264       Transform3DTo2D m_transform;
00265     };
00266   
00267 
00268     /* ================ Non member functions below ================ */
00269 
00286     Transform3DTo2D
00287     operator*(const Transform3DTo2D& transform0, const Transform3D& transform1);
00288 
00289 
00305     std::ostream&
00306     operator<<(std::ostream& stream, const Transform3DTo2D& transform0);
00307 
00308   
00321     std::istream&
00322     operator>>(std::istream& stream, Transform3DTo2D& transform0);
00323   
00324     
00325   
00326   } // namespace numeric
00327 
00328 }; // namespace dlr
00329 
00330 
00331 /* ======= Declarations to maintain compatibility with legacy code. ======= */
00332 
00333 namespace dlr {
00334 
00335   using numeric::Transform3DTo2D;
00336   using numeric::Transform3DTo2DFunctor;
00337 
00338 } // namespace dlr
00339 
00340 
00341 /*******************************************************************
00342  * Member function definitions follow.  This would be a .C file
00343  * if it weren't templated.
00344  *******************************************************************/
00345 
00346 namespace dlr {
00347 
00348   namespace numeric {
00349     
00350     // This operator returns one element from the matrix
00351     // representation of the coordinate transform by reference.
00352     // The case statements should optimize away, since row and column
00353     // are both known at compile time.
00354 //   template <size_t ROW, size_t COLUMN>
00355 //   double&
00356 //   Transform3D::
00357 //   value()
00358 //   {
00359 //     switch(ROW) {
00360 //     case 0:
00361 //       switch(COLUMN) {
00362 //       case 0: return m_00; break;
00363 //       case 1: return m_01; break;
00364 //       case 2: return m_02; break;
00365 //       case 3: return m_03; break;
00366 //       default: break;
00367 //       }
00368 //       break;
00369 //     case 1:
00370 //       switch(COLUMN) {
00371 //       case 0: return m_10; break;
00372 //       case 1: return m_11; break;
00373 //       case 2: return m_12; break;
00374 //       case 3: return m_13; break;
00375 //       default: break;
00376 //       }
00377 //       break;
00378 //     case 2:
00379 //       switch(COLUMN) {
00380 //       case 0: return m_20; break;
00381 //       case 1: return m_21; break;
00382 //       case 2: return m_22; break;
00383 //       case 3: return m_23; break;
00384 //       default: break;
00385 //       }
00386 //       break;
00387 //     case 3:
00388 //       switch(COLUMN) {
00389 //       case 0: return m_30; break;
00390 //       case 1: return m_31; break;
00391 //       case 2: return m_32; break;
00392 //       default: break;
00393 //       }
00394 //       break;
00395 //     default:
00396 //       break;
00397 //     }
00398 //     std::ostringstream message;
00399 //     message << "Index (" << ROW << ", " << COLUMN << ") out of bounds.";
00400 //     DLR_THROW(IndexException, message.str().c_str());
00401 //     return m_00; // Dummy return to keep the compiler happy.
00402 //   }
00403 
00404     // This operator returns one element from the matrix
00405     // representation of the coordinate transform by value.
00406     // The case statements should optimize away, since row and column
00407     // are both known at compile time.
00408     template <size_t ROW, size_t COLUMN>
00409     double
00410     Transform3DTo2D::
00411     value() const
00412     {
00413       // // Avoid ugly duplication of code using ugly const_cast.
00414       // return const_cast<Transform3D*>(this)->value<ROW, COLUMN>();
00415       switch(ROW) {
00416       case 0:
00417         switch(COLUMN) {
00418         case 0: return m_00; break;
00419         case 1: return m_01; break;
00420         case 2: return m_02; break;
00421         case 3: return m_03; break;
00422         default: break;
00423         }
00424         break;
00425       case 1:
00426         switch(COLUMN) {
00427         case 0: return m_10; break;
00428         case 1: return m_11; break;
00429         case 2: return m_12; break;
00430         case 3: return m_13; break;
00431         default: break;
00432         }
00433         break;
00434       case 2:
00435         switch(COLUMN) {
00436         case 0: return m_20; break;
00437         case 1: return m_21; break;
00438         case 2: return m_22; break;
00439         case 3: return m_23; break;
00440         default: break;
00441         }
00442         break;
00443       default:
00444         break;
00445       }
00446       std::ostringstream message;
00447       message << "Indices (" << ROW << ", " << COLUMN << ") are out of bounds.";
00448       DLR_THROW(IndexException, "Transform3DTo2D::value<size_t, size_t>()",
00449                 message.str().c_str());
00450       return 0.0; // Dummy return to keep the compiler happy.
00451     }
00452 
00453   } // namespace numeric
00454 
00455 } // namespace dlr
00456 
00457 #endif // #ifndef _DLR_TRANSFORM3DTO2D_H_

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