LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiHTypes.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiHTypes.h
00027  * authors ....: Pablo Alvarado
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 07.06.01
00030  * revisions ..: $Id: ltiHTypes.h,v 1.11 2006/02/08 11:14:26 ltilib Exp $
00031  */
00032 
00033 #ifndef LTI_H_TYPES_H
00034 #define LTI_H_TYPES_H
00035 
00036 #include "ltiTypes.h"
00037 #include "ltiMatrix.h"
00038 
00039 /**
00040  * @file ltiHTypes.h
00041  * This file contains the definitions of the basic types
00042  * for projective algebra in 2 and 3 dimensions.
00043  *
00044  * The types are basically points and matrices
00045  */
00046 
00047 namespace lti {
00048   /**
00049    * Homogeneous point in two dimensions
00050    * Note that an homogeneous two-dimensional point has three elements:
00051    * x,y and h.  All arithmetical operations will be calculated for the
00052    * corresponding non-homogeneous 2D point, and then homogenized.  For example
00053    * the addition of two hPoints2D will be:
00054    * \f[ \begin{pmatrix}x_1 \\ y_1 \\ h_1 \end{pmatrix} +
00055    *     \begin{pmatrix}x_2 \\ y_2 \\ h_2 \end{pmatrix} =
00056    *     \begin{pmatrix}x_1/h_1 \\ y_1/h_1 \\ 1 \end{pmatrix} +
00057    *     \begin{pmatrix}x_2/h_2 \\ y_2/h_2 \\ 1 \end{pmatrix} =
00058    *     \begin{pmatrix}\frac{x_1}{h_1}+\frac{x_2}{h_2} \\
00059    *                    \frac{y_1}{h_1}+\frac{y_2}{h_2} \\ 1 \end{pmatrix} =
00060    *     \begin{pmatrix} x_1+x_2 \cdot \frac{h_1}{h_2} \\
00061    *                     y_1+y_2 \cdot \frac{h_1}{h_2} \\ h_1 \end{pmatrix}\f]
00062    */
00063   template <class T>
00064   class hPoint2D {
00065     public:
00066 
00067     /**
00068      * coordinate x
00069      */
00070     T& x;
00071 
00072     /**
00073      * coordinate y;
00074      */
00075     T& y;
00076 
00077 
00078     /**
00079      * component h
00080      */
00081     T& h;
00082 
00083     /**
00084      * this constant value indicates the dimensionality of this point
00085      * as vector: i.e. this will contain the value 3
00086      */
00087     static const int totalDimensionality;
00088 
00089     /**
00090      * default constructor
00091      */
00092     explicit hPoint2D(const T newx=0,const T newy=0,const T newh=T(1))
00093       : x(data[0]),y(data[1]),h(data[2]) {
00094       x=newx;
00095       y=newy;
00096       h=newh;
00097     };
00098 
00099     /**
00100      * copy constructor
00101      */
00102     hPoint2D(const hPoint2D<T>& p)
00103       : x(data[0]),y(data[1]),h(data[2]) {
00104       copy(p);
00105     };
00106 
00107     /**
00108      * copy constructor
00109      */
00110     template <class U>
00111     hPoint2D<T>& castFrom(const hPoint2D<U>& p) {
00112       x = static_cast<T>(p.x);
00113       y = static_cast<T>(p.y);
00114       h = static_cast<T>(p.h);
00115       return (*this);
00116     };
00117 
00118     /**
00119      * copy constructor
00120      */
00121     hPoint2D(const tpoint<T>& p)
00122       : x(data[0]),y(data[1]),h(data[2]) {
00123       copy(p);
00124     };
00125 
00126     /**
00127      * copy constructor
00128      */
00129     template <class U>
00130     hPoint2D<T>& castFrom(const tpoint<U>& p) {
00131       x = static_cast<T>(p.x);
00132       y = static_cast<T>(p.y);
00133       h = static_cast<T>(T(1));
00134       return (*this);
00135     };
00136 
00137     /**
00138      * copy this point normalized into the given tpoint and return a
00139      * reference to it
00140      */
00141     inline tpoint<T>& castTo(tpoint<T>& p) const {
00142       p.x = x/h;
00143       p.y = y/h;
00144       return p;
00145     };
00146 
00147     /**
00148      * multiply hPoint2D<T> with a given factor
00149      * This will affect the (x,y) values! (multiplying h would had no effect!)
00150      */
00151     inline hPoint2D<T>& multiply(const T c);
00152 
00153     /**
00154      * multiply hPoint2D<T> with a given factor
00155      * This will affect the (x,y) values! (multiplying h would had no effect!)
00156      */
00157     inline hPoint2D<T> operator*(const T c) const;
00158 
00159     /**
00160      * this product multiplies elementwise the components of this and
00161      * the point c.
00162      */
00163     inline hPoint2D<T> operator*(const hPoint2D<T>& c) const;
00164 
00165     /**
00166      * this product multiplies elementwise the components of this and
00167      * the point c
00168      */
00169     inline hPoint2D<T>& operator*=(const hPoint2D<T>& c);
00170 
00171     /**
00172      * divide each component of hPoint2D<T> (x,y only) with a given factor
00173      */
00174     inline hPoint2D<T>& divide(const T c);
00175 
00176     /**
00177      * divide each component of hPoint2D<T> with a given factor
00178      */
00179     inline hPoint2D<T> operator/(const T c) const;
00180 
00181     /**
00182      * elementwise division of each component of the points
00183      */
00184     inline hPoint2D<T> operator/(const hPoint2D<T>& c) const;
00185 
00186     /**
00187      * elementwise division of each component of the points
00188      */
00189     inline hPoint2D<T>& operator/=(const hPoint2D<T>& c);
00190 
00191     /**
00192      * add
00193      */
00194     inline hPoint2D<T>& add(const hPoint2D<T>& p);
00195 
00196     /**
00197      * operator +
00198      */
00199     inline hPoint2D<T> operator+(const hPoint2D<T>& p) const;
00200 
00201     /**
00202      * operator +=
00203      */
00204     inline hPoint2D<T>& operator+=(const hPoint2D<T>& p);
00205 
00206     /**
00207      * subtract
00208      */
00209     inline hPoint2D<T>& subtract(const hPoint2D<T>& p);
00210 
00211     /**
00212      * operator -
00213      */
00214     inline hPoint2D<T> operator-(const hPoint2D<T>& p) const;
00215 
00216     /**
00217      * operator -=
00218      */
00219     inline hPoint2D<T>& operator-=(const hPoint2D<T>& p);
00220 
00221     /**
00222      * Dot product with another point.
00223      *
00224      * This considers the normalized x and y components only!
00225      * i.e. the result will be (x*p.x+y*p.y)/(h*p.h)
00226      */
00227     inline T dot(const hPoint2D<T>& p) const;
00228 
00229     /**
00230      * Dot product with a 3D vector. Typically, this would be a
00231      * transformation vector (e.g. a row of an hMatrix) which projects
00232      * the point onto an axis. The result is a normal dot product,
00233      * i.e. x*p.at(0)+y*p.at(1)+h*p.at(2).
00234      *
00235      * Please note that this result differs considerably from the dot
00236      * product with another hPoint, as the latter case normalizes the
00237      * x and y components by the h one, and then makes a dot product of
00238      * only the x and y components, while the former one assumes the
00239      * hPoint and the vector as 3D points to make their product.
00240      *
00241      * @param p three dimensional vector
00242      * @return normal dot product between hPoint2D and vector
00243      */
00244     inline T dot(const vector<T>& p) const;
00245 
00246     /**
00247      * copy operator
00248      */
00249     inline hPoint2D<T>& copy(const hPoint2D<T>& p);
00250 
00251     /**
00252      * operator =
00253      */
00254     inline hPoint2D<T>& operator=(const hPoint2D<T>& p) {return copy(p);};
00255 
00256     /**
00257      * copy operator
00258      */
00259     inline hPoint2D<T>& copy(const tpoint<T>& p);
00260 
00261     /**
00262      * operator =
00263      */
00264     inline hPoint2D<T>& operator=(const tpoint<T>& p) {return copy(p);};
00265 
00266     /**
00267      * operator ==
00268      * This compares the normalized x and y coordinates,
00269      * i.e. x*p.h == p.x*h and the same thing for y
00270      */
00271     inline bool operator==(const hPoint2D<T>& p) const;
00272 
00273     /**
00274      * operator !=
00275      */
00276     inline bool operator!=(const hPoint2D<T>& p) const;
00277 
00278     /**
00279      * normalize this point.  This makes the h component 1
00280      * @return a reference to this point
00281      */
00282     inline hPoint2D<T>& normalize();
00283 
00284     /**
00285      * copy in this point the normalized point p
00286      * @return a reference to this point
00287      */
00288     inline hPoint2D<T>& normalize(const hPoint2D<T>& p);
00289 
00290     /**
00291      * operator to access the point as a vector.
00292      * The position x corresponds to the element 0.
00293      * The position y corresponds to the element 1.
00294      * The position h corresponds to the element 2.
00295      */
00296     inline T& operator[](const int& i);
00297 
00298     /**
00299      * operator to access the point as a vector.
00300      * The position x corresponds to the element 0.
00301      * The position y corresponds to the element 1.
00302      * The position h corresponds to the element 2.
00303      */
00304     inline const T& operator[](const int& i) const;
00305 
00306     /**
00307      * return the square of the magnitud of this point (after its
00308      * normalization)
00309      */
00310     inline T absSqr() const;
00311 
00312   protected:
00313     /**
00314      * the content of the point
00315      */
00316     T data[3];
00317 
00318   };
00319 
00320   // implementation: not in Doc++!!!
00321 
00322   /*
00323    * this constant value indicates the dimensionality of this point
00324    * as vector: i.e. this will contain the value 3
00325    */
00326   template <class T>
00327   const int hPoint2D<T>::totalDimensionality = 3;
00328 
00329 
00330   template <class T>
00331   inline hPoint2D<T>& hPoint2D<T>::multiply(const T c) {
00332     x*=c;
00333     y*=c;
00334     // h will be keeped
00335     return (*this);
00336   }
00337 
00338   template <class T>
00339   inline hPoint2D<T> hPoint2D<T>::operator*(const T c) const {
00340     return hPoint2D<T>(x*c,y*c,h);
00341   }
00342 
00343   template <class T>
00344   inline hPoint2D<T> hPoint2D<T>::operator*(const hPoint2D<T>& c) const {
00345     return hPoint2D<T>(c.x*x/c.h,c.y*y/c.h,h);
00346   }
00347 
00348   template <class T>
00349   inline hPoint2D<T>& hPoint2D<T>::operator*=(const hPoint2D<T>& c) {
00350     x=x*c.x/c.h;
00351     y=x*c.y/c.h;
00352     return *this;
00353   }
00354 
00355   template <class T>
00356   inline hPoint2D<T>& hPoint2D<T>::divide(const T c) {
00357     x/=c;
00358     y/=c;
00359     // h remains as it was...
00360     return (*this);
00361   }
00362 
00363   template <class T>
00364   inline hPoint2D<T> hPoint2D<T>::operator/(const T c) const {
00365     return hPoint2D<T>(x/c,y/c,h);
00366   }
00367 
00368   template <class T>
00369   inline hPoint2D<T> hPoint2D<T>::operator/(const hPoint2D<T>& c) const {
00370     return hPoint2D<T>(c.h*x/c.x,c.h*y/c.y,h);
00371   }
00372 
00373   template <class T>
00374   inline hPoint2D<T>& hPoint2D<T>::operator/=(const hPoint2D<T>& c) {
00375     x = c.h*x/c.x;
00376     y = c.h*y/c.y;
00377     // h the same ...
00378     return *this;
00379   }
00380 
00381   template <class T>
00382   inline hPoint2D<T>& hPoint2D<T>::add(const hPoint2D<T>& p) {
00383     x+= (h*p.x/p.h);
00384     y+= (h*p.y/p.h);
00385     // h the same...
00386     return (*this);
00387   }
00388 
00389   template <class T>
00390   inline hPoint2D<T> hPoint2D<T>::operator+(const hPoint2D<T>& p) const {
00391     return hPoint2D<T>(x+(h*p.x/p.h),y+(h*p.y/p.h),h);
00392   }
00393 
00394   template <class T>
00395   inline hPoint2D<T>& hPoint2D<T>::operator+=(const hPoint2D<T>& p) {
00396     return add(p);
00397   }
00398 
00399   template <class T>
00400   inline hPoint2D<T>& hPoint2D<T>::subtract(const hPoint2D<T>& p) {
00401     x-=(p.x*h/p.h);
00402     y-=(p.y*h/p.h);
00403     // h the same...
00404     return (*this);
00405   }
00406 
00407   template <class T>
00408   inline hPoint2D<T> hPoint2D<T>::operator-(const hPoint2D<T>& p) const {
00409     return hPoint2D<T>(x-(p.x*h/p.h),y-(p.y*h/p.h),h);
00410   }
00411 
00412   template <class T>
00413   inline hPoint2D<T>& hPoint2D<T>::operator-=(const hPoint2D<T>& p) {
00414     return subtract(p);
00415   }
00416 
00417   template <class T>
00418   inline T hPoint2D<T>::dot(const hPoint2D<T>& p) const {
00419     return ((x*p.x) + (y*p.y))/(h*p.h);
00420   }
00421 
00422   template <class T>
00423   inline T hPoint2D<T>::dot(const vector<T>& p) const {
00424     assert(p.size()==3);
00425     return x*p.at(0)+y*p.at(1)+h*p.at(2);
00426   }
00427 
00428   template <class T>
00429   inline hPoint2D<T>& hPoint2D<T>::copy(const hPoint2D<T>& p) {
00430     x = p.x;
00431     y = p.y;
00432     h = p.h;
00433     return (*this);
00434   }
00435 
00436   template <class T>
00437   inline hPoint2D<T>& hPoint2D<T>::copy(const tpoint<T>& p) {
00438     x = p.x;
00439     y = p.y;
00440     h = static_cast<T>(1);
00441     return (*this);
00442   }
00443 
00444   template <class T>
00445   inline bool hPoint2D<T>::operator==(const hPoint2D<T>& p) const {
00446     return ((h*p.y == p.h*y) && (h*p.x == p.h*x));
00447   }
00448 
00449   template <class T>
00450   inline bool hPoint2D<T>::operator!=(const hPoint2D<T>& p) const {
00451     return ((h*p.y != p.h*y) || (h*p.x != p.h*x));
00452   }
00453 
00454   template <class T>
00455   inline hPoint2D<T>& hPoint2D<T>::normalize() {
00456     x /= h;
00457     y /= h;
00458     h = T(1);
00459     return (*this);
00460   }
00461 
00462   template <class T>
00463   inline hPoint2D<T>& hPoint2D<T>::normalize(const hPoint2D<T>& p) {
00464     x = p.x/p.h;
00465     y = p.y/p.h;
00466     h = T(1);
00467     return (*this);
00468   }
00469 
00470   template <class T>
00471   inline T& hPoint2D<T>::operator[](const int& i) {
00472     assert(i<totalDimensionality);
00473     return data[i];
00474   }
00475 
00476   template <class T>
00477   inline const T& hPoint2D<T>::operator[](const int& i) const {
00478     assert(i<totalDimensionality);
00479     return data[i];
00480   }
00481 
00482   template <class T>
00483     inline T hPoint2D<T>::absSqr() const {
00484     return (x*x+y*y)/(h*h);
00485   }
00486 
00487   /**
00488    * A point with double coordinates
00489    */
00490   typedef hPoint2D<double> dhPoint2D;
00491 
00492   /** @name Storable interface for points
00493    *  Members for the storable interface
00494    */
00495   //@{
00496   /**
00497    * read the vector from the given ioHandler.  The complete flag indicates
00498    * if the enclosing begin and end should be also be readed
00499    */
00500   template <class T>
00501     bool read(ioHandler& handler,hPoint2D<T>& p,const bool complete=true) {
00502     bool b(true);
00503 
00504     if (complete) {
00505       b = b && handler.readBegin();
00506     }
00507 
00508     b = b && handler.read(p.x);
00509     b = b && handler.readDataSeparator();
00510     b = b && handler.read(p.y);
00511     b = b && handler.readDataSeparator();
00512     b = b && handler.read(p.h);
00513 
00514     if (complete) {
00515       b = b && handler.readEnd();
00516     }
00517 
00518     return b;
00519   };
00520 
00521   /**
00522    * write the vector in the given ioHandler.  The complete flag indicates
00523    * if the enclosing begin and end should be also be written or not
00524    */
00525   template<class T>
00526   bool write(ioHandler& handler,const hPoint2D<T>& p,
00527              const bool complete=true) {
00528     bool b(true);
00529 
00530     if (complete) {
00531       b = b && handler.writeBegin();
00532     }
00533 
00534     b = b && handler.write(p.x);
00535     b = b && handler.writeDataSeparator();
00536     b = b && handler.write(p.y);
00537     b = b && handler.writeDataSeparator();
00538     b = b && handler.write(p.h);
00539 
00540     if (complete) {
00541       b = b && handler.writeEnd();
00542     }
00543 
00544     return b;
00545   };
00546   //@}
00547 
00548 
00549 
00550   /**
00551    * Homogeneous point in three dimensions.
00552    *
00553    * Note that an homogeneous three-dimensional point has four elements:
00554    * x,y,z and h.  All arithmetical operations will be calculated for the
00555    * corresponding non-homogeneous 3D point, and then homogenized.  For example
00556    * the addition of two hPoints3D will be:
00557    * \f[ \begin{pmatrix}x_1 \\ y_1 \\ z_1 \\ h_1 \end{pmatrix} +
00558    *     \begin{pmatrix}x_2 \\ y_2 \\ z_2 \\ h_2 \end{pmatrix} =
00559    *     \begin{pmatrix}x_1/h_1 \\ y_1/h_1 \\ z_1/h_1 \\ 1 \end{pmatrix} +
00560    *     \begin{pmatrix}x_2/h_2 \\ y_2/h_2 \\ z_2/h_2 \\ 1 \end{pmatrix} =
00561    *     \begin{pmatrix}\frac{x_1}{h_1}+\frac{x_2}{h_2} \\
00562    *                    \frac{y_1}{h_1}+\frac{y_2}{h_2} \\
00563    *                    \frac{z_1}{h_1}+\frac{z_2}{h_2} \\ 1 \end{pmatrix} =
00564    *     \begin{pmatrix} x_1+x_2 \cdot \frac{h_1}{h_2} \\
00565    *                     y_1+y_2 \cdot \frac{h_1}{h_2} \\
00566    *                     z_1+z_2 \cdot \frac{h_1}{h_2} \\ h_1 \end{pmatrix}\f]
00567    */
00568   template <class T>
00569   class hPoint3D {
00570     public:
00571 
00572     /**
00573      * coordinate x
00574      */
00575     T& x;
00576 
00577     /**
00578      * coordinate y;
00579      */
00580     T& y;
00581 
00582     /**
00583      * coordinate z;
00584      */
00585     T& z;
00586 
00587     /**
00588      * component h
00589      */
00590     T& h;
00591 
00592     /**
00593      * This constant value indicates the dimensionality of this point
00594      * as vector: i.e. this will contain the value 4
00595      */
00596     static const int totalDimensionality;
00597 
00598     /**
00599      * default constructor
00600      */
00601     explicit hPoint3D(const T newx=0,
00602                       const T newy=0,
00603                       const T newz=0,
00604                       const T newh=T(1))
00605       : x(data[0]),y(data[1]),z(data[2]),h(data[3]) {
00606       x = newx;
00607       y = newy;
00608       z = newz;
00609       h = newh;
00610     };
00611 
00612     /**
00613      * copy constructor
00614      */
00615     hPoint3D(const hPoint3D<T>& p)
00616       : x(data[0]),y(data[1]),z(data[2]),h(data[3]) {
00617       copy(p);
00618     };
00619 
00620     /**
00621      * copy constructor
00622      */
00623     hPoint3D(const hPoint2D<T>& p)
00624       : x(data[0]),y(data[1]),z(data[2]),h(data[3]) {
00625       copy(p);
00626     };
00627 
00628     /**
00629      * copy constructor
00630      */
00631     hPoint3D(const tpoint<T>& p)
00632       : x(data[0]),y(data[1]),z(data[2]),h(data[3]) {
00633       copy(p);
00634     };
00635 
00636     /**
00637      * copy constructor
00638      */
00639     hPoint3D(const tpoint3D<T>& p)
00640       : x(data[0]),y(data[1]),z(data[2]),h(data[3]) {
00641       copy(p);
00642     };
00643 
00644     /**
00645      * copy constructor
00646      */
00647     template <class U>
00648     hPoint3D<T>& castFrom(const hPoint3D<U>& p) {
00649       x = static_cast<T>(p.x);
00650       y = static_cast<T>(p.y);
00651       z = static_cast<T>(p.z);
00652       h = static_cast<T>(p.h);
00653       return (*this);
00654     };
00655 
00656 
00657     /**
00658      * copy constructor
00659      */
00660     template <class U>
00661     hPoint3D<T>& castFrom(const tpoint3D<U>& p) {
00662       x = static_cast<T>(p.x);
00663       y = static_cast<T>(p.y);
00664       z = static_cast<T>(p.z);
00665       h = static_cast<T>(T(1));
00666       return (*this);
00667     };
00668 
00669     /**
00670      * copy this point normalized into the given tpoint and return a
00671      * reference to it
00672      */
00673     inline tpoint3D<T>& castTo(tpoint3D<T>& p) const {
00674       p.x = x/h;
00675       p.y = y/h;
00676       p.z = z/h;
00677       return p;
00678     };
00679 
00680     /**
00681      * copy this point into the given hPoint2D and return a
00682      * reference to it.  The z coordinate will be ignored (this corresponds
00683      * to an orthogonal projection of the point in the x-y plane
00684      */
00685     inline hPoint2D<T>& project(hPoint2D<T>& p) const {
00686       p.x = x;
00687       p.y = y;
00688       p.h = h;
00689       return p;
00690     };
00691 
00692     /**
00693      * copy this point normalized into the given tpoint and return a
00694      * reference to it.  The z coordinate will be ignored (this corresponds
00695      * to an orthogonal projection of the point in the x-y plane
00696      */
00697     inline tpoint<T>& project(tpoint<T>& p) const {
00698       p.x = x/h;
00699       p.y = y/h;
00700       return p;
00701     };
00702 
00703     /**
00704      * multiply hPoint3D<T> with a given factor
00705      * This will affect the (x,y) values! (multiplying h would had no effect!)
00706      */
00707     inline hPoint3D<T>& multiply(const T c);
00708 
00709     /**
00710      * multiply hPoint3D<T> with a given factor
00711      * This will affect the (x,y) values! (multiplying h would had no effect!)
00712      */
00713     inline hPoint3D<T> operator*(const T c) const;
00714 
00715     /**
00716      * this product multiplies elementwise the components of this and
00717      * the point c.
00718      */
00719     inline hPoint3D<T> operator*(const hPoint3D<T>& c) const;
00720 
00721     /**
00722      * this product multiplies elementwise the components of this and
00723      * the point c
00724      */
00725     inline hPoint3D<T>& operator*=(const hPoint3D<T>& c);
00726 
00727     /**
00728      * divide each component of hPoint3D<T> (x,y only) with a given factor
00729      */
00730     inline hPoint3D<T>& divide(const T c);
00731 
00732     /**
00733      * divide each component of hPoint3D<T> with a given factor
00734      */
00735     inline hPoint3D<T> operator/(const T c) const;
00736 
00737     /**
00738      * elementwise division of each component of the points
00739      */
00740     inline hPoint3D<T> operator/(const hPoint3D<T>& c) const;
00741 
00742     /**
00743      * elementwise division of each component of the points
00744      */
00745     inline hPoint3D<T>& operator/=(const hPoint3D<T>& c);
00746 
00747     /**
00748      * add
00749      */
00750     inline hPoint3D<T>& add(const hPoint3D<T>& p);
00751 
00752     /**
00753      * operator +
00754      */
00755     inline hPoint3D<T> operator+(const hPoint3D<T>& p) const;
00756 
00757     /**
00758      * operator +=
00759      */
00760     inline hPoint3D<T>& operator+=(const hPoint3D<T>& p);
00761 
00762     /**
00763      * subtract
00764      */
00765     inline hPoint3D<T>& subtract(const hPoint3D<T>& p);
00766 
00767     /**
00768      * operator -
00769      */
00770     inline hPoint3D<T> operator-(const hPoint3D<T>& p) const;
00771 
00772     /**
00773      * operator -=
00774      */
00775     inline hPoint3D<T>& operator-=(const hPoint3D<T>& p);
00776 
00777     /**
00778      * Dot product with another point.
00779      *
00780      * This consider the normalized x, y and z components only!
00781      * i.e. the result will be (x*p.x + y*p.y + z*p.z)/(h*p.h)
00782      */
00783     inline T dot(const hPoint3D<T>& p) const;
00784 
00785     /**
00786      * Dot product with a 4D vector. Typically, this would be a
00787      * transformation vector (e.g. a row of an hMatrix) which projects
00788      * the point onto an axis. The result is a normal dot product,
00789      * i.e. x*p.at(0)+...+h*p.at(3).
00790      *
00791      *
00792      * Please note that this result differs considerably from the dot
00793      * product with another hPoint, as the latter case normalizes the
00794      * x, y and z components by the h one, and then makes a dot
00795      * product of only the x, y and z normalized components, while the
00796      * former one assumes the hPoint and the vector as 4D points and
00797      * makes their product.
00798      *
00799      * @param p four dimensional vector
00800      * @return normal dot product between hPoint3D and vector
00801      */
00802     inline T dot(const vector<T>& p) const;
00803 
00804     /**
00805      * copy operator
00806      */
00807     inline hPoint3D<T>& copy(const hPoint3D<T>& p);
00808 
00809     /**
00810      * copy operator (assume z=0)
00811      */
00812     inline hPoint3D<T>& copy(const hPoint2D<T>& p);
00813 
00814     /**
00815      * operator =
00816      */
00817     inline hPoint3D<T>& operator=(const hPoint3D<T>& p) {return copy(p);};
00818 
00819     /**
00820      * copy operator
00821      */
00822     inline hPoint3D<T>& copy(const tpoint3D<T>& p);
00823 
00824     /**
00825      * copy operator (assume z=0)
00826      */
00827     inline hPoint3D<T>& copy(const tpoint<T>& p);
00828 
00829     /**
00830      * operator =
00831      */
00832     inline hPoint3D<T>& operator=(const tpoint3D<T>& p) {return copy(p);};
00833 
00834     /**
00835      * operator ==
00836      * This compares the normalized x and y coordinates,
00837      * i.e. x*p.h == p.x*h and the same thing for y
00838      */
00839     inline bool operator==(const hPoint3D<T>& p) const;
00840 
00841     /**
00842      * operator !=
00843      */
00844     inline bool operator!=(const hPoint3D<T>& p) const;
00845 
00846     /**
00847      * normalize this point.  This makes the h component 1
00848      * @return a reference to this point
00849      */
00850     inline hPoint3D<T>& normalize();
00851 
00852     /**
00853      * normalize this point.  This makes the h component 1
00854      * @return a reference to this point
00855      */
00856     inline hPoint3D<T>& normalize(const hPoint3D<T>& p);
00857 
00858     /**
00859      * operator to access the point as a vector.
00860      * The position x corresponds to the element 0.
00861      * The position y corresponds to the element 1.
00862      * The position z corresponds to the element 2.
00863      * The position h corresponds to the element 3.
00864      */
00865     inline T& operator[](const int& i);
00866 
00867     /**
00868      * operator to access the point as a vector.
00869      * The position x corresponds to the element 0.
00870      * The position y corresponds to the element 1.
00871      * The position z corresponds to the element 2.
00872      * The position h corresponds to the element 3.
00873      */
00874     inline const T& operator[](const int& i) const;
00875 
00876     /**
00877      * return the square of the magnitud of this point (after its
00878      * normalization)
00879      */
00880     inline T absSqr() const;
00881 
00882   protected:
00883     /**
00884      * the content of the point
00885      */
00886     T data[4];
00887   };
00888 
00889   // implementation: not in Doc++!!!
00890 
00891   /*
00892    * this constant value indicates the dimensionality of this point
00893    * as vector: i.e. this will contain the value 3
00894    */
00895   template <class T>
00896     const int hPoint3D<T>::totalDimensionality = 4;
00897 
00898   template <class T>
00899   inline hPoint3D<T>& hPoint3D<T>::multiply(const T c) {
00900     x*=c;
00901     y*=c;
00902     z*=c;
00903     // h will be keeped
00904     return (*this);
00905   }
00906 
00907   template <class T>
00908   inline hPoint3D<T> hPoint3D<T>::operator*(const T c) const {
00909     return hPoint3D<T>(x*c,y*c,z*c,h);
00910   }
00911 
00912   template <class T>
00913   inline hPoint3D<T> hPoint3D<T>::operator*(const hPoint3D<T>& c) const {
00914     return hPoint3D<T>(c.x*x/c.h,c.y*y/c.h,c.z*z/c.h,h);
00915   }
00916 
00917   template <class T>
00918   inline hPoint3D<T>& hPoint3D<T>::operator*=(const hPoint3D<T>& c) {
00919     x=x*c.x/c.h;
00920     y=y*c.y/c.h;
00921     z=z*c.z/c.h;
00922     return *this;
00923   }
00924 
00925   template <class T>
00926   inline hPoint3D<T>& hPoint3D<T>::divide(const T c) {
00927     x/=c;
00928     y/=c;
00929     z/=c;
00930     // h remains as it was...
00931     return (*this);
00932   }
00933 
00934   template <class T>
00935   inline hPoint3D<T> hPoint3D<T>::operator/(const T c) const {
00936     return hPoint3D<T>(x/c,y/c,z/c,h);
00937   }
00938 
00939   template <class T>
00940   inline hPoint3D<T> hPoint3D<T>::operator/(const hPoint3D<T>& c) const {
00941     return hPoint3D<T>(c.h*x/c.x,c.h*y/c.y,c.h*z/c.z,h);
00942   }
00943 
00944   template <class T>
00945   inline hPoint3D<T>& hPoint3D<T>::operator/=(const hPoint3D<T>& c) {
00946     x = c.h*x/c.x;
00947     y = c.h*y/c.y;
00948     z = c.h*z/c.z;
00949     // h the same ...
00950     return *this;
00951   }
00952 
00953   template <class T>
00954   inline hPoint3D<T>& hPoint3D<T>::add(const hPoint3D<T>& p) {
00955     x+= (h*p.x/p.h);
00956     y+= (h*p.y/p.h);
00957     z+= (h*p.z/p.h);
00958     // h the same...
00959     return (*this);
00960   }
00961 
00962   template <class T>
00963   inline hPoint3D<T> hPoint3D<T>::operator+(const hPoint3D<T>& p) const {
00964     return hPoint3D<T>(x+(h*p.x/p.h),y+(h*p.y/p.h),z+(h*p.z/p.h),h);
00965   }
00966 
00967   template <class T>
00968   inline hPoint3D<T>& hPoint3D<T>::operator+=(const hPoint3D<T>& p) {
00969     return add(p);
00970   }
00971 
00972   template <class T>
00973   inline hPoint3D<T>& hPoint3D<T>::subtract(const hPoint3D<T>& p) {
00974     x-=(p.x*h/p.h);
00975     y-=(p.y*h/p.h);
00976     z-=(p.z*h/p.h);
00977     // h the same...
00978     return (*this);
00979   }
00980 
00981   template <class T>
00982   inline hPoint3D<T> hPoint3D<T>::operator-(const hPoint3D<T>& p) const {
00983     return hPoint3D<T>(x-(p.x*h/p.h),y-(p.y*h/p.h),z-(p.z*h/p.h),h);
00984   }
00985 
00986   template <class T>
00987   inline hPoint3D<T>& hPoint3D<T>::operator-=(const hPoint3D<T>& p) {
00988     return subtract(p);
00989   }
00990 
00991   template <class T>
00992   inline T hPoint3D<T>::dot(const hPoint3D<T>& p) const {
00993     return ((x*p.x) + (y*p.y) + (z*p.z))/(h*p.h);
00994   }
00995 
00996   template <class T>
00997   inline T hPoint3D<T>::dot(const vector<T>& p) const {
00998     assert(p.size()==4);
00999     return x*p.at(0)+y*p.at(1)+z*p.at(2)+h*p.at(3);
01000   }
01001 
01002   template <class T>
01003   inline hPoint3D<T>& hPoint3D<T>::copy(const hPoint3D<T>& p) {
01004     x = p.x;
01005     y = p.y;
01006     z = p.z;
01007     h = p.h;
01008     return (*this);
01009   }
01010 
01011   template <class T>
01012   inline hPoint3D<T>& hPoint3D<T>::copy(const hPoint2D<T>& p) {
01013     x = p.x;
01014     y = p.y;
01015     z = T(0);
01016     h = p.h;
01017     return (*this);
01018   }
01019 
01020   template <class T>
01021   inline hPoint3D<T>& hPoint3D<T>::copy(const tpoint3D<T>& p) {
01022     x = p.x;
01023     y = p.y;
01024     z = p.z;
01025     h = static_cast<T>(1);
01026     return (*this);
01027   }
01028 
01029   template <class T>
01030   inline hPoint3D<T>& hPoint3D<T>::copy(const tpoint<T>& p) {
01031     x = p.x;
01032     y = p.y;
01033     z = T(0);
01034     h = static_cast<T>(1);
01035     return (*this);
01036   }
01037 
01038   template <class T>
01039   inline bool hPoint3D<T>::operator==(const hPoint3D<T>& p) const {
01040     return ((h*p.y == p.h*y) && (h*p.x == p.h*x) && (h*p.z == p.h*z));
01041   }
01042 
01043   template <class T>
01044   inline bool hPoint3D<T>::operator!=(const hPoint3D<T>& p) const {
01045     return ((h*p.y != p.h*y) || (h*p.x != p.h*x) || (h*p.z != p.h*z));
01046   }
01047 
01048   template <class T>
01049   inline hPoint3D<T>& hPoint3D<T>::normalize() {
01050     x /= h;
01051     y /= h;
01052     z /= h;
01053     h = T(1);
01054     return (*this);
01055   }
01056 
01057   template <class T>
01058   inline hPoint3D<T>& hPoint3D<T>::normalize(const hPoint3D<T>& p) {
01059     x = p.x/p.h;
01060     y = p.y/p.h;
01061     z = p.z/p.h;
01062     h = T(1);
01063     return (*this);
01064   }
01065 
01066   template <class T>
01067   inline T& hPoint3D<T>::operator[](const int& i) {
01068     assert(i<totalDimensionality);
01069     return data[i];
01070   }
01071 
01072   template <class T>
01073   inline const T& hPoint3D<T>::operator[](const int& i) const {
01074     assert(i<totalDimensionality);
01075     return data[i];
01076   }
01077 
01078   template <class T>
01079     inline T hPoint3D<T>::absSqr() const {
01080     return (x*x+y*y+z*z)/(h*h);
01081   }
01082 
01083 
01084   /**
01085    * A point with double coordinates
01086    */
01087   typedef hPoint3D<double> dhPoint3D;
01088 
01089   /** @name Storable interface for points
01090    *  Members for the storable interface
01091    */
01092   //@{
01093   /**
01094    * read the vector from the given ioHandler.  The complete flag indicates
01095    * if the enclosing begin and end should be also be readed
01096    */
01097   template <class T>
01098     bool read(ioHandler& handler,hPoint3D<T>& p,const bool complete=true) {
01099     bool b(true);
01100 
01101     if (complete) {
01102       b = b && handler.readBegin();
01103     }
01104 
01105     b = b && handler.read(p.x);
01106     b = b && handler.readDataSeparator();
01107     b = b && handler.read(p.y);
01108     b = b && handler.readDataSeparator();
01109     b = b && handler.read(p.z);
01110     b = b && handler.readDataSeparator();
01111     b = b && handler.read(p.h);
01112 
01113     if (complete) {
01114       b = b && handler.readEnd();
01115     }
01116 
01117     return b;
01118   };
01119 
01120   /**
01121    * write the vector in the given ioHandler.  The complete flag indicates
01122    * if the enclosing begin and end should be also be written or not
01123    */
01124   template<class T>
01125   bool write(ioHandler& handler,const hPoint3D<T>& p,
01126              const bool complete=true) {
01127     bool b(true);
01128 
01129     if (complete) {
01130       b = b && handler.writeBegin();
01131     }
01132 
01133     b = b && handler.write(p.x);
01134     b = b && handler.writeDataSeparator();
01135     b = b && handler.write(p.y);
01136     b = b && handler.writeDataSeparator();
01137     b = b && handler.write(p.z);
01138     b = b && handler.writeDataSeparator();
01139     b = b && handler.write(p.h);
01140 
01141     if (complete) {
01142       b = b && handler.writeEnd();
01143     }
01144 
01145     return b;
01146   };
01147   //@}
01148 
01149 
01150   /**
01151    * Homogeneous matrix for projective space transformations.
01152    *
01153    * The template class T indicates the contained type and the class
01154    * P the point type (hPoint2D or hPoint3D)
01155    */
01156   template <class T, class P>
01157   class hMatrix : public mathObject {
01158     public:
01159     /**
01160      * type of the contained data
01161      */
01162     typedef T value_type;
01163 
01164     /**
01165      * return type of the size() member
01166      */
01167     typedef point size_type;
01168 
01169     /**
01170      * Default constructor.
01171      *
01172      * Initialize the matrix with the identity matrix (all elements in the
01173      * diagonal are one, the rest are zero).
01174      */
01175     hMatrix();
01176 
01177     /**
01178      * Copy constructor
01179      */
01180     hMatrix(const hMatrix<T,P>& other);
01181 
01182     /**
01183      * Copy constructor
01184      */
01185     hMatrix(const matrix<T>& other);
01186 
01187     /**
01188      * Destructor
01189      */
01190     virtual ~hMatrix();
01191 
01192     /**
01193      * Clean matrix (all elements with 0)
01194      */
01195     void clear();
01196 
01197     /**
01198      * Unit matrix.
01199      *
01200      * Initialize this matrix with the unit matrix having zeros in all
01201      * but the diagonal elements, which will be set to  one.
01202      */
01203     void unit();
01204 
01205     /**
01206      * Return the size of the %matrix in a lti::point structure.
01207      *
01208      * @return lti::point with the number of columns in its
01209      *         <code>x</code> coordinate and the number of rows in its
01210      *         <code>y</code> coordinate.
01211      */
01212     inline const point& size() const;
01213 
01214     /**
01215      * Returns the name of this class
01216      */
01217     virtual const char* getTypeName() const {
01218       return "hMatrix";
01219     };
01220 
01221     /**
01222      * Returns a copy of this object
01223      */
01224     virtual mathObject* clone() const;
01225 
01226     /**
01227      * Copy operator
01228      */
01229     hMatrix<T,P>& copy(const hMatrix<T,P>& other);
01230 
01231     /**
01232      * Copy operator
01233      */
01234     hMatrix<T,P>& copy(const matrix<T>& other);
01235 
01236     /**
01237      * Copy operator
01238      */
01239     hMatrix<T,P>& operator=(const hMatrix<T,P>& other) {
01240       return copy(other);
01241     }
01242 
01243     /**
01244      * Copy the contents of this %hmatrix into the given lti::matrix
01245      */
01246     matrix<T>& castTo(matrix<T>& result) const;
01247 
01248     /**
01249      * Copy the content of the given lti::matrix into this hmatrix.
01250      */
01251     hMatrix<T,P>& castFrom(const matrix<T>& other);
01252 
01253     /**
01254      * Write the object in the given ioHandler
01255      */
01256     virtual bool write(ioHandler& handler,
01257                        const bool complete = true) const;
01258 
01259     /**
01260      * Read the object from the given ioHandler
01261      */
01262     virtual bool read(ioHandler& handler,const bool complete = true);
01263 
01264     /**
01265      * Multiply this matrix with another homogeneous matrix and
01266      * leave the result here.
01267      */
01268     hMatrix<T,P>& multiply(const hMatrix<T,P>& other);
01269 
01270     /**
01271      * Left-Multiply this matrix with another homogeneous matrix and
01272      * leave the result here.
01273      */
01274     hMatrix<T,P>& leftMultiply(const hMatrix<T,P>& other);
01275 
01276     /**
01277      * Multiply the matrices a and b and leave the result here.
01278      */
01279     hMatrix<T,P>& multiply(const hMatrix<T,P>& a,const hMatrix<T,P>& b);
01280     
01281     /**
01282      * Return a new object which is the result of multiplying this matrix
01283      * with the other one
01284      */
01285     inline hMatrix<T,P> operator*(const hMatrix<T,P>& other) const {
01286       hMatrix<T,P> tmp;
01287       tmp.multiply(*this,other);
01288       return tmp;
01289     };
01290 
01291     /**
01292      * Alias for multiply
01293      */
01294     inline hMatrix<T,P>& operator*=(const hMatrix<T,P>& other) {
01295       return multiply(other);
01296     }
01297 
01298     /**
01299      * Multiply with a point and leave the result in the second
01300      * parameters.
01301      * Return a reference to the second parameters
01302      */
01303     P& multiply(const P& other, P& result) const;
01304 
01305     /**
01306      * Multiply with a homogeneous point
01307      */
01308     P operator*(const P& p) const {
01309       P temp;
01310       multiply(p,temp);
01311 
01312       return temp;
01313     };
01314 
01315     /**
01316      * Return value at row m and column n
01317      */
01318     inline T &at(const int& m,const int& n) {
01319       return theRows[m][n];
01320     };
01321 
01322     /**
01323      * Return value a row m and column n
01324      */
01325     inline const T &at(const int& m,const int& n) const {
01326       return theRows[m][n];
01327     };
01328 
01329     /**
01330      * Access operator to a row
01331      */
01332     inline T* operator[](const int& m) {
01333       return theRows[m];
01334     }
01335 
01336     /**
01337      * Read-only access operator to a row
01338      */
01339     inline const T* operator[](const int& m) const {
01340       return theRows[m];
01341     }
01342 
01343     /**
01344      * Invert this matrix an return a reference to it
01345      */
01346     hMatrix<T,P>& invert();
01347 
01348     /**
01349      * Copy here the other matrix inverted.
01350      */
01351     hMatrix<T,P>& invert(const hMatrix<T,P>& other);
01352 
01353     /**
01354      * Transpose this matrix an return a reference to it
01355      */
01356     hMatrix<T,P>& transpose();
01357 
01358     /**
01359      * Copy the transposed other matrix here.
01360      */
01361     hMatrix<T,P>& transpose(const hMatrix<T,P>& other);
01362 
01363     /**
01364      * Set the scale factor of the transformation.
01365      *
01366      * This is the element with the greatest indices.  Changing its value from
01367      * one will imply a scaling of everything, including the translation
01368      * factors.
01369      */
01370     void setScaleFactor(const T& s);
01371 
01372     /**
01373      * Return the scale factor used in the transformation.
01374      *
01375      * The scale factor is the element with the greatest indices.  Changing its
01376      * value from one will imply a scaling of everything, including the
01377      * translation factors.     
01378      */
01379     const T& getScaleFactor() const;
01380 
01381     /**
01382      * Multiply the scale factor with this value.
01383      *
01384      * The scale factor is the element with the greatest indices.  Changing its
01385      * value from one will imply a scaling of everything, including the
01386      * translation factors.
01387      */
01388     void scale(const T& s);
01389 
01390     /**
01391      * Multiply a scaling matrix with this one.
01392      *
01393      * The scaling matrix is obtaind multiplying a unit matrix with the
01394      * scalar \a s and setting the element with the greatest indices to
01395      * 1.0.
01396      *
01397      * This corresponds to scaling the rotation sub-matrix, but leaving the
01398      * translation components untouched.
01399      */
01400     void scaleR(const T& s);
01401 
01402 
01403     /**
01404      * This function sets the translation vector with the normalized data,
01405      * i.e. the given homogeneous point will be normalized and its components
01406      * (except the h component) will be used as the translation vector.
01407      */
01408     void setTranslation(const P& thePoint);
01409 
01410     /**
01411      * return a non-homegeneous point with the actual translation vector
01412      */
01413     P getTranslation() const;
01414 
01415     /**
01416      * Add the normalized homogeneous vector to the one in the matrix
01417      */
01418     void translate(const P& thePoint);
01419 
01420     /**
01421      * Multiply the rotation matrix with a new rotation matrix generated
01422      * from the given %parameters.
01423      * @param angle the rotation angle in radians.
01424      * @param axis this vector is the rotation-axis.
01425      * @param center the contents of this point will be normalized to get the
01426      *               center of the rotation.
01427      */
01428     void rotate(const double& angle,
01429                 const hPoint3D<T>& axis=hPoint3D<T>(0,0,1),
01430                 const hPoint3D<T>& center=hPoint3D<T>());
01431 
01432     /**
01433      * Set rotation submatrix with a new rotation matrix generated
01434      * from the given %parameters.
01435      * @param angle the rotation angle in radians.
01436      * @param axis this vector is the rotation-axis.
01437      * @param center the contents of this point will be normalized to get the
01438      *               center of the rotation.
01439      */
01440     void setRotation(const double& angle,
01441                      const hPoint3D<T>& axis=hPoint3D<T>(0,0,T(1)),
01442                      const hPoint3D<T>& center=hPoint3D<T>());
01443 
01444     /**
01445      * Set similarity transformation.
01446      *
01447      * The similarity transformation is defined as:
01448      * \f[ \begin{bmatrix} 
01449      *        s\cdot \cos(\alpha) & s\cdot -\sin(\alpha) & 0 & t_x \\
01450      *        s\cdot \sin(\alpha) & s\cdot  \cos(\alpha) & 0 & t_y \\
01451      *                 0          &           0          & 1 & 0   \\
01452      *                 0          &           0          & 0 & 1 
01453      *     \end{bmatrix} \f]
01454      * with \a s the scaling factor, \f$\alpha\f$ the rotation angle and
01455      * \f$(t_x,t_y)\f$ the translation.
01456      * @param t point with the two-dimensional translation amount
01457      * @param angle angle amount
01458      * @param scaling scaling amount
01459      */
01460     void setSimilarityTransform(const tpoint<T>& t,
01461                                 const T& angle,
01462                                 const T& scaling);
01463 
01464   protected:
01465     /**
01466      * Memory block with all elements
01467      */
01468     T* theElements;
01469 
01470     /**
01471      * Pointers to each row.
01472      */
01473     T** theRows;
01474 
01475     /**
01476      * Pointer to the element after the last element of the data
01477      */
01478     T* postElement;
01479 
01480     /**
01481      * Initialize the memory.
01482      *
01483      * This method allocates theElements and theRows and ensures that
01484      * theRows points to each row in theElements.
01485      */
01486     void initMem();
01487 
01488     /**
01489      * The real size of the matrix
01490      */
01491     const point theSize;
01492   };
01493 
01494   /**
01495    * Homogeneous matrix to represent linear transformations in a
01496    * two-dimensional projective space.
01497    *
01498    * The two-dimensional transformations are represented by 3x3 matrices of
01499    * the form:
01500    * \f[\begin{bmatrix}
01501    *       r_1 & r_2 & t_x \\ r_3 & r_4 & t_y \\ 0 & 0 & 1
01502    *    \end{bmatrix}\f]
01503    * where the terms \f$r_i\f$ represent a rotation and scaling and the
01504    * terms \f$t_\zeta\f$ the translation.
01505    */
01506   template <class T>
01507   class hMatrix2D : public hMatrix<T,hPoint2D<T> > {
01508     public:
01509     /**
01510      * Default constructor
01511      */
01512     hMatrix2D();
01513 
01514     /**
01515      * Copy constructor
01516      */
01517     hMatrix2D(const hMatrix2D<T>& other);
01518 
01519     /**
01520      * Copy constructor
01521      */
01522     hMatrix2D(const matrix<T>& other);
01523 
01524     /**
01525      * Destructor
01526      */
01527     virtual ~hMatrix2D();
01528 
01529     /**
01530      * Multiply this matrix with another homogeneous matrix and
01531      * leave the result here.
01532      */
01533     inline hMatrix2D<T>& multiply(const hMatrix2D<T>& other) {
01534       hMatrix<T,hPoint2D<T> >::multiply(other);
01535       return *this;
01536     };
01537 
01538     /**
01539      * Multiply the matrices a and b and leave the result here.
01540      */
01541     inline hMatrix2D<T>& multiply(const hMatrix2D<T>& a,
01542                                   const hMatrix2D<T>& b) {
01543       hMatrix<T,hPoint2D<T> >::multiply(a,b);
01544       return *this;
01545     };
01546 
01547     /**
01548      * Return a new object which is the result of multiplying this matrix
01549      * with the other one
01550      */
01551     inline hMatrix2D<T> operator*(const hMatrix2D<T>& other) const {
01552       hMatrix2D<T> tmp;
01553       tmp.multiply(*this,other);
01554       return tmp;
01555     };
01556 
01557     /**
01558      * Alias for multiply
01559      */
01560     inline hMatrix2D<T>& operator*=(const hMatrix2D<T>& other) {
01561       return multiply(other);
01562     }
01563 
01564     /**
01565      * Multiply with a point and leave the result in the second
01566      * parameters.
01567      * Return a reference to the second parameters
01568      */
01569     inline hPoint2D<T>& multiply(const hPoint2D<T>& other,
01570                                 hPoint2D<T>& result) const {
01571       return hMatrix<T,hPoint2D<T> >::multiply(other,result);
01572     };
01573 
01574     /**
01575      * Multiply with a point
01576      */
01577     hPoint2D<T> operator*(const hPoint2D<T>& p) const {
01578       hPoint2D<T> temp;
01579       multiply(p,temp);
01580 
01581       return temp;
01582     };
01583 
01584     /**
01585      * Multiply with a point and leave the result in the second
01586      * parameters.
01587      * Return a reference to the second parameters
01588      */
01589     tpoint<T>& multiply(const tpoint<T>& other,
01590                               tpoint<T>& result) const;
01591 
01592     /**
01593      * Multiply with a point
01594      */
01595     tpoint<T> operator*(const tpoint<T>& p) const {
01596       tpoint<T> temp;
01597       multiply(p,temp);
01598 
01599       return temp;
01600     };
01601   };
01602 
01603   /**
01604    * Homogeneous matrix in 3D projective space.
01605    *
01606    * The three-dimensional transformations are represented by 4x4 matrices of
01607    * the form:
01608    * \f[\begin{bmatrix}
01609    *       r_1 & r_2 & r_3 & t_x \\ 
01610    *       r_4 & r_5 & r_6 & t_y \\ 
01611    *       r_7 & r_8 & r_9 & t_z \\
01612    *       0   & 0   & 0   & 1
01613    *    \end{bmatrix}\f]
01614    * where the terms \f$r_i\f$ represent a rotation and scaling and the
01615    * terms \f$t_\zeta\f$ the translation.
01616    */
01617   template <class T>
01618   class hMatrix3D : public hMatrix<T,hPoint3D<T> > {
01619     public:
01620     /**
01621      * default constructor
01622      */
01623     hMatrix3D();
01624 
01625     /**
01626      * copy constructor
01627      */
01628     hMatrix3D(const hMatrix3D<T>& other);
01629 
01630     /**
01631      * copy constructor
01632      */
01633     hMatrix3D(const hMatrix2D<T>& other);
01634 
01635     /**
01636      * copy constructor
01637      */
01638     hMatrix3D(const matrix<T>& other);
01639 
01640     /**
01641      * destructor
01642      */
01643     virtual ~hMatrix3D();
01644 
01645     /**
01646      * multiply this matrix with another homogeneous matrix and
01647      * leave the result here.
01648      */
01649     inline hMatrix3D<T>& multiply(const hMatrix3D<T>& other) {
01650       hMatrix<T,hPoint3D<T> >::multiply(other);
01651       return *this;
01652     };
01653 
01654     /**
01655      * multiply the matrices a and b and leave the result here.
01656      */
01657     inline hMatrix3D<T>& multiply(const hMatrix3D<T>& a,
01658                                   const hMatrix3D<T>& b) {
01659       hMatrix<T,hPoint3D<T> >::multiply(a,b);
01660       return *this;
01661     };
01662 
01663     /**
01664      * return a new object which is the result of multiplying this matrix
01665      * with the other one
01666      */
01667     inline hMatrix3D<T> operator*(const hMatrix3D<T>& other) {
01668       hMatrix3D<T> tmp;
01669       tmp.multiply(*this,other);
01670       return tmp;
01671     };
01672 
01673     /**
01674      * alias for multiply
01675      */
01676     inline hMatrix3D<T>& operator*=(const hMatrix3D<T>& other) {
01677       return multiply(other);
01678     }
01679 
01680     /**
01681      * multiply with a point and leave the result in the second
01682      * parameters.
01683      * Return a reference to the second parameters
01684      */
01685     inline hPoint3D<T>& multiply(const hPoint3D<T>& other,
01686                                 hPoint3D<T>& result) const {
01687       return hMatrix<T,hPoint3D<T> >::multiply(other,result);
01688     };
01689 
01690     /**
01691      * multiply with a point
01692      */
01693     hPoint3D<T> operator*(const hPoint3D<T>& p) const {
01694       hPoint3D<T> temp;
01695       multiply(p,temp);
01696 
01697       return temp;
01698     };
01699 
01700     /**
01701      * multiply with a point and leave the result in the second
01702      * parameters.
01703      * Return a reference to the second parameters
01704      */
01705     tpoint3D<T>& multiply(const tpoint3D<T>& other,
01706                                 tpoint3D<T>& result) const;
01707 
01708     /**
01709      * multiply with a point
01710      */
01711     tpoint3D<T> operator*(const tpoint3D<T>& p) const {
01712       tpoint3D<T> temp;
01713       multiply(p,temp);
01714 
01715       return temp;
01716     };
01717 
01718     /**
01719      * multiply with a point (assume z=0) and leave the result in the second
01720      * parameter.
01721      * Return a reference to the second parameters
01722      */
01723     hPoint2D<T>& multiply(const hPoint2D<T>& other,
01724                                 hPoint2D<T>& result) const;
01725 
01726     /**
01727      * multiply with a point (assume z=0).
01728      */
01729     hPoint2D<T> operator*(const hPoint2D<T>& p) const {
01730       hPoint2D<T> temp;
01731       multiply(p,temp);
01732 
01733       return temp;
01734     };
01735 
01736     /**
01737      * multiply with a point (assume z=0) and leave the result in the second
01738      * parameters.
01739      * @return a reference to the second parameter
01740      */
01741     tpoint<T>& multiply(const tpoint<T>& other,
01742                               tpoint<T>& result) const;
01743 
01744     /**
01745      * multiply with a point (assume z=0)
01746      */
01747     tpoint<T> operator*(const tpoint<T>& p) const {
01748       tpoint<T> temp;
01749       multiply(p,temp);
01750 
01751       return temp;
01752     };
01753 
01754   };
01755 
01756 
01757   /**
01758    * homogeneous transformation matrix for 2D homogeneous points
01759    * of type double
01760    */
01761   typedef hMatrix2D<double> dhMatrix2D;
01762 
01763   /**
01764    * homogeneous transformation matrix for 2D homogeneous points
01765    * of type float
01766    */
01767   typedef hMatrix2D<float> fhMatrix2D;
01768 
01769 
01770   /**
01771    * homogeneous transformation matrix for 3D homogeneous points
01772    * of type double
01773    */
01774   typedef hMatrix3D<double> dhMatrix3D;
01775 
01776   /**
01777    * homogeneous transformation matrix for 3D homogeneous points
01778    * of type float
01779    */
01780   typedef hMatrix3D<float> fhMatrix3D;
01781 
01782   /**
01783    * write the vector in the given ioHandler.  The complete flag indicates
01784    * if the enclosing begin and end should be also be written or not
01785    */
01786   template<class T,class P>
01787     bool write(ioHandler& handler,const hMatrix<T,P>& mat,
01788                const bool complete=true) {
01789     return mat.write(handler,complete);
01790   }
01791 
01792   /**
01793    * read the vector from the given ioHandler.  The complete flag indicates
01794    * if the enclosing begin and end should be also be read or not
01795    */
01796   template<class T,class P>
01797     bool read(ioHandler& handler,hMatrix<T,P>& mat,
01798               const bool complete=true) {
01799     return mat.read(handler,complete);
01800   }
01801 
01802 }
01803 
01804 namespace std {
01805   template<class T>
01806     ostream& operator<<(ostream& out,const lti::hPoint2D<T>& p) {
01807     out << "(" << p.x << "," << p.y << "," << p.h << ")";
01808     return out;
01809   }
01810 
01811   template<class T>
01812   ostream& operator<<(ostream& out,const lti::hPoint3D<T>& p) {
01813     out << "(" << p.x << "," << p.y << "," << p.z << "," << p.h << ")";
01814     return out;
01815   }
01816 
01817   template<class T,class P>
01818   ostream& operator<<(ostream& out,const lti::hMatrix<T,P>& p) {
01819     out << endl << "(";
01820     for (int j=0;j<P::totalDimensionality;++j) {
01821       if (j>0) {
01822         out << " (";
01823       } else {
01824         out << "(";
01825       }
01826       for (int i=0;i<P::totalDimensionality;++i) {
01827         out.width(14);
01828         out << p.at(j,i);
01829       }
01830       out << ")" << endl ;
01831     }
01832     out << ")" << endl;
01833     return out;
01834   }
01835 
01836 }
01837 
01838 
01839 #endif

Generated on Sat Apr 10 15:25:40 2010 for LTI-Lib by Doxygen 1.6.1