CVR-Lib last update 20 Sep 2009

cvrRectangle.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 1998-2004
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  *
00006  * This file is part of the Computer Vision and Robotics Library (CVR-Lib)
00007  *
00008  * The CVR-Lib is free software; you can redistribute it and/or
00009  * modify it under the terms of the BSD License.
00010  *
00011  * All rights reserved.
00012  *
00013  * Redistribution and use in source and binary forms, with or without
00014  * modification, are permitted provided that the following conditions are met:
00015  *
00016  * 1. Redistributions of source code must retain the above copyright notice,
00017  *    this list of conditions and the following disclaimer.
00018  *
00019  * 2. Redistributions in binary form must reproduce the above copyright notice,
00020  *    this list of conditions and the following disclaimer in the documentation
00021  *    and/or other materials provided with the distribution.
00022  *
00023  * 3. Neither the name of the authors nor the names of its contributors may be
00024  *    used to endorse or promote products derived from this software without
00025  *    specific prior written permission.
00026  *
00027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00028  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00030  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00031  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00032  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00033  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00034  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00035  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00036  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00037  * POSSIBILITY OF SUCH DAMAGE.
00038  */
00039 
00040 
00041 
00042 /**
00043  * \file   cvrRectangle.h
00044  *         Contains template class for aligned rectangles, which are described
00045  *         through two points.
00046  * \author Pablo Alvarado
00047  * \date   01.11.2002
00048  *
00049  * $Id: cvrRectangle.h,v 1.9 2007/10/22 00:47:18 alvarado Exp $
00050  */
00051 
00052 #ifndef _CVR_RECTANGLE_H
00053 #define _CVR_RECTANGLE_H
00054 
00055 #include "cvrIoHandler.h"
00056 #include "cvrPoint.h"
00057 #include "cvrTypeInfo.h"
00058 
00059 #include <iostream>
00060 
00061 namespace cvr {
00062 
00063   /**
00064    * Policy class to compute the size of a rectangle's side and the
00065    * inverse transformation.
00066    *
00067    * For integer types it assumes the rectangle lies on a discrete grid with
00068    * grid elements of size 1x1, which means that the size of a side defined by
00069    * two scalar values x1 and x2 (x2>x1) is x2-x1+1.
00070    *
00071    * For floating point values the size is just x2-x1, because of the
00072    * assumption that the rectangle lies on a real valued 2D space.
00073    *
00074    * The template parameter T represents the type used for the coordinates, and
00075    * is usually int or float.
00076    */
00077   template <typename T>
00078   class rectangleSide {
00079   public:
00080     /**
00081      * Return the size of a rectangle's side which is aligned with one
00082      * of the two coordinates, assuming that the delimiting coordinates are
00083      * x1 and x2.
00084      *
00085      * For example:
00086      * - if T is int, x1=0 and x2=2, then returns 3
00087      * - if T is float, x1=0 and x2=2 then returns 2
00088      */
00089     static inline T size(const T x1,const T x2);
00090 
00091     /**
00092      * For a given side size, compute two coordinates which generates it.
00093      *
00094      * For example:
00095      * - if T is int and sz is 3, the returned values would be
00096      *   x1=-1 and x2=1.
00097      * - if T is float and sz = 3, the returned values would be
00098      *   x1=-1.5 and x2=1.5
00099      */
00100     static inline void invSize(const T sz,T& x1,T& x2);
00101   };
00102 
00103   // specialization for float
00104   template <>
00105   class rectangleSide<float> {
00106   public:
00107     static inline float size(const float x1,const float x2);
00108     static inline void invSize(const float sz,float& x1,float& x2);
00109   };
00110 
00111   // specialization for double
00112   template <>
00113   class rectangleSide<double> {
00114   public:
00115     static inline double size(const double x1,const double x2);
00116     static inline void invSize(const double sz,double& x1,double& x2);
00117   };
00118 
00119   /**
00120    * Rectangle representation class.
00121    *
00122    * A rectangle is described by a pair of points: the upper-left and
00123    * bottom-right corners.
00124    *
00125    * A consistent rectangle will have the x and y coordinates of its upper-
00126    * left corner smaller than the ones of its bottom-right corner (note
00127    * the use of a left coordinate system, as usual with imaging systems).
00128    *
00129    * You can always check if a rectangle is consistent with the method
00130    * \c isConsistent() or even force its consistency with
00131    * \c ensureConsistency().
00132    *
00133    * This is a template class, where the first template parameter \c T
00134    * denotes the type used for the two points, which will be of type
00135    * \c point<T>.  For example, the type rectangle<int> (which
00136    * has the alias irectangle) contains to ipoints (point<int>) as corner
00137    * representation.  You can access the type T through the public type
00138    * \c value_type.
00139    *
00140    * The second template parameter S is optional and allows the rectangle to
00141    * behave correctly in a discrete integer grid or in a continuous real grid
00142    * (please see the cvr::rectangleSide policy for more information).
00143    *
00144    * @ingroup gGeomData
00145    */
00146   template <typename T,class S=rectangleSide<T> >
00147   class rectangle {
00148   public:
00149     /**
00150      * Type used in each coordinate of the two internal points
00151      */
00152     typedef T value_type;
00153 
00154     /**
00155      * Type used for the side policy
00156      */
00157     typedef S side_type;
00158 
00159     /**
00160      * \name The two corners of the rectangle
00161      */
00162     //@{
00163     /**
00164      * Upper-left point<T>
00165      */
00166     point<T> ul;
00167 
00168     /**
00169      * Bottom-right point<T>
00170      */
00171     point<T> br;
00172     //@}
00173 
00174     /**
00175      * Default constructor
00176      *
00177      * The two points \a ul and \a br will be initialized with (0,0)
00178      */
00179     rectangle();
00180 
00181     /**
00182      * Constructor with two points
00183      *
00184      * @param ul upper left corner
00185      * @param br bottom right corner
00186      */
00187     rectangle(const point<T>& ul,const point<T>& br);
00188 
00189     /**
00190      * Construct a rectangle via separate coordinates
00191      *
00192      * @param left left side coordinate
00193      * @param top top side coordinate
00194      * @param right right side coordinate
00195      * @param bottom bottom side coordinate
00196      */
00197     rectangle(const T& left,const T& top,
00198               const T& right,const T& bottom);
00199 
00200     /**
00201      * Construct a square with the given side size.
00202      *
00203      * If the size is even and T is an integer type, the rectangle
00204      * will be created from -|_size/2_| to size + |_size/2_| in both
00205      * coordinates x and y.
00206      */
00207     rectangle(const T& size);
00208 
00209     /**
00210      * Copy constructor
00211      */
00212     template<typename U,class US>
00213     rectangle(const rectangle<U,US>& other);
00214 
00215 
00216     /**
00217      * Set the corners via separate coordinates
00218      *
00219      * You must ensure that the data is consistent, i.e. left < right and
00220      * top < bottom.  See setConsistent().
00221      *
00222      * @param left left side coordinate
00223      * @param top top side coordinate
00224      * @param right right side coordinate
00225      * @param bottom bottom side coordinate
00226      * @return true when successful, false otherwise
00227      */
00228     inline bool set(const T& left, const T& top,
00229                     const T& right, const T& bottom);
00230 
00231 
00232     /**
00233      * Set the corners via two points
00234      *
00235      * You must ensure that the data is consistent, i.e. ul.x < br.x and
00236      * ul.y < br.y.  See setConsistent().
00237      *
00238      * @param ul upper left corner
00239      * @param br bottom right corner
00240      * @return true upon success, false otherwise
00241      */
00242     inline bool set(const point<T>& ul, const point<T>& br);
00243 
00244     /**
00245      * Set the corners via separate coordinates.
00246      *
00247      * This method ensures consistency of the resulting rectangle, no matter if
00248      * the given data implies negative sides.
00249      *
00250      * @param left left side coordinate
00251      * @param top top side coordinate
00252      * @param right right side coordinate
00253      * @param bottom bottom side coordinate
00254      * @return true when successful, false otherwise
00255      */
00256     inline bool setConsistent(const T& left, const T& top,
00257                               const T& right, const T& bottom);
00258 
00259 
00260     /**
00261      * Set the corners via two points
00262      *
00263      * This method ensures consistency of the resulting rectangle, no matter if
00264      * the given data implies negative sides.
00265      *
00266      * @param ul upper left corner
00267      * @param br bottom right corner
00268      * @return true upon success, false otherwise
00269      */
00270     inline bool setConsistent(const point<T>& ul, const point<T>& br);
00271 
00272 
00273     /**
00274      * @name Location and Dimensions
00275      */
00276     //@{
00277 
00278     /**
00279      * Resize rectangle<T,S> with new dimensions, but keep its center
00280      */
00281     void resize(const point<T>& dim);
00282 
00283     /**
00284      * Resize rectangle<T,S> with new dimensions, but keep its center
00285      */
00286     void resize(const T& x, const T& y);
00287 
00288     /**
00289      * Get dimensions of rectangle<T,S>.  If one coordinate of the two
00290      * points coincide and the rectangle contains fixed point typed
00291      * points, the returned dimension is one.  For floating point
00292      * types this case will return 0.
00293      *
00294      * \warning Note that the result of this method depends on the type T
00295      *
00296      * For integer types it will be assumed that the rectangle lies on
00297      * a discrete grid with grid elements of size 1x1, and that is not
00298      * the rectangle itself what is described but the number of grid
00299      * elements.  This means that the size of a side defined by two
00300      * scalar values x1 and x2 (x2>x1) is x2-x1+1.  This is useful for
00301      * example when dealing with rectangular regions of images.
00302      *
00303      * For floating point values the size is just x2-x1, because of
00304      * the assumtion that the rectangle lies on a real valued 2D space.
00305      */
00306     inline point<T> getDimensions() const;
00307 
00308     /**
00309      * Get the area of this rectangle. This value is always
00310      * positive, regardless of the position of the upper left and
00311      * bottom right corner. A rectangle whose corners coincide
00312      * has an area of 1 for fixed point types or 0 for floating point ones.
00313      *
00314      * \warning Note that the result of this method depends on the type T
00315      *
00316      * For integer types it will be assumed that the rectangle lies on
00317      * a discrete grid with grid elements of size 1x1, and that is not
00318      * the rectangle itself what is described but the index of grid
00319      * elements.  This means that the size of a side defined by two
00320      * scalar values x1 and x2 (x2>x1) is x2-x1+1.  This is useful for
00321      * example when dealing with rectangular regions of images.
00322      *
00323      * For floating point values the size is just x2-x1, because of
00324      * the assumtion that the rectangle lies on a real valued 2D space.
00325      */
00326     inline typename typeInfo<T>::square_accumulation_type getArea() const;
00327 
00328     /**
00329      * Get center of rectangle<T,S>
00330      */
00331     inline point<T> getCenter() const;
00332 
00333     /**
00334      * Set the center of this rectangle.
00335      */
00336     void setCenter(point<T> center);
00337 
00338     /**
00339      * Ensure consistency of upper-left and bottom-right corners.
00340      * A rectangle<T,S> is called "consistent" if the upper-left
00341      * point<T> has lower coordinate-values than the bottom-right
00342      * point<T>.
00343      */
00344     void ensureConsistency();
00345 
00346     /**
00347      * Check for consistent rectangle<T,S>.
00348      * @return True if upper-left corner and bottom-right are correct
00349      */
00350     inline bool isConsistent() const;
00351 
00352     /**
00353      * Shift rectangle<T,S> by delta
00354      *
00355      * @param delta The shift amount to be added to both corners
00356      */
00357     inline void shift(const point<T>& delta);
00358 
00359     /**
00360      * Shift the other rectangle<T,S> by delta and leave the result here
00361      *
00362      * @param other The reference rectangle
00363      * @param delta The shift amount to be added to both corners of the
00364      *              reference rectangle
00365      */
00366     inline void shift(const rectangle<T,S>& other,
00367                       const point<T>& delta);
00368     //@}
00369 
00370     /**
00371      * @name Simple operations
00372      */
00373     //@{
00374 
00375     /**
00376      * Check if point<T> p is inside this rectangle. (border inclusive!)
00377      */
00378     inline bool contains(const point<T>& p) const;
00379 
00380     /**
00381      * Check if the given coordinates are inside this rectangle.
00382      * (border included!)
00383      */
00384     inline bool contains(const T& x, const T& y) const;
00385 
00386     //@}
00387 
00388     /**
00389      * @name Duplication
00390      */
00391     //@{
00392 
00393     /**
00394      * Copy member
00395      */
00396     rectangle<T,S>& copy(const rectangle<T,S>& other);
00397 
00398     /**
00399      * Cast from a rectangle of another type
00400      */
00401     template <class U,class SU>
00402     rectangle<T,S>& castFrom(const rectangle<U,SU>& other);
00403 
00404     /**
00405      * Alias for copy
00406      */
00407     inline rectangle<T,S>& operator=(const rectangle<T,S>& other);
00408 
00409     //@}
00410 
00411     /**
00412      * @name Comparison
00413      */
00414     //@{
00415 
00416     /**
00417      * Test for equality
00418      */
00419     inline bool operator==(const rectangle<T,S>& other) const;
00420 
00421     /**
00422      * Test for inequality
00423      */
00424     inline bool operator!=(const rectangle<T,S>& other) const;
00425 
00426     //@}
00427 
00428     /**
00429      * @name Geometrical combination
00430      */
00431     //@{
00432 
00433     /**
00434      * Intersection of this rectangle with tRect
00435      *
00436      * (the largest rectangle which is contained both inside this
00437      * rectangle and inside tRect).
00438      *
00439      * The result will be left in this instance. If the rectangles do
00440      * not intersect, the resul will be inconsistent, so you should
00441      * call isConsistent() to check for this case unless you know for
00442      * sure that it cannot occur.
00443      *
00444      * @return A reference to this (modified) instance.
00445      */
00446     rectangle<T,S>& intersect(const rectangle<T,S>& tRect);
00447 
00448     /**
00449      * Check whether this rectangle overlaps with the given rectangle.
00450      */
00451     bool overlaps(const rectangle<T,S>& tRect) const;
00452 
00453     /**
00454      * Check whether this rectangle is close to the given rectangle, i.e.
00455      * if the two rectangles overlap if one is extended by the given distance.
00456      */
00457     bool isClose(const rectangle<T,S>& tRect, const point<T>& dist) const;
00458 
00459     /**
00460      * This rectangle is set to the intersection of himself with tRect.
00461      * (alias for intersect)
00462      */
00463     inline rectangle<T,S>& operator&=(const rectangle<T,S>& tRect);
00464 
00465     /**
00466      * New rectangle equals the intersection of this rectangle with tRect
00467      */
00468     inline rectangle<T,S> operator&(const rectangle<T,S>& tRect);
00469 
00470     /**
00471      * Union-rectangle of this rectangle with tRect.
00472      *
00473      * This is the smallest rectangle containing both this rectangle and
00474      * tRect. The result will be left in this instance.
00475      *
00476      * @return A reference to this (modified) instance.
00477      */
00478     rectangle<T,S>& join(const rectangle<T,S>& tRect);
00479 
00480     /**
00481      * This rectangle is set to the union-rectangle of this rectangle with
00482      * tRect (alias for join()).
00483      */
00484     inline rectangle<T,S>& operator|=(const rectangle<T,S>& tRect);
00485 
00486     /**
00487      * Generates a new rectangle equal to the smallest rectangle that
00488      * contains the union of this rectangle with tRect
00489      */
00490     rectangle<T,S> operator|(const rectangle<T,S>& tRect);
00491     //@}
00492   };
00493 
00494   /**
00495    * A rectangle with integer coordinates
00496    */
00497   typedef rectangle<int> irectangle;
00498 
00499   /**
00500    * A rectangle with float coordinates
00501    */
00502   typedef rectangle<float> frectangle;
00503 
00504   /**
00505    * A rectangle with double coordinates
00506    */
00507   typedef rectangle<double> drectangle;
00508 
00509   /**
00510    * Read the vector from the given ioHandler.  The complete flag indicates
00511    * if the enclosing begin and end should be also read.
00512    *
00513    * @ingroup gStorable
00514    */
00515   template<typename T,class S>
00516   bool read(ioHandler& handler,rectangle<T,S>& p,const bool complete=true);
00517 
00518   /**
00519    * Write the vector in the given ioHandler.  The complete flag indicates
00520    * if the enclosing begin and end should be also written.
00521    *
00522    * @ingroup gStorable
00523    */
00524   template <typename T,class S>
00525   bool write(ioHandler& handler,const rectangle<T,S>& p,
00526              const bool complete=true);
00527 }
00528 
00529 namespace std {
00530 
00531   template <typename T,class S>
00532   inline ostream& operator<<(ostream& s,const cvr::rectangle<T,S>& p);
00533 
00534   template <typename T,class S>
00535   inline istream& operator>>(istream& s,cvr::rectangle<T,S>& p);
00536 }
00537 
00538 #include "cvrRectangle_inline.h"
00539 #include "cvrRectangle_template.h"
00540 
00541 #endif
00542 

Generated on Sun Sep 20 22:08:00 2009 for CVR-Lib by Doxygen 1.5.8