LTI-Lib latest version v1.9 - last update 24 Nov 2005
Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ltiHTypes.h

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

Generated on Thu Nov 24 16:26:02 2005 for LTI-Lib by Doxygen 1.4.4