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 
00142       template <size_t row, size_t column>
00143       double
00144       getValue() const {return this->value<row, column>();}
00145 
00146 
00153       Transform3D
00154       invert() const;
00155 
00156     
00182       void
00183       setTransform(double a00, double a01, double a02, double a03,
00184                    double a10, double a11, double a12, double a13,
00185                    double a20, double a21, double a22, double a23,
00186                    double a30, double a31, double a32, double a33);
00187 
00188 
00189 
00212       void
00213       setValue(size_t row, size_t column, double value);
00214 
00215 
00231       template <size_t row, size_t column>
00232       void
00233       setValue(double value);
00234 
00235 
00239       void
00240       setValue(double a00, double a01, double a02, double a03,
00241                double a10, double a11, double a12, double a13,
00242                double a20, double a21, double a22, double a23,
00243                double a30, double a31, double a32, double a33) {
00244         this->setTransform(a00, a01, a02, a03, a10, a11, a12, a13,
00245                            a20, a21, a22, a23, a30, a31, a32, a33);
00246       }
00247 
00248       
00259       template <size_t row, size_t column>
00260       double
00261       value() const;
00262 
00263 
00274       double
00275       operator()(size_t row, size_t column) const;
00276 
00277     
00285       Vector3D
00286       operator*(const Vector3D& vector0) const;
00287 
00288     
00295       Transform3D&
00296       operator=(const Transform3D& source);
00297 
00298     
00299     private:
00300       void normalize(double scaleFactor);
00301       
00302       double m_00, m_01, m_02, m_03;
00303       double m_10, m_11, m_12, m_13;
00304       double m_20, m_21, m_22, m_23;
00305       double m_30, m_31, m_32;
00306 
00307     }; // class Transform3D
00308 
00309 
00310     /* ============== Helper classes ============== */
00311 
00312 
00316     class Transform3DFunctor
00317       : public std::unary_function<Vector3D, Vector3D> {
00318 
00319     public:
00320 
00326       Transform3DFunctor(const Transform3D& transform)
00327         : m_transform(transform) {}
00328 
00329     
00337       inline Vector3D
00338       operator()(const Vector3D& vec) const {return m_transform * vec;}
00339     
00340     private:
00341       Transform3D m_transform;
00342     };
00343   
00344   
00345     /* ============== Non-member functions ============== */
00346   
00362     Transform3D
00363     operator*(const Transform3D& transform0, const Transform3D& transform1);
00364 
00365   
00382     std::ostream&
00383     operator<<(std::ostream& stream, const Transform3D& transform0);
00384 
00385   
00398     std::istream&
00399     operator>>(std::istream& stream, Transform3D& transform0);
00400   
00401   } // namespace numeric
00402 
00403 } // namespace dlr
00404 
00405 
00406 /* ======= Declarations to maintain compatibility with legacy code. ======= */
00407 
00408 namespace dlr {
00409 
00410   using numeric::Transform3D;
00411   using numeric::Transform3DFunctor;
00412 
00413 } // namespace dlr
00414 
00415 
00416 /*******************************************************************
00417  * Member function definitions follow.  This would be a .C file
00418  * if it weren't templated.
00419  *******************************************************************/
00420 
00421 namespace dlr {
00422 
00423   namespace numeric {
00424     
00425     // This operator sets one element of the matrix representation of
00426     // the coordinate transform.  The case statements should optimize
00427     // away, since row and column are both known at compile time.
00428     template <size_t ROW, size_t COLUMN>
00429     void
00430     Transform3D::
00431     setValue(double inValue)
00432     {
00433       switch(ROW) {
00434       case 0:
00435         switch(COLUMN) {
00436         case 0: m_00 = inValue; return; break;
00437         case 1: m_01 = inValue; return; break;
00438         case 2: m_02 = inValue; return; break;
00439         case 3: m_03 = inValue; return; break;
00440         default: break;
00441         }
00442         break;
00443       case 1:
00444         switch(COLUMN) {
00445         case 0: m_10 = inValue; return; break;
00446         case 1: m_11 = inValue; return; break;
00447         case 2: m_12 = inValue; return; break;
00448         case 3: m_13 = inValue; return; break;
00449         default: break;
00450         }
00451         break;
00452       case 2:
00453         switch(COLUMN) {
00454         case 0: m_20 = inValue; return; break;
00455         case 1: m_21 = inValue; return; break;
00456         case 2: m_22 = inValue; return; break;
00457         case 3: m_23 = inValue; return; break;
00458         default: break;
00459         }
00460         break;
00461       case 3:
00462         switch(COLUMN) {
00463         case 0: m_30 = inValue; return; break;
00464         case 1: m_31 = inValue; return; break;
00465         case 2: m_32 = inValue; return; break;
00466         default: break;
00467         }
00468         break;
00469       default:
00470         break;
00471       }
00472       std::ostringstream message;
00473       message << "Indices (" << ROW << ", " << COLUMN << ") are out of bounds.";
00474       DLR_THROW(IndexException, "Transform3D::setValue<size_t, size_t>(double)",
00475                 message.str().c_str());
00476     }
00477 
00478   
00479     // This operator returns one element from the matrix
00480     // representation of the coordinate transform by value.
00481     // The case statements should optimize away, since row and column
00482     // are both known at compile time.
00483     template <size_t ROW, size_t COLUMN>
00484     double
00485     Transform3D::
00486     value() const
00487     {
00488       switch(ROW) {
00489       case 0:
00490         switch(COLUMN) {
00491         case 0: return m_00; break;
00492         case 1: return m_01; break;
00493         case 2: return m_02; break;
00494         case 3: return m_03; break;
00495         default: break;
00496         }
00497         break;
00498       case 1:
00499         switch(COLUMN) {
00500         case 0: return m_10; break;
00501         case 1: return m_11; break;
00502         case 2: return m_12; break;
00503         case 3: return m_13; break;
00504         default: break;
00505         }
00506         break;
00507       case 2:
00508         switch(COLUMN) {
00509         case 0: return m_20; break;
00510         case 1: return m_21; break;
00511         case 2: return m_22; break;
00512         case 3: return m_23; break;
00513         default: break;
00514         }
00515         break;
00516       case 3:
00517         switch(COLUMN) {
00518         case 0: return m_30; break;
00519         case 1: return m_31; break;
00520         case 2: return m_32; break;
00521         case 3: return 1.0; break;
00522         default: break;
00523         }
00524         break;
00525       default:
00526         break;
00527       }
00528       std::ostringstream message;
00529       message << "Indices (" << ROW << ", " << COLUMN << ") are out of bounds.";
00530       DLR_THROW(IndexException, "Transform3D::value<size_t, size_t>()",
00531                 message.str().c_str());
00532       return 0.0; // Dummy return to keep the compiler happy.
00533     }
00534 
00535   } // namespace numeric
00536 
00537 } // namespace dlr
00538   
00539 #endif // #ifndef _DLR_TRANSFORM3D_H_

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