vigra - vigra/diff2d.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/diff2d.hxx |

    00001 /************************************************************************/
    00002 /*                                                                      */
    00003 /*                  Copyright 1998-2003 by Hans Meine                   */
    00004 /*                                                                      */
    00005 /*    This file is part of the VIGRA computer vision library.           */
    00006 /*    The VIGRA Website is                                              */
    00007 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
    00008 /*    Please direct questions, bug reports, and contributions to        */
    00009 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00010 /*        vigra@informatik.uni-hamburg.de                               */
    00011 /*                                                                      */
    00012 /*    Permission is hereby granted, free of charge, to any person       */
    00013 /*    obtaining a copy of this software and associated documentation    */
    00014 /*    files (the "Software"), to deal in the Software without           */
    00015 /*    restriction, including without limitation the rights to use,      */
    00016 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00017 /*    sell copies of the Software, and to permit persons to whom the    */
    00018 /*    Software is furnished to do so, subject to the following          */
    00019 /*    conditions:                                                       */
    00020 /*                                                                      */
    00021 /*    The above copyright notice and this permission notice shall be    */
    00022 /*    included in all copies or substantial portions of the             */
    00023 /*    Software.                                                         */
    00024 /*                                                                      */
    00025 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00026 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00027 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00028 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00029 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00030 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00031 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00032 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00033 /*                                                                      */
    00034 /************************************************************************/
    00035
    00036 #ifndef VIGRA_DIFF2D_HXX
    00037 #define VIGRA_DIFF2D_HXX
    00038
    00039 #include <cmath> // for sqrt()
    00040 #include <iosfwd>
    00041 #include "config.hxx"
    00042 #include "iteratortags.hxx"
    00043 #include "iteratortraits.hxx"
    00044 #include "iteratoradapter.hxx"
    00045 #include "tuple.hxx"
    00046
    00047
    00048 namespace vigra {
    00049
    00050
    00051 template <class Diff>
    00052 class Diff2DConstRowIteratorPolicy
    00053 {
    00054   public:
    00055     typedef Diff                            BaseType;
    00056     typedef Diff                            value_type;
    00057     typedef typename Diff::MoveX            difference_type;
    00058     typedef Diff const &                    reference;
    00059     typedef Diff                            index_reference;
    00060     typedef Diff const *                    pointer;
    00061     typedef std::random_access_iterator_tag iterator_category;
    00062
    00063     static void initialize(BaseType &) {}
    00064
    00065     static reference dereference(BaseType const & d)
    00066         { return d; }
    00067
    00068     static index_reference dereference(BaseType d, difference_type n)
    00069     {
    00070         d.x += n;
    00071         return d;
    00072     }
    00073
    00074     static bool equal(BaseType const & d1, BaseType const & d2)
    00075         { return d1.x == d2.x; }
    00076
    00077     static bool less(BaseType const & d1, BaseType const & d2)
    00078         { return d1.x < d2.x; }
    00079
    00080     static difference_type difference(BaseType const & d1, BaseType const & d2)
    00081         { return d1.x - d2.x; }
    00082
    00083     static void increment(BaseType & d)
    00084         { ++d.x; }
    00085
    00086     static void decrement(BaseType & d)
    00087         { --d.x; }
    00088
    00089     static void advance(BaseType & d, difference_type n)
    00090         { d.x += n; }
    00091 };
    00092
    00093 template <class Diff>
    00094 class Diff2DConstColumnIteratorPolicy
    00095 {
    00096   public:
    00097     typedef Diff                            BaseType;
    00098     typedef Diff                            value_type;
    00099     typedef typename Diff::MoveY            difference_type;
    00100     typedef Diff const &                    reference;
    00101     typedef Diff                            index_reference;
    00102     typedef Diff const *                    pointer;
    00103     typedef std::random_access_iterator_tag iterator_category;
    00104
    00105     static void initialize(BaseType & /*d*/) {}
    00106
    00107     static reference dereference(BaseType const & d)
    00108         { return d; }
    00109
    00110     static index_reference dereference(BaseType d, difference_type n)
    00111     {
    00112         d.y += n;
    00113         return d;
    00114     }
    00115
    00116     static bool equal(BaseType const & d1, BaseType const & d2)
    00117         { return d1.y == d2.y; }
    00118
    00119     static bool less(BaseType const & d1, BaseType const & d2)
    00120         { return d1.y < d2.y; }
    00121
    00122     static difference_type difference(BaseType const & d1, BaseType const & d2)
    00123         { return d1.y - d2.y; }
    00124
    00125     static void increment(BaseType & d)
    00126         { ++d.y; }
    00127
    00128     static void decrement(BaseType & d)
    00129         { --d.y; }
    00130
    00131     static void advance(BaseType & d, difference_type n)
    00132         { d.y += n; }
    00133 };
    00134
    00135 /** \addtogroup RangesAndPoints Ranges and Points
    00136
    00137     Specify 2-D and N-D positions, extents, and boxes.
    00138 */
    00139 //@{
    00140
    00141 /********************************************************/
    00142 /*                                                      */
    00143 /*                      Diff2D                          */
    00144 /*                                                      */
    00145 /********************************************************/
    00146
    00147 /** \brief Two dimensional difference vector.
    00148
    00149     This class acts primarily as a difference vector for specifying
    00150     pixel coordinates and region sizes. In addition, Diff2D fulfills
    00151     the requirements of an \ref ImageIterator, so that it can be used to
    00152     simulate an image whose pixels' values equal their coordinates. This
    00153     secondary usage is explained on page \ref CoordinateIterator.
    00154
    00155     Standard usage as a difference vector is mainly needed in the context
    00156     of images. For example, Diff2D may be used as an index for <TT>operator[]</TT>:
    00157
    00158     \code
    00159     vigra::Diff2D location(...);
    00160
    00161     value = image[location];
    00162     \endcode
    00163
    00164     This is especially important in connection with accessors, where the
    00165     offset variant of <TT>operator()</TT> takes only one offset object:
    00166
    00167     \code
    00168     // accessor(iterator, dx, dy); is not allowed
    00169     value = accessor(iterator, vigra::Diff2D(dx, dy));
    00170     \endcode
    00171
    00172
    00173     Diff2D is also returned by <TT>image.size()</TT>, so that we can create
    00174     new images by calculating their size using Diff2D's arithmetic
    00175     functions:
    00176
    00177     \code
    00178     // create an image that is 10 pixels smaller in each direction
    00179     Image new_image(old_image.size() - Diff2D(10,10));
    00180     \endcode
    00181
    00182     <b>\#include</b> <vigra/diff2d.hxx><br>
    00183     Namespace: vigra
    00184 */
    00185 class Diff2D
    00186 {
    00187   public:
    00188         /** The iterator's value type: a coordinate.
    00189         */
    00190     typedef Diff2D PixelType;
    00191
    00192         /** The iterator's value type: a coordinate.
    00193         */
    00194     typedef Diff2D value_type;
    00195
    00196         /** the iterator's reference type (return type of <TT>*iter</TT>)
    00197         */
    00198     typedef Diff2D const &       reference;
    00199
    00200         /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
    00201         */
    00202     typedef Diff2D               index_reference;
    00203
    00204         /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
    00205         */
    00206     typedef Diff2D const *       pointer;
    00207
    00208         /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
    00209         */
    00210     typedef Diff2D               difference_type;
    00211
    00212         /** the iterator tag (image traverser)
    00213         */
    00214     typedef image_traverser_tag  iterator_category;
    00215
    00216         /** The associated row iterator.
    00217         */
    00218     typedef IteratorAdaptor<Diff2DConstRowIteratorPolicy<Diff2D> >    row_iterator;
    00219
    00220         /** The associated column iterator.
    00221         */
    00222    typedef IteratorAdaptor<Diff2DConstColumnIteratorPolicy<Diff2D> > column_iterator;
    00223
    00224         /** type of the iterator's x-navigator
    00225         */
    00226     typedef int MoveX;
    00227         /** type of the iterator's y-navigator
    00228         */
    00229     typedef int MoveY;
    00230
    00231
    00232         /** Default Constructor. Init iterator at position (0,0)
    00233         */
    00234     Diff2D()
    00235     : x(0), y(0)
    00236     {}
    00237
    00238         /** Construct at given position.
    00239         */
    00240     Diff2D(int ax, int ay)
    00241     : x(ax), y(ay)
    00242     {}
    00243
    00244         /** Copy Constructor.
    00245         */
    00246     Diff2D(Diff2D const & v)
    00247     : x(v.x), y(v.y)
    00248     {}
    00249
    00250         /** Copy Assigment.
    00251         */
    00252     Diff2D & operator=(Diff2D const & v)
    00253     {
    00254         if(this != &v)
    00255         {
    00256             x = v.x;
    00257             y = v.y;
    00258         }
    00259         return *this;
    00260     }
    00261
    00262         /** Unary negation.
    00263         */
    00264     Diff2D operator-() const
    00265     {
    00266         return Diff2D(-x, -y);
    00267     }
    00268
    00269         /** Increase coordinate by specified offset.
    00270         */
    00271     Diff2D & operator+=(Diff2D const & offset)
    00272     {
    00273         x += offset.x;
    00274         y += offset.y;
    00275         return *this;
    00276     }
    00277
    00278         /** Decrease coordinate by specified vector.
    00279         */
    00280     Diff2D & operator-=(Diff2D const & offset)
    00281     {
    00282         x -= offset.x;
    00283         y -= offset.y;
    00284         return *this;
    00285     }
    00286
    00287        /** Create vector by scaling by factor.
    00288         */
    00289     Diff2D & operator*=(int factor)
    00290     {
    00291         x *= factor;
    00292         y *= factor;
    00293         return *this;
    00294     }
    00295
    00296        /** Create vector by scaling by factor.
    00297         */
    00298     Diff2D & operator*=(double factor)
    00299     {
    00300         x = (int)(x * factor);
    00301         y = (int)(y * factor);
    00302         return *this;
    00303     }
    00304
    00305        /** Create vector by scaling by 1/factor.
    00306         */
    00307     Diff2D & operator/=(int factor)
    00308     {
    00309         x /= factor;
    00310         y /= factor;
    00311         return *this;
    00312     }
    00313
    00314        /** Create vector by scaling by 1/factor.
    00315         */
    00316     Diff2D & operator/=(double factor)
    00317     {
    00318         x = (int)(x / factor);
    00319         y = (int)(y / factor);
    00320         return *this;
    00321     }
    00322
    00323        /** Create vector by scaling by factor.
    00324         */
    00325     Diff2D operator*(int factor) const
    00326     {
    00327         return Diff2D(x * factor, y * factor);
    00328     }
    00329
    00330        /** Create vector by scaling by factor.
    00331         */
    00332     Diff2D operator*(double factor) const
    00333     {
    00334         return Diff2D((int)(x * factor), (int)(y * factor));
    00335     }
    00336
    00337        /** Create vector by scaling by 1/factor.
    00338         */
    00339     Diff2D operator/(int factor) const
    00340     {
    00341         return Diff2D(x / factor, y / factor);
    00342     }
    00343
    00344        /** Create vector by scaling by 1/factor.
    00345         */
    00346     Diff2D operator/(double factor) const
    00347     {
    00348         return Diff2D((int)(x / factor), (int)(y / factor));
    00349     }
    00350
    00351         /** Calculate length of difference vector.
    00352         */
    00353     int squaredMagnitude() const
    00354     {
    00355         return x*x + y*y;
    00356     }
    00357
    00358         /** Calculate length of difference vector.
    00359         */
    00360     double magnitude() const
    00361     {
    00362         return VIGRA_CSTD::sqrt((double)squaredMagnitude());
    00363     }
    00364
    00365         /** Equality.
    00366         */
    00367     bool operator==(Diff2D const & r) const
    00368     {
    00369         return (x == r.x) && (y == r.y);
    00370     }
    00371
    00372         /** Inequality.
    00373         */
    00374     bool operator!=(Diff2D const & r) const
    00375     {
    00376         return (x != r.x) || (y != r.y);
    00377     }
    00378
    00379         /** Used for both access to the current x-coordinate \em and
    00380             to specify that an iterator navigation command is to be
    00381             applied in x-direction. <br>
    00382             usage:  <TT> x = diff2d.x </TT> (use \p Diff2D::x  as component of difference vector) <br>
    00383             or <TT>&nbsp; ++diff.x &nbsp; </TT> (use Diff2D as iterator, move right)
    00384          */
    00385     int x;
    00386         /** Used for both access to the current y-coordinate \em and
    00387             to specify that an iterator navigation command is to be
    00388             applied in y-direction. <br>
    00389             usage:  <TT> y = diff2d.y </TT> (use \p Diff2D::y as component of difference vector) <br>
    00390             or <TT>&nbsp; ++diff.y &nbsp; </TT> (use Diff2D as iterator, move right)
    00391         */
    00392     int y;
    00393
    00394         /** Access current coordinate.
    00395         */
    00396     reference operator*() const
    00397     {
    00398         return *this;
    00399     }
    00400
    00401         /** Read coordinate at an offset.
    00402         */
    00403     index_reference operator()(int const & dx, int const & dy) const
    00404     {
    00405         return Diff2D(x + dx, y + dy);
    00406     }
    00407
    00408         /** Read coordinate at an offset.
    00409         */
    00410     index_reference operator[](Diff2D const & offset) const
    00411     {
    00412         return Diff2D(x + offset.x, y + offset.y);
    00413     }
    00414
    00415         /** Read vector components.
    00416         */
    00417     int operator[](int index) const
    00418     {
    00419         return (&x)[index];
    00420     }
    00421
    00422         /** Access current coordinate.
    00423         */
    00424     pointer operator->() const
    00425     {
    00426         return this;
    00427     }
    00428
    00429         /** Get a row iterator at the current position.
    00430         */
    00431     row_iterator rowIterator() const
    00432         { return row_iterator(*this); }
    00433
    00434         /** Get a column iterator at the current position.
    00435         */
    00436     column_iterator columnIterator() const
    00437         { return column_iterator(*this); }
    00438 };
    00439
    00440
    00441 template <>
    00442 struct IteratorTraits<Diff2D >
    00443 {
    00444     typedef Diff2D                               Iterator;
    00445     typedef Iterator                             iterator;
    00446     typedef Iterator                             const_iterator;
    00447     // typedef                                   multable_iterator; undefined
    00448     typedef iterator::iterator_category          iterator_category;
    00449     typedef iterator::value_type                 value_type;
    00450     typedef iterator::reference                  reference;
    00451     typedef iterator::index_reference            index_reference;
    00452     typedef iterator::pointer                    pointer;
    00453     typedef iterator::difference_type            difference_type;
    00454     typedef iterator::row_iterator               row_iterator;
    00455     typedef iterator::column_iterator            column_iterator;
    00456     typedef StandardConstValueAccessor<Diff2D>   DefaultAccessor;
    00457     typedef StandardConstValueAccessor<Diff2D>   default_accessor;
    00458     typedef VigraTrueType                        hasConstantStrides;
    00459
    00460 };
    00461
    00462 /********************************************************/
    00463 /*                                                      */
    00464 /*                      Size2D                          */
    00465 /*                                                      */
    00466 /********************************************************/
    00467
    00468 /** \brief Two dimensional size object.
    00469
    00470     Specializes \ref Diff2D for the specification of a 2-dimensional
    00471     extent, in contrast to a point or position (for the latter
    00472     use \ref Point2D).
    00473
    00474     \code
    00475     // create an image that is 10 pixels squared
    00476     Image new_image(Size2D(10,10));
    00477     \endcode
    00478
    00479     <b>\#include</b> <vigra/diff2d.hxx><br>
    00480     Namespace: vigra
    00481 */
    00482 class Size2D : public Diff2D
    00483 {
    00484 public:
    00485         /** Default Constructor. Init point at position (0,0)
    00486         */
    00487     Size2D()
    00488     {}
    00489
    00490         /** Construct point at given position.
    00491         */
    00492     Size2D(int width, int height)
    00493     : Diff2D(width, height)
    00494     {}
    00495
    00496         /** Copy Constructor.
    00497         */
    00498     Size2D(Size2D const & v)
    00499     : Diff2D(v)
    00500     {}
    00501
    00502         /** Explicit conversion Constructor.
    00503         */
    00504     explicit Size2D(Diff2D const & v)
    00505     : Diff2D(v)
    00506     {}
    00507
    00508         /** Query the width.
    00509          */
    00510     int width() const
    00511     {
    00512         return x;
    00513     }
    00514
    00515         /** Query the height.
    00516          */
    00517     int height() const
    00518     {
    00519         return y;
    00520     }
    00521
    00522         /** Change the width.
    00523          */
    00524     void setWidth(int w)
    00525     {
    00526         x = w;
    00527     }
    00528
    00529         /** Change the height.
    00530          */
    00531     void setHeight(int h)
    00532     {
    00533         y = h;
    00534     }
    00535
    00536         /** Returns width()*height(), the area of a rectangle of this size.
    00537          */
    00538     int area() const
    00539     {
    00540         return width()*height();
    00541     }
    00542
    00543         /** Copy Assigment.
    00544         */
    00545     Size2D & operator=(Diff2D const & v)
    00546     {
    00547         return static_cast<Size2D &>(Diff2D::operator=(v));
    00548     }
    00549
    00550         /** Unary negation.
    00551         */
    00552     Size2D operator-() const
    00553     {
    00554         return Size2D(-x, -y);
    00555     }
    00556
    00557         /** Increase size by specified offset.
    00558         */
    00559     Size2D & operator+=(Diff2D const & offset)
    00560     {
    00561         return static_cast<Size2D &>(Diff2D::operator+=(offset));
    00562     }
    00563
    00564         /** Decrease size by specified offset.
    00565         */
    00566     Size2D & operator-=(Diff2D const & offset)
    00567     {
    00568         return static_cast<Size2D &>(Diff2D::operator-=(offset));
    00569     }
    00570 };
    00571
    00572 /********************************************************/
    00573 /*                                                      */
    00574 /*                     Point2D                          */
    00575 /*                                                      */
    00576 /********************************************************/
    00577
    00578 /** \brief Two dimensional point or position.
    00579
    00580     Specializes \ref Diff2D for the specification of a 2-dimensional
    00581     point or position, in contrast to an extent (for the latter
    00582     use \ref Size2D).
    00583
    00584     \code
    00585     // access an image at a point
    00586     value = image[Point2D(10, 20)];
    00587     \endcode
    00588
    00589     <b>\#include</b> <vigra/diff2d.hxx><br>
    00590     Namespace: vigra
    00591 */
    00592 class Point2D : public Diff2D
    00593 {
    00594 public:
    00595         /** The iterator's value type: a coordinate.
    00596         */
    00597     typedef Point2D PixelType;
    00598
    00599         /** The iterator's value type: a coordinate.
    00600         */
    00601     typedef Point2D value_type;
    00602
    00603         /** the iterator's reference type (return type of <TT>*iter</TT>)
    00604         */
    00605     typedef Point2D const & reference;
    00606
    00607         /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
    00608         */
    00609     typedef Point2D         index_reference;
    00610
    00611         /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
    00612         */
    00613     typedef Point2D const * pointer;
    00614
    00615         /** Default Constructor. Init point at position (0,0)
    00616         */
    00617     Point2D()
    00618     {}
    00619
    00620         /** Construct point at given position.
    00621         */
    00622     Point2D(int x, int y)
    00623     : Diff2D(x, y)
    00624     {}
    00625
    00626         /** Copy Constructor.
    00627         */
    00628     Point2D(Point2D const & v)
    00629     : Diff2D(v)
    00630     {}
    00631
    00632         /** Explicit conversion Constructor.
    00633         */
    00634     explicit Point2D(Diff2D const & v)
    00635     : Diff2D(v)
    00636     {}
    00637
    00638         /** Query the points' x coordinate
    00639          */
    00640     int px() const
    00641     {
    00642         return x;
    00643     }
    00644
    00645         /** Query the points' y coordinate
    00646          */
    00647     int py() const
    00648     {
    00649         return y;
    00650     }
    00651
    00652         /** Copy Assigment.
    00653         */
    00654     Point2D & operator=(Diff2D const & v)
    00655     {
    00656         return static_cast<Point2D &>(Diff2D::operator=(v));
    00657     }
    00658
    00659         /** Unary negation.
    00660         */
    00661     Point2D operator-() const
    00662     {
    00663         return Point2D(-x, -y);
    00664     }
    00665
    00666         /** Increase point coordinates by specified offset.
    00667         */
    00668     Point2D & operator+=(Diff2D const & offset)
    00669     {
    00670         return static_cast<Point2D &>(Diff2D::operator+=(offset));
    00671     }
    00672
    00673         /** Decrease point coordinates by specified offset.
    00674         */
    00675     Point2D & operator-=(Diff2D const & offset)
    00676     {
    00677         return static_cast<Point2D &>(Diff2D::operator-=(offset));
    00678     }
    00679
    00680         /** Access current point coordinate.
    00681         */
    00682     reference operator*() const
    00683     {
    00684         return *this;
    00685     }
    00686
    00687         /** Read point coordinate at an offset.
    00688         */
    00689     index_reference operator()(int const & dx, int const & dy) const
    00690     {
    00691         return Point2D(x + dx, y + dy);
    00692     }
    00693
    00694         /** Read point coordinate at an offset.
    00695         */
    00696     index_reference operator[](Diff2D const & offset) const
    00697     {
    00698         return Point2D(x + offset.x, y + offset.y);
    00699     }
    00700
    00701         /** Access current point coordinate.
    00702         */
    00703     pointer operator->() const
    00704     {
    00705         return this;
    00706     }
    00707 };
    00708
    00709 /** Create vector by subtracting specified offset.
    00710  */
    00711 inline Diff2D operator-(Diff2D const &a, Diff2D const &b)
    00712 {
    00713     return Diff2D(a.x - b.x, a.y - b.y);
    00714 }
    00715
    00716 /** Create size by subtracting specified offset.
    00717  */
    00718 inline Size2D operator-(Size2D const & s, Diff2D const &offset)
    00719 {
    00720     return Size2D(s.x - offset.x, s.y - offset.y);
    00721 }
    00722
    00723 /** Calculate size of rect between two points.
    00724  */
    00725 inline Point2D operator-(Point2D const & s, Diff2D const & offset)
    00726 {
    00727     return Point2D(s.x - offset.x, s.y - offset.y);
    00728 }
    00729
    00730 /** The difference of two points is a size
    00731  */
    00732 inline Size2D operator-(Point2D const & s, Point2D const & p)
    00733 {
    00734     return Size2D(s.x - p.x, s.y - p.y);
    00735 }
    00736
    00737 /** Create vector by adding specified offset.
    00738  */
    00739 inline Diff2D operator+(Diff2D const &a, Diff2D const &b)
    00740 {
    00741     return Diff2D(a.x + b.x, a.y + b.y);
    00742 }
    00743
    00744 /** Create size by adding specified offset.
    00745  */
    00746 inline Size2D operator+(Size2D const &a, Diff2D const &b)
    00747 {
    00748     return Size2D(a.x + b.x, a.y + b.y);
    00749 }
    00750
    00751 /** Create point by adding specified offset.
    00752  */
    00753 inline Point2D operator+(Point2D const &a, Diff2D const &b)
    00754 {
    00755     return Point2D(a.x + b.x, a.y + b.y);
    00756 }
    00757
    00758 /** Add size and point
    00759  */
    00760 inline Point2D operator+(Size2D const & s, Point2D const & p)
    00761 {
    00762     return Point2D(s.x + p.x, s.y + p.y);
    00763 }
    00764
    00765 inline Point2D operator*(Point2D l, double r)
    00766 {
    00767     l *= r;
    00768     return l;
    00769 }
    00770
    00771 inline Point2D operator*(double l, Point2D r)
    00772 {
    00773     r *= l;
    00774     return r;
    00775 }
    00776
    00777 inline Size2D operator*(Size2D l, double r)
    00778 {
    00779     l *= r;
    00780     return l;
    00781 }
    00782
    00783 inline Size2D operator*(double l, Size2D r)
    00784 {
    00785     r *= l;
    00786     return r;
    00787 }
    00788
    00789 inline Point2D operator/(Point2D l, double r)
    00790 {
    00791     l /= r;
    00792     return l;
    00793 }
    00794
    00795 inline Size2D operator/(Size2D l, double r)
    00796 {
    00797     l /= r;
    00798     return l;
    00799 }
    00800
    00801 inline Point2D operator*(Point2D l, int r)
    00802 {
    00803     l *= r;
    00804     return l;
    00805 }
    00806
    00807 inline Point2D operator*(int l, Point2D r)
    00808 {
    00809     r *= l;
    00810     return r;
    00811 }
    00812
    00813 inline Size2D operator*(Size2D l, int r)
    00814 {
    00815     l *= r;
    00816     return l;
    00817 }
    00818
    00819 inline Size2D operator*(int l, Size2D r)
    00820 {
    00821     r *= l;
    00822     return r;
    00823 }
    00824
    00825 inline Point2D operator/(Point2D l, int r)
    00826 {
    00827     l /= r;
    00828     return l;
    00829 }
    00830
    00831 inline Size2D operator/(Size2D l, int r)
    00832 {
    00833     l /= r;
    00834     return l;
    00835 }
    00836
    00837
    00838 /********************************************************/
    00839 /*                                                      */
    00840 /*                      Rect2D                          */
    00841 /*                                                      */
    00842 /********************************************************/
    00843
    00844 /** \brief Two dimensional rectangle.
    00845
    00846     This class stores a 2-dimensional rectangular range or region. Thus,
    00847     it follows the VIGRA convention that the upper left corner is inside
    00848     the rectangle, while the lower right is 1 pixel to the right and below the
    00849     last pixel in the rectangle.
    00850
    00851     A major advantage of this class is that it can be constructed from either
    00852     a pair of \ref Point2D, or from a \ref Point2D and an extend
    00853     (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set
    00854     union (in the sense of a minimal bounding rectangle) and set intersection.
    00855
    00856     \code
    00857     Rect2D r1(Point2D(0,0), Point2D(10, 20)),
    00858            r2(Point2D(10, 15), Size2D(20, 20));
    00859     Point2D p(0,100);
    00860
    00861     Rect2D r3 =  r1 | r2; // upper left is (0,0), lower right is (30, 35)
    00862     assert(r3.contains(r2));
    00863     assert(!r3.contains(p));
    00864
    00865     r3 |= p;       // lower right now (30,101) so that p is inside r3
    00866     assert(r3.contains(p));
    00867     \endcode
    00868
    00869     <b>\#include</b> <vigra/diff2d.hxx><br>
    00870     Namespace: vigra
    00871 */
    00872 class Rect2D
    00873 {
    00874     Point2D upperLeft_, lowerRight_;
    00875
    00876 public:
    00877         /** Construct a null rectangle (isEmpty() will return true)
    00878          */
    00879     Rect2D()
    00880     {}
    00881
    00882         /** Construct a rectangle representing the given range
    00883          * (lowerRight is considered to be outside the rectangle as
    00884          * usual in the VIGRA)
    00885          */
    00886     Rect2D(Point2D const &upperLeft, Point2D const &lowerRight)
    00887     : upperLeft_(upperLeft), lowerRight_(lowerRight)
    00888     {}
    00889
    00890         /** Construct a rectangle representing the given range
    00891          */
    00892     Rect2D(int left, int top, int right, int bottom)
    00893     : upperLeft_(left, top), lowerRight_(right, bottom)
    00894     {}
    00895
    00896         /** Construct a rectangle of given position and size
    00897          */
    00898     Rect2D(Point2D const &upperLeft, Size2D const &size)
    00899     : upperLeft_(upperLeft), lowerRight_(upperLeft + size)
    00900     {}
    00901
    00902         /** Construct a rectangle of given size at position (0,0)
    00903          */
    00904     explicit Rect2D(Size2D const &size)
    00905     : lowerRight_(Point2D(size))
    00906     {}
    00907
    00908         /** Return the first point (scan-order wise) which is
    00909          * considered to be "in" the rectangle.
    00910          */
    00911     Point2D const & upperLeft() const
    00912     {
    00913         return upperLeft_;
    00914     }
    00915
    00916         /** Return the first point to the right and below the
    00917          * rectangle.
    00918          */
    00919     Point2D const & lowerRight() const
    00920     {
    00921         return lowerRight_;
    00922     }
    00923
    00924         /** Change upperLeft() without changing lowerRight(), which
    00925          * will change the size most probably.
    00926          */
    00927     void setUpperLeft(Point2D const &ul)
    00928     {
    00929         upperLeft_ = ul;
    00930     }
    00931
    00932         /** Change lowerRight() without changing upperLeft(), which
    00933          * will change the size most probably.
    00934          */
    00935     void setLowerRight(Point2D const &lr)
    00936     {
    00937         lowerRight_ = lr;
    00938     }
    00939
    00940         /** Move the whole rectangle so that the given point will be
    00941          * upperLeft() afterwards.
    00942          */
    00943     void moveTo(Point2D const &newUpperLeft)
    00944     {
    00945         lowerRight_ += newUpperLeft - upperLeft_;
    00946         upperLeft_ = newUpperLeft;
    00947     }
    00948
    00949         /** Move the whole rectangle so that upperLeft() will become
    00950          * Point2D(left, top) afterwards.
    00951          */
    00952     void moveTo(int left, int top)
    00953     {
    00954         moveTo(Point2D(left, top));
    00955     }
    00956
    00957         /** Move the whole rectangle by the given 2D offset.
    00958          */
    00959     void moveBy(Diff2D const &offset)
    00960     {
    00961         upperLeft_ += offset;
    00962         lowerRight_ += offset;
    00963     }
    00964
    00965         /** Move the whole rectangle by the given x- and y-offsets.
    00966          */
    00967     void moveBy(int xOffset, int yOffset)
    00968     {
    00969         moveBy(Diff2D(xOffset, yOffset));
    00970     }
    00971
    00972         /** Return the left coordinate of this rectangle.
    00973          */
    00974     int left() const
    00975     {
    00976         return upperLeft_.x;
    00977     }
    00978
    00979         /** Return the top coordinate of this rectangle.
    00980          */
    00981     int top() const
    00982     {
    00983         return upperLeft_.y;
    00984     }
    00985
    00986         /** Return the right coordinate of this rectangle. That is the
    00987          * first column to the right of the rectangle.
    00988          */
    00989     int right() const
    00990     {
    00991         return lowerRight_.x;
    00992     }
    00993
    00994         /** Return the bottom coordinate of this rectangle. That is the
    00995          * first row below the rectangle.
    00996          */
    00997     int bottom() const
    00998     {
    00999         return lowerRight_.y;
    01000     }
    01001
    01002         /** Determine and return the width of this rectangle. It might be
    01003          * zero or even negative, and if so, isEmpty() will return true.
    01004          */
    01005     int width() const
    01006     {
    01007         return lowerRight_.x - upperLeft_.x;
    01008     }
    01009
    01010         /** Determine and return the height of this rectangle. It might be
    01011          * zero or even negative, and if so, isEmpty() will return true.
    01012          */
    01013     int height() const
    01014     {
    01015         return lowerRight_.y - upperLeft_.y;
    01016     }
    01017
    01018         /** Determine and return the area of this rectangle. That is, if
    01019          * this rect isEmpty(), returns zero, otherwise returns
    01020          * width()*height().
    01021          */
    01022     int area() const
    01023     {
    01024         return isEmpty() ? 0 : width()*height();
    01025     }
    01026
    01027         /** Determine and return the size of this rectangle. The width
    01028          * and/or height might be zero or even negative, and if so,
    01029          * isEmpty() will return true.
    01030          */
    01031     Size2D size() const
    01032     {
    01033         return lowerRight_ - upperLeft_;
    01034     }
    01035
    01036         /** Resize this rectangle to the given extents. This will move
    01037          * the lower right corner only.
    01038          */
    01039     void setSize(Size2D const &size)
    01040     {
    01041         lowerRight_ = upperLeft_ + size;
    01042     }
    01043
    01044         /** Resize this rectangle to the given extents. This will move
    01045          * the lower right corner only.
    01046          */
    01047     void setSize(int width, int height)
    01048     {
    01049         lowerRight_ = upperLeft_ + Size2D(width, height);
    01050     }
    01051
    01052         /** Increase the size of the rectangle by the given offset. This
    01053          * will move the lower right corner only. (If any of offset's
    01054          * components is negative, the rectangle will get smaller
    01055          * accordingly.)
    01056          */
    01057     void addSize(Size2D const &offset)
    01058     {
    01059         lowerRight_ += offset;
    01060     }
    01061
    01062         /** Adds a border of the given width around the rectangle. That
    01063          * means, upperLeft()'s components are moved by -borderWidth
    01064          * and lowerRight()'s by borderWidth. (If borderWidth is
    01065          * negative, the rectangle will get smaller accordingly.)
    01066          */
    01067     void addBorder(int borderWidth)
    01068     {
    01069         upperLeft_ += Diff2D(-borderWidth, -borderWidth);
    01070         lowerRight_ += Diff2D(borderWidth, borderWidth);
    01071     }
    01072
    01073         /** Adds a border with possibly different widths in x- and
    01074          * y-directions around the rectangle. That means, each x
    01075          * component is moved borderWidth pixels and each y component
    01076          * is moved borderHeight pixels to the outside. (If
    01077          * borderWidth is negative, the rectangle will get smaller
    01078          * accordingly.)
    01079          */
    01080     void addBorder(int borderWidth, int borderHeight)
    01081     {
    01082         upperLeft_ += Diff2D(-borderWidth, -borderHeight);
    01083         lowerRight_ += Diff2D(borderWidth, borderHeight);
    01084     }
    01085
    01086         /// equality check
    01087     bool operator==(Rect2D const &r) const
    01088     {
    01089         return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_);
    01090     }
    01091
    01092         /// inequality check
    01093     bool operator!=(Rect2D const &r) const
    01094     {
    01095         return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_);
    01096     }
    01097
    01098         /** Return whether this rectangle is considered empty. It is
    01099          * non-empty if both coordinates of the lower right corner are
    01100          * greater than the corresponding coordinate of the upper left
    01101          * corner. Uniting an empty rectangle with something will return
    01102          * the bounding rectangle of the 'something', intersecting with an
    01103          * empty rectangle will yield again an empty rectangle.
    01104          */
    01105     bool isEmpty() const
    01106     {
    01107         return ((lowerRight_.x <= upperLeft_.x) ||
    01108                 (lowerRight_.y <= upperLeft_.y));
    01109     }
    01110
    01111         /** Return whether this rectangle contains the given point. That
    01112          * is, if the point lies within the valid range of an
    01113          * ImageIterator walking from upperLeft() to lowerRight()
    01114          * (excluding the latter).
    01115          */
    01116     bool contains(Point2D const &p) const
    01117     {
    01118         return ((upperLeft_.x <= p.x) &&
    01119                 (upperLeft_.y <= p.y) &&
    01120                 (p.x < lowerRight_.x) &&
    01121                 (p.y < lowerRight_.y));
    01122     }
    01123
    01124         /** Return whether this rectangle contains the given
    01125          * one. <tt>r1.contains(r2)</tt> returns the same as
    01126          * <tt>r1 == (r1|r2)</tt> (but is of course more
    01127          * efficient). That also means, a rectangle (even an empty one!)
    01128          * contains() any empty rectangle.
    01129          */
    01130     bool contains(Rect2D const &r) const
    01131     {
    01132         return r.isEmpty() ||
    01133             (contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1)));
    01134     }
    01135
    01136         /** Return whether this rectangle overlaps with the given
    01137          * one. <tt>r1.intersects(r2)</tt> returns the same as
    01138          * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more
    01139          * efficient).
    01140          */
    01141     bool intersects(Rect2D const &r) const
    01142     {
    01143         return ((r.upperLeft_.x < lowerRight_.x) &&
    01144                 (upperLeft_.x < r.lowerRight_.x) &&
    01145                 (r.upperLeft_.y < lowerRight_.y) &&
    01146                 (upperLeft_.y < r.lowerRight_.y))
    01147             && !r.isEmpty();
    01148     }
    01149
    01150         /** Modifies this rectangle by including the given point. The
    01151          * result is the bounding rectangle of the rectangle and the
    01152          * point. If isEmpty returns true, the union will be a
    01153          * rectangle containing only the given point.
    01154          */
    01155     Rect2D &operator|=(Point2D const &p)
    01156     {
    01157         if(isEmpty())
    01158         {
    01159             upperLeft_ = p;
    01160             lowerRight_ = p + Diff2D(1, 1);
    01161         }
    01162         else
    01163         {
    01164             if(p.x < upperLeft_.x)
    01165                 upperLeft_.x = p.x;
    01166             if(p.y < upperLeft_.y)
    01167                 upperLeft_.y = p.y;
    01168             if(lowerRight_.x <= p.x)
    01169                 lowerRight_.x = p.x + 1;
    01170             if(lowerRight_.y <= p.y)
    01171                 lowerRight_.y = p.y + 1;
    01172         }
    01173         return *this;
    01174     }
    01175
    01176         /** Returns the union of this rectangle and the given
    01177          * point. The result is the bounding rectangle of the
    01178          * rectangle and the point. If isEmpty returns true, the union
    01179          * will be a rectangle containing only the given point.
    01180          */
    01181     Rect2D operator|(Point2D const &p) const
    01182     {
    01183         Rect2D result(*this);
    01184         result |= p;
    01185         return result;
    01186     }
    01187
    01188         /** Modifies this rectangle by uniting it with the given
    01189          * one. The result is the bounding rectangle of both
    01190          * rectangles. If one of the rectangles isEmpty(), the union
    01191          * will be the other one.
    01192          */
    01193     Rect2D &operator|=(Rect2D const &r)
    01194     {
    01195         if(r.isEmpty())
    01196             return *this;
    01197         if(isEmpty())
    01198             return operator=(r);
    01199
    01200         if(r.upperLeft_.x < upperLeft_.x)
    01201             upperLeft_.x = r.upperLeft_.x;
    01202         if(r.upperLeft_.y < upperLeft_.y)
    01203             upperLeft_.y = r.upperLeft_.y;
    01204         if(lowerRight_.x < r.lowerRight_.x)
    01205             lowerRight_.x = r.lowerRight_.x;
    01206         if(lowerRight_.y < r.lowerRight_.y)
    01207             lowerRight_.y = r.lowerRight_.y;
    01208         return *this;
    01209     }
    01210
    01211         /** Returns the union of this rectangle and the given one. The
    01212          * result is the bounding rectangle of both rectangles. If one
    01213          * of the rectangles isEmpty(), the union will be the other
    01214          * one.
    01215          */
    01216     Rect2D operator|(Rect2D const &r) const
    01217     {
    01218         Rect2D result(*this);
    01219         result |= r;
    01220         return result;
    01221     }
    01222
    01223         /** Modifies this rectangle by intersecting it with the given
    01224          * point. The result is the bounding rect of the point (with
    01225          * width and height equal to 1) if it was contained in the
    01226          * original rect, or an empty rect otherwise.
    01227          */
    01228     Rect2D &operator&=(Point2D const &p)
    01229     {
    01230         if(contains(p))
    01231         {
    01232             upperLeft_ = p;
    01233             lowerRight_ = p + Diff2D(1, 1);
    01234         }
    01235         else
    01236             lowerRight_ = upperLeft_;
    01237         return *this;
    01238     }
    01239
    01240         /** Intersects this rectangle with the given point. The result
    01241          * is the bounding rect of the point (with width and height
    01242          * equal to 1) if it was contained in the original rect, or an
    01243          * empty rect otherwise.
    01244          */
    01245     Rect2D operator&(Point2D const &p) const
    01246     {
    01247         Rect2D result(*this);
    01248         result &= p;
    01249         return result;
    01250     }
    01251
    01252         /** Modifies this rectangle by intersecting it with the given
    01253          * one. The result is the maximal rectangle contained in both
    01254          * original ones. Intersecting with an empty rectangle will
    01255          * yield again an empty rectangle.
    01256          */
    01257     Rect2D &operator&=(Rect2D const &r)
    01258     {
    01259         if(isEmpty())
    01260             return *this;
    01261         if(r.isEmpty())
    01262             return operator=(r);
    01263
    01264         if(upperLeft_.x < r.upperLeft_.x)
    01265             upperLeft_.x = r.upperLeft_.x;
    01266         if(upperLeft_.y < r.upperLeft_.y)
    01267             upperLeft_.y = r.upperLeft_.y;
    01268         if(r.lowerRight_.x < lowerRight_.x)
    01269             lowerRight_.x = r.lowerRight_.x;
    01270         if(r.lowerRight_.y < lowerRight_.y)
    01271             lowerRight_.y = r.lowerRight_.y;
    01272         return *this;
    01273     }
    01274
    01275        /** Scale this rectangle by the given factor.
    01276         * To be specific, both upperLeft() and lowerRight() are
    01277         * multiplied by `factor`.
    01278         */
    01279     Rect2D & operator*=(int factor)
    01280     {
    01281         upperLeft_ *= factor;
    01282         lowerRight_ *= factor;
    01283         return *this;
    01284     }
    01285
    01286        /** Scale this rectangle by the given factor.
    01287         * To be specific, both upperLeft() and lowerRight() are
    01288         * multiplied by `factor`.
    01289         */
    01290     Rect2D & operator*=(double factor)
    01291     {
    01292         upperLeft_ *= factor;
    01293         lowerRight_ *= factor;
    01294         return *this;
    01295     }
    01296
    01297        /** Return rectangle scaled by the given factor.
    01298         * To be specific, both upperLeft() and lowerRight() are
    01299         * multiplied by `factor`.
    01300         */
    01301     Rect2D operator*(int factor) const
    01302     {
    01303         return Rect2D(*this)*=factor;
    01304     }
    01305
    01306        /** Return rectangle scaled by the given factor.
    01307         * To be specific, both upperLeft() and lowerRight() are
    01308         * multiplied by `factor`.
    01309         */
    01310     Rect2D operator*(double factor) const
    01311     {
    01312         return Rect2D(*this)*=factor;
    01313     }
    01314
    01315         /** Intersects this rectangle with the given one. The result
    01316          * is the maximal rectangle contained in both original ones.
    01317          * Intersecting with an empty rectangle will yield again an
    01318          * empty rectangle.
    01319          */
    01320     Rect2D operator&(Rect2D const &r) const
    01321     {
    01322         Rect2D result(*this);
    01323         result &= r;
    01324         return result;
    01325     }
    01326 };
    01327
    01328
    01329 /********************************************************/
    01330 /*                                                      */
    01331 /*                      Dist2D                          */
    01332 /*                                                      */
    01333 /********************************************************/
    01334
    01335 /** @deprecated use \ref vigra::Diff2D instead
    01336 */
    01337 class Dist2D
    01338 {
    01339   public:
    01340     Dist2D(int the_width, int the_height)
    01341     : width(the_width),
    01342       height(the_height)
    01343     {}
    01344
    01345     Dist2D(Dist2D const & s)
    01346     : width(s.width),
    01347       height(s.height)
    01348     {}
    01349
    01350     Dist2D & operator=(Dist2D const & s)
    01351     {
    01352         if(this != &s)
    01353         {
    01354             width = s.width;
    01355             height = s.height;
    01356         }
    01357         return *this;
    01358     }
    01359
    01360     Dist2D & operator+=(Dist2D const & s)
    01361     {
    01362         width += s.width;
    01363         height += s.height;
    01364
    01365         return *this;
    01366     }
    01367
    01368     Dist2D  operator+(Dist2D const & s) const
    01369     {
    01370         Dist2D ret(*this);
    01371         ret += s;
    01372
    01373         return ret;
    01374     }
    01375
    01376     operator Diff2D()
    01377         { return Diff2D(width, height); }
    01378
    01379     int width;
    01380     int height;
    01381  };
    01382
    01383 //@}
    01384
    01385 } // namespace vigra
    01386
    01387 namespace std {
    01388
    01389 /**
    01390  * Output a \ref vigra::Diff2D as a tuple.
    01391  * Example Diff2D(-12, 13) -> "(-12, 13)"
    01392  */
    01393 inline
    01394 ostream & operator<<(ostream & o, vigra::Diff2D const & d)
    01395 {
    01396     o << '(' << d.x << ", " << d.y << ')';
    01397     return o;
    01398 }
    01399
    01400 /**
    01401  * Output a \ref vigra::Size2D.
    01402  * Example Size2D(100, 200) -> "(100x200)"
    01403  */
    01404 inline
    01405 ostream &operator <<(ostream &s, vigra::Size2D const &d)
    01406 {
    01407     s << '(' << d.x << 'x' << d.y << ')';
    01408     return s;
    01409 }
    01410
    01411 /**
    01412  * Output a description of a \ref vigra::Rect2D.
    01413  * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]"
    01414  */
    01415 inline
    01416 ostream &operator <<(ostream &s, vigra::Rect2D const &r)
    01417 {
    01418     s << "[" << r.upperLeft() << " to " << r.lowerRight()
    01419       << " = " << r.size() << "]";
    01420     return s;
    01421 }
    01422
    01423 } // namespace std
    01424
    01425 #endif // VIGRA_DIFF2D_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.9.0 (Tue Nov 6 2012)