transform3D.h

Go to the documentation of this file.
00001 
00015 #ifndef _DLR_TRANSFORM3D_H_
00016 #define _DLR_TRANSFORM3D_H_
00017 
00018 #include <dlrNumeric/array2D.h>
00019 #include <dlrNumeric/vector3D.h>
00020 
00021 namespace dlr {
00022 
00023   namespace numeric {
00024     
00025     // Forward declaration.
00026     class Transform3DFunctor;
00027 
00028   
00034     class Transform3D {
00035     public:
00036 
00040       inline
00041       Transform3D()
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(0.0),
00045           m_30(0.0), m_31(0.0), m_32(0.0) {}
00046 
00072       inline
00073       Transform3D(double a00, double a01, double a02, double a03,
00074                   double a10, double a11, double a12, double a13,
00075                   double a20, double a21, double a22, double a23,
00076                   double a30, double a31, double a32, double a33)
00077         : m_00(a00), m_01(a01), m_02(a02), m_03(a03),
00078           m_10(a10), m_11(a11), m_12(a12), m_13(a13),
00079           m_20(a20), m_21(a21), m_22(a22), m_23(a23),
00080           m_30(a30), m_31(a31), m_32(a32) {
00081         this->normalize(a33);
00082       }
00083 
00090       Transform3D(const Array2D<double>& source);
00091 
00097       inline
00098       Transform3D(const Transform3D& src)
00099         : m_00(src.m_00), m_01(src.m_01), m_02(src.m_02), m_03(src.m_03),
00100           m_10(src.m_10), m_11(src.m_11), m_12(src.m_12), m_13(src.m_13),
00101           m_20(src.m_20), m_21(src.m_21), m_22(src.m_22), m_23(src.m_23),
00102           m_30(src.m_30), m_31(src.m_31), m_32(src.m_32) {}
00103 
00107       ~Transform3D() {}
00108 
00109 
00125       Transform3DFunctor
00126       getFunctor() const;
00127     
00128     
00135       Transform3D
00136       invert() const;
00137 
00138     
00164       void
00165       setTransform(double a00, double a01, double a02, double a03,
00166                    double a10, double a11, double a12, double a13,
00167                    double a20, double a21, double a22, double a23,
00168                    double a30, double a31, double a32, double a33);
00169 
00170 
00171 
00194       void
00195       setValue(size_t row, size_t column, double value);
00196 
00197 
00213       template <size_t row, size_t column>
00214       void
00215       setValue(double value);
00216 
00217     
00228       template <size_t row, size_t column>
00229       double
00230       value() const;
00231 
00232 
00243       double
00244       operator()(size_t row, size_t column) const;
00245 
00246     
00254       Vector3D
00255       operator*(const Vector3D& vector0) const;
00256 
00257     
00264       Transform3D&
00265       operator=(const Transform3D& source);
00266 
00267     
00268     private:
00269       void normalize(double scaleFactor);
00270       
00271       double m_00, m_01, m_02, m_03;
00272       double m_10, m_11, m_12, m_13;
00273       double m_20, m_21, m_22, m_23;
00274       double m_30, m_31, m_32;
00275 
00276     }; // class Transform3D
00277 
00278 
00279     /* ============== Helper classes ============== */
00280 
00281 
00285     class Transform3DFunctor
00286       : public std::unary_function<Vector3D, Vector3D> {
00287 
00288     public:
00289 
00295       Transform3DFunctor(const Transform3D& transform)
00296         : m_transform(transform) {}
00297 
00298     
00306       inline Vector3D
00307       operator()(const Vector3D& vec) const {return m_transform * vec;}
00308     
00309     private:
00310       Transform3D m_transform;
00311     };
00312   
00313   
00314     /* ============== Non-member functions ============== */
00315   
00331     Transform3D
00332     operator*(const Transform3D& transform0, const Transform3D& transform1);
00333 
00334   
00351     std::ostream&
00352     operator<<(std::ostream& stream, const Transform3D& transform0);
00353 
00354   
00367     std::istream&
00368     operator>>(std::istream& stream, Transform3D& transform0);
00369   
00370   } // namespace numeric
00371 
00372 } // namespace dlr
00373 
00374 
00375 /* ======= Declarations to maintain compatibility with legacy code. ======= */
00376 
00377 namespace dlr {
00378 
00379   using numeric::Transform3D;
00380   using numeric::Transform3DFunctor;
00381 
00382 } // namespace dlr
00383 
00384 
00385 /*******************************************************************
00386  * Member function definitions follow.  This would be a .C file
00387  * if it weren't templated.
00388  *******************************************************************/
00389 
00390 namespace dlr {
00391 
00392   namespace numeric {
00393     
00394     // This operator sets one element of the matrix representation of
00395     // the coordinate transform.  The case statements should optimize
00396     // away, since row and column are both known at compile time.
00397     template <size_t ROW, size_t COLUMN>
00398     void
00399     Transform3D::
00400     setValue(double value)
00401     {
00402       switch(ROW) {
00403       case 0:
00404         switch(COLUMN) {
00405         case 0: m_00 = value; return; break;
00406         case 1: m_01 = value; return; break;
00407         case 2: m_02 = value; return; break;
00408         case 3: m_03 = value; return; break;
00409         default: break;
00410         }
00411         break;
00412       case 1:
00413         switch(COLUMN) {
00414         case 0: m_10 = value; return; break;
00415         case 1: m_11 = value; return; break;
00416         case 2: m_12 = value; return; break;
00417         case 3: m_13 = value; return; break;
00418         default: break;
00419         }
00420         break;
00421       case 2:
00422         switch(COLUMN) {
00423         case 0: m_20 = value; return; break;
00424         case 1: m_21 = value; return; break;
00425         case 2: m_22 = value; return; break;
00426         case 3: m_23 = value; return; break;
00427         default: break;
00428         }
00429         break;
00430       case 3:
00431         switch(COLUMN) {
00432         case 0: m_30 = value; return; break;
00433         case 1: m_31 = value; return; break;
00434         case 2: m_32 = value; return; break;
00435         default: break;
00436         }
00437         break;
00438       default:
00439         break;
00440       }
00441       std::ostringstream message;
00442       message << "Indices (" << ROW << ", " << COLUMN << ") are out of bounds.";
00443       DLR_THROW(IndexException, "Transform3D::setValue<size_t, size_t>(double)",
00444                 message.str().c_str());
00445     }
00446 
00447   
00448     // This operator returns one element from the matrix
00449     // representation of the coordinate transform by value.
00450     // The case statements should optimize away, since row and column
00451     // are both known at compile time.
00452     template <size_t ROW, size_t COLUMN>
00453     double
00454     Transform3D::
00455     value() const
00456     {
00457       switch(ROW) {
00458       case 0:
00459         switch(COLUMN) {
00460         case 0: return m_00; break;
00461         case 1: return m_01; break;
00462         case 2: return m_02; break;
00463         case 3: return m_03; break;
00464         default: break;
00465         }
00466         break;
00467       case 1:
00468         switch(COLUMN) {
00469         case 0: return m_10; break;
00470         case 1: return m_11; break;
00471         case 2: return m_12; break;
00472         case 3: return m_13; break;
00473         default: break;
00474         }
00475         break;
00476       case 2:
00477         switch(COLUMN) {
00478         case 0: return m_20; break;
00479         case 1: return m_21; break;
00480         case 2: return m_22; break;
00481         case 3: return m_23; break;
00482         default: break;
00483         }
00484         break;
00485       case 3:
00486         switch(COLUMN) {
00487         case 0: return m_30; break;
00488         case 1: return m_31; break;
00489         case 2: return m_32; break;
00490         case 3: return 1.0; break;
00491         default: break;
00492         }
00493         break;
00494       default:
00495         break;
00496       }
00497       std::ostringstream message;
00498       message << "Indices (" << ROW << ", " << COLUMN << ") are out of bounds.";
00499       DLR_THROW(IndexException, "Transform3D::value<size_t, size_t>()",
00500                 message.str().c_str());
00501       return 0.0; // Dummy return to keep the compiler happy.
00502     }
00503 
00504   } // namespace numeric
00505 
00506 } // namespace dlr
00507   
00508 #endif // #ifndef _DLR_TRANSFORM3D_H_

Generated on Mon Jul 9 20:34:03 2007 for dlrLibs Utility Libraries by  doxygen 1.5.2