VIGRA - 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 /*       Cognitive Systems Group, University of Hamburg, Germany        */
    00005 /*                                                                      */
    00006 /*    This file is part of the VIGRA computer vision library.           */
    00007 /*    ( Version 1.6.0, Aug 13 2008 )                                    */
    00008 /*    The VIGRA Website is                                              */
    00009 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
    00010 /*    Please direct questions, bug reports, and contributions to        */
    00011 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
    00012 /*        vigra@informatik.uni-hamburg.de                               */
    00013 /*                                                                      */
    00014 /*    Permission is hereby granted, free of charge, to any person       */
    00015 /*    obtaining a copy of this software and associated documentation    */
    00016 /*    files (the "Software"), to deal in the Software without           */
    00017 /*    restriction, including without limitation the rights to use,      */
    00018 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
    00019 /*    sell copies of the Software, and to permit persons to whom the    */
    00020 /*    Software is furnished to do so, subject to the following          */
    00021 /*    conditions:                                                       */
    00022 /*                                                                      */
    00023 /*    The above copyright notice and this permission notice shall be    */
    00024 /*    included in all copies or substantial portions of the             */
    00025 /*    Software.                                                         */
    00026 /*                                                                      */
    00027 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
    00028 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
    00029 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
    00030 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
    00031 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
    00032 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
    00033 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
    00034 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
    00035 /*                                                                      */
    00036 /************************************************************************/
    00037
    00038 #ifndef VIGRA_DIFF2D_HXX
    00039 #define VIGRA_DIFF2D_HXX
    00040
    00041 #include <cmath> // for sqrt()
    00042 #include <iosfwd>
    00043 #include "config.hxx"
    00044 #include "iteratortags.hxx"
    00045 #include "iteratortraits.hxx"
    00046 #include "iteratoradapter.hxx"
    00047 #include "tuple.hxx"
    00048
    00049 namespace vigra {
    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 Two-dimensional Ranges and Points
    00136
    00137     Specify a 2D position, extent, or rectangle.
    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> <<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>><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 /*                                                      */
    00465 /*                      Size2D                          */
    00466 /*                                                      */
    00467 /********************************************************/
    00468
    00469 /** \brief Two dimensional size object.
    00470
    00471     Specializes \ref Diff2D for the specification of a 2-dimensional
    00472     extent, in contrast to a point or position (for the latter
    00473     use \ref Point2D).
    00474
    00475     \code
    00476     // create an image that is 10 pixels squared
    00477     Image new_image(Size2D(10,10));
    00478     \endcode
    00479
    00480     <b>\#include</b> <<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>><br>
    00481     Namespace: vigra
    00482 */
    00483 class Size2D : public Diff2D
    00484 {
    00485 public:
    00486         /** Default Constructor. Init point at position (0,0)
    00487         */
    00488     Size2D()
    00489     {}
    00490
    00491         /** Construct point at given position.
    00492         */
    00493     Size2D(int width, int height)
    00494     : Diff2D(width, height)
    00495     {}
    00496
    00497         /** Copy Constructor.
    00498         */
    00499     Size2D(Size2D const & v)
    00500     : Diff2D(v)
    00501     {}
    00502
    00503         /** Explicit conversion Constructor.
    00504         */
    00505     explicit Size2D(Diff2D const & v)
    00506     : Diff2D(v)
    00507     {}
    00508
    00509         /** Query the width.
    00510          */
    00511     int width() const
    00512     {
    00513         return x;
    00514     }
    00515
    00516         /** Query the height.
    00517          */
    00518     int height() const
    00519     {
    00520         return y;
    00521     }
    00522
    00523         /** Change the width.
    00524          */
    00525     void setWidth(int w)
    00526     {
    00527         x = w;
    00528     }
    00529
    00530         /** Change the height.
    00531          */
    00532     void setHeight(int h)
    00533     {
    00534         y = h;
    00535     }
    00536
    00537         /** Returns width()*height(), the area of a rectangle of this size.
    00538          */
    00539     int area() const
    00540     {
    00541         return width()*height();
    00542     }
    00543
    00544         /** Copy Assigment.
    00545         */
    00546     Size2D & operator=(Diff2D const & v)
    00547     {
    00548         return static_cast<Size2D &>(Diff2D::operator=(v));
    00549     }
    00550
    00551         /** Unary negation.
    00552         */
    00553     Size2D operator-() const
    00554     {
    00555         return Size2D(-x, -y);
    00556     }
    00557
    00558         /** Increase size by specified offset.
    00559         */
    00560     Size2D & operator+=(Diff2D const & offset)
    00561     {
    00562         return static_cast<Size2D &>(Diff2D::operator+=(offset));
    00563     }
    00564
    00565         /** Decrease size by specified offset.
    00566         */
    00567     Size2D & operator-=(Diff2D const & offset)
    00568     {
    00569         return static_cast<Size2D &>(Diff2D::operator-=(offset));
    00570     }
    00571 };
    00572
    00573 /********************************************************/
    00574 /*                                                      */
    00575 /*                     Point2D                          */
    00576 /*                                                      */
    00577 /********************************************************/
    00578
    00579 /** \brief Two dimensional point or position.
    00580
    00581     Specializes \ref Diff2D for the specification of a 2-dimensional
    00582     point or position, in contrast to an extent (for the latter
    00583     use \ref Size2D).
    00584
    00585     \code
    00586     // access an image at a point
    00587     value = image[Point2D(10, 20)];
    00588     \endcode
    00589
    00590     <b>\#include</b> <<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>><br>
    00591     Namespace: vigra
    00592 */
    00593 class Point2D : public Diff2D
    00594 {
    00595 public:
    00596         /** The iterator's value type: a coordinate.
    00597         */
    00598     typedef Point2D PixelType;
    00599
    00600         /** The iterator's value type: a coordinate.
    00601         */
    00602     typedef Point2D value_type;
    00603
    00604         /** the iterator's reference type (return type of <TT>*iter</TT>)
    00605         */
    00606     typedef Point2D const & reference;
    00607
    00608         /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
    00609         */
    00610     typedef Point2D         index_reference;
    00611
    00612         /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
    00613         */
    00614     typedef Point2D const * pointer;
    00615
    00616         /** Default Constructor. Init point at position (0,0)
    00617         */
    00618     Point2D()
    00619     {}
    00620
    00621         /** Construct point at given position.
    00622         */
    00623     Point2D(int x, int y)
    00624     : Diff2D(x, y)
    00625     {}
    00626
    00627         /** Copy Constructor.
    00628         */
    00629     Point2D(Point2D const & v)
    00630     : Diff2D(v)
    00631     {}
    00632
    00633         /** Explicit conversion Constructor.
    00634         */
    00635     explicit Point2D(Diff2D const & v)
    00636     : Diff2D(v)
    00637     {}
    00638
    00639         /** Query the points' x coordinate
    00640          */
    00641     int px() const
    00642     {
    00643         return x;
    00644     }
    00645
    00646         /** Query the points' y coordinate
    00647          */
    00648     int py() const
    00649     {
    00650         return y;
    00651     }
    00652
    00653         /** Copy Assigment.
    00654         */
    00655     Point2D & operator=(Diff2D const & v)
    00656     {
    00657         return static_cast<Point2D &>(Diff2D::operator=(v));
    00658     }
    00659
    00660         /** Unary negation.
    00661         */
    00662     Point2D operator-() const
    00663     {
    00664         return Point2D(-x, -y);
    00665     }
    00666
    00667         /** Increase point coordinates by specified offset.
    00668         */
    00669     Point2D & operator+=(Diff2D const & offset)
    00670     {
    00671         return static_cast<Point2D &>(Diff2D::operator+=(offset));
    00672     }
    00673
    00674         /** Decrease point coordinates by specified offset.
    00675         */
    00676     Point2D & operator-=(Diff2D const & offset)
    00677     {
    00678         return static_cast<Point2D &>(Diff2D::operator-=(offset));
    00679     }
    00680
    00681         /** Access current point coordinate.
    00682         */
    00683     reference operator*() const
    00684     {
    00685         return *this;
    00686     }
    00687
    00688         /** Read point coordinate at an offset.
    00689         */
    00690     index_reference operator()(int const & dx, int const & dy) const
    00691     {
    00692         return Point2D(x + dx, y + dy);
    00693     }
    00694
    00695         /** Read point coordinate at an offset.
    00696         */
    00697     index_reference operator[](Diff2D const & offset) const
    00698     {
    00699         return Point2D(x + offset.x, y + offset.y);
    00700     }
    00701
    00702         /** Access current point coordinate.
    00703         */
    00704     pointer operator->() const
    00705     {
    00706         return this;
    00707     }
    00708 };
    00709
    00710 /** Create vector by subtracting specified offset.
    00711  */
    00712 inline Diff2D operator-(Diff2D const &a, Diff2D const &b)
    00713 {
    00714     return Diff2D(a.x - b.x, a.y - b.y);
    00715 }
    00716
    00717 /** Create size by subtracting specified offset.
    00718  */
    00719 inline Size2D operator-(Size2D const & s, Diff2D const &offset)
    00720 {
    00721     return Size2D(s.x - offset.x, s.y - offset.y);
    00722 }
    00723
    00724 /** Calculate size of rect between two points.
    00725  */
    00726 inline Point2D operator-(Point2D const & s, Diff2D const & offset)
    00727 {
    00728     return Point2D(s.x - offset.x, s.y - offset.y);
    00729 }
    00730
    00731 /** The difference of two points is a size
    00732  */
    00733 inline Size2D operator-(Point2D const & s, Point2D const & p)
    00734 {
    00735     return Size2D(s.x - p.x, s.y - p.y);
    00736 }
    00737
    00738 /** Create vector by adding specified offset.
    00739  */
    00740 inline Diff2D operator+(Diff2D const &a, Diff2D const &b)
    00741 {
    00742     return Diff2D(a.x + b.x, a.y + b.y);
    00743 }
    00744
    00745 /** Create size by adding specified offset.
    00746  */
    00747 inline Size2D operator+(Size2D const &a, Diff2D const &b)
    00748 {
    00749     return Size2D(a.x + b.x, a.y + b.y);
    00750 }
    00751
    00752 /** Create point by adding specified offset.
    00753  */
    00754 inline Point2D operator+(Point2D const &a, Diff2D const &b)
    00755 {
    00756     return Point2D(a.x + b.x, a.y + b.y);
    00757 }
    00758
    00759 /** Add size and point
    00760  */
    00761 inline Point2D operator+(Size2D const & s, Point2D const & p)
    00762 {
    00763     return Point2D(s.x + p.x, s.y + p.y);
    00764 }
    00765
    00766 inline Point2D operator*(Point2D l, double r)
    00767 {
    00768     l *= r;
    00769     return l;
    00770 }
    00771
    00772 inline Point2D operator*(double l, Point2D r)
    00773 {
    00774     r *= l;
    00775     return r;
    00776 }
    00777
    00778 inline Size2D operator*(Size2D l, double r)
    00779 {
    00780     l *= r;
    00781     return l;
    00782 }
    00783
    00784 inline Size2D operator*(double l, Size2D r)
    00785 {
    00786     r *= l;
    00787     return r;
    00788 }
    00789
    00790 inline Point2D operator/(Point2D l, double r)
    00791 {
    00792     l /= r;
    00793     return l;
    00794 }
    00795
    00796 inline Size2D operator/(Size2D l, double r)
    00797 {
    00798     l /= r;
    00799     return l;
    00800 }
    00801
    00802 inline Point2D operator*(Point2D l, int r)
    00803 {
    00804     l *= r;
    00805     return l;
    00806 }
    00807
    00808 inline Point2D operator*(int l, Point2D r)
    00809 {
    00810     r *= l;
    00811     return r;
    00812 }
    00813
    00814 inline Size2D operator*(Size2D l, int r)
    00815 {
    00816     l *= r;
    00817     return l;
    00818 }
    00819
    00820 inline Size2D operator*(int l, Size2D r)
    00821 {
    00822     r *= l;
    00823     return r;
    00824 }
    00825
    00826 inline Point2D operator/(Point2D l, int r)
    00827 {
    00828     l /= r;
    00829     return l;
    00830 }
    00831
    00832 inline Size2D operator/(Size2D l, int r)
    00833 {
    00834     l /= r;
    00835     return l;
    00836 }
    00837
    00838
    00839 /********************************************************/
    00840 /*                                                      */
    00841 /*                      Rect2D                          */
    00842 /*                                                      */
    00843 /********************************************************/
    00844
    00845 /** \brief Two dimensional rectangle.
    00846
    00847     This class stores a 2-dimensional rectangular range or region. Thus,
    00848     it follows the VIGRA convention that the upper left corner is inside
    00849     the rectangle, while the lower right is 1 pixel to the right and below the
    00850     last pixel in the rectangle.
    00851
    00852     A major advantage of this class is that it can be constructed from either
    00853     a pair of \ref Point2D, or from a \ref Point2D and an extend
    00854     (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set
    00855     union (in the sense of a minimal bounding rectangle) and set intersection.
    00856
    00857     \code
    00858     Rect2D r1(Point2D(0,0), Point2D(10, 20)),
    00859            r2(Point2D(10, 15), Size2D(20, 20));
    00860     Point2D p(0,100);
    00861
    00862     Rect2D r3 =  r1 | r2; // upper left is (0,0), lower right is (30, 35)
    00863     assert(r3.contains(r2));
    00864     assert(!r3.contains(p));
    00865
    00866     r3 |= p;       // lower right now (30,101) so that p is inside r3
    00867     assert(r3.contains(p));
    00868     \endcode
    00869
    00870     <b>\#include</b> <<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>><br>
    00871     Namespace: vigra
    00872 */
    00873 class Rect2D
    00874 {
    00875     Point2D upperLeft_, lowerRight_;
    00876
    00877 public:
    00878         /** Construct a null rectangle (isEmpty() will return true)
    00879          */
    00880     Rect2D()
    00881     {}
    00882
    00883         /** Construct a rectangle representing the given range
    00884          * (lowerRight is considered to be outside the rectangle as
    00885          * usual in the VIGRA)
    00886          */
    00887     Rect2D(Point2D const &upperLeft, Point2D const &lowerRight)
    00888     : upperLeft_(upperLeft), lowerRight_(lowerRight)
    00889     {}
    00890
    00891         /** Construct a rectangle representing the given range
    00892          */
    00893     Rect2D(int left, int top, int right, int bottom)
    00894     : upperLeft_(left, top), lowerRight_(right, bottom)
    00895     {}
    00896
    00897         /** Construct a rectangle of given position and size
    00898          */
    00899     Rect2D(Point2D const &upperLeft, Size2D const &size)
    00900     : upperLeft_(upperLeft), lowerRight_(upperLeft + size)
    00901     {}
    00902
    00903         /** Construct a rectangle of given size at position (0,0)
    00904          */
    00905     explicit Rect2D(Size2D const &size)
    00906     : lowerRight_(Point2D(size))
    00907     {}
    00908
    00909         /** Return the first point (scan-order wise) which is
    00910          * considered to be "in" the rectangle.
    00911          */
    00912     Point2D const & upperLeft() const
    00913     {
    00914         return upperLeft_;
    00915     }
    00916
    00917         /** Return the first point to the right and below the
    00918          * rectangle.
    00919          */
    00920     Point2D const & lowerRight() const
    00921     {
    00922         return lowerRight_;
    00923     }
    00924
    00925         /** Change upperLeft() without changing lowerRight(), which
    00926          * will change the size most probably.
    00927          */
    00928     void setUpperLeft(Point2D const &ul)
    00929     {
    00930         upperLeft_ = ul;
    00931     }
    00932
    00933         /** Change lowerRight() without changing upperLeft(), which
    00934          * will change the size most probably.
    00935          */
    00936     void setLowerRight(Point2D const &lr)
    00937     {
    00938         lowerRight_ = lr;
    00939     }
    00940
    00941         /** Move the whole rectangle so that the given point will be
    00942          * upperLeft() afterwards.
    00943          */
    00944     void moveTo(Point2D const &newUpperLeft)
    00945     {
    00946         lowerRight_ += newUpperLeft - upperLeft_;
    00947         upperLeft_ = newUpperLeft;
    00948     }
    00949
    00950         /** Move the whole rectangle so that upperLeft() will become
    00951          * Point2D(left, top) afterwards.
    00952          */
    00953     void moveTo(int left, int top)
    00954     {
    00955         moveTo(Point2D(left, top));
    00956     }
    00957
    00958         /** Move the whole rectangle by the given 2D offset.
    00959          */
    00960     void moveBy(Diff2D const &offset)
    00961     {
    00962         upperLeft_ += offset;
    00963         lowerRight_ += offset;
    00964     }
    00965
    00966         /** Move the whole rectangle by the given x- and y-offsets.
    00967          */
    00968     void moveBy(int xOffset, int yOffset)
    00969     {
    00970         moveBy(Diff2D(xOffset, yOffset));
    00971     }
    00972
    00973         /** Return the left coordinate of this rectangle.
    00974          */
    00975     int left() const
    00976     {
    00977         return upperLeft_.x;
    00978     }
    00979
    00980         /** Return the top coordinate of this rectangle.
    00981          */
    00982     int top() const
    00983     {
    00984         return upperLeft_.y;
    00985     }
    00986
    00987         /** Return the right coordinate of this rectangle. That is the
    00988          * first column to the right of the rectangle.
    00989          */
    00990     int right() const
    00991     {
    00992         return lowerRight_.x;
    00993     }
    00994
    00995         /** Return the bottom coordinate of this rectangle. That is the
    00996          * first row below the rectangle.
    00997          */
    00998     int bottom() const
    00999     {
    01000         return lowerRight_.y;
    01001     }
    01002
    01003         /** Determine and return the width of this rectangle. It might be
    01004          * zero or even negative, and if so, isEmpty() will return true.
    01005          */
    01006     int width() const
    01007     {
    01008         return lowerRight_.x - upperLeft_.x;
    01009     }
    01010
    01011         /** Determine and return the height of this rectangle. It might be
    01012          * zero or even negative, and if so, isEmpty() will return true.
    01013          */
    01014     int height() const
    01015     {
    01016         return lowerRight_.y - upperLeft_.y;
    01017     }
    01018
    01019         /** Determine and return the area of this rectangle. That is, if
    01020          * this rect isEmpty(), returns zero, otherwise returns
    01021          * width()*height().
    01022          */
    01023     int area() const
    01024     {
    01025         return isEmpty() ? 0 : width()*height();
    01026     }
    01027
    01028         /** Determine and return the size of this rectangle. The width
    01029          * and/or height might be zero or even negative, and if so,
    01030          * isEmpty() will return true.
    01031          */
    01032     Size2D size() const
    01033     {
    01034         return lowerRight_ - upperLeft_;
    01035     }
    01036
    01037         /** Resize this rectangle to the given extents. This will move
    01038          * the lower right corner only.
    01039          */
    01040     void setSize(Size2D const &size)
    01041     {
    01042         lowerRight_ = upperLeft_ + size;
    01043     }
    01044
    01045         /** Resize this rectangle to the given extents. This will move
    01046          * the lower right corner only.
    01047          */
    01048     void setSize(int width, int height)
    01049     {
    01050         lowerRight_ = upperLeft_ + Size2D(width, height);
    01051     }
    01052
    01053         /** Increase the size of the rectangle by the given offset. This
    01054          * will move the lower right corner only. (If any of offset's
    01055          * components is negative, the rectangle will get smaller
    01056          * accordingly.)
    01057          */
    01058     void addSize(Size2D const &offset)
    01059     {
    01060         lowerRight_ += offset;
    01061     }
    01062
    01063         /** Adds a border of the given width around the rectangle. That
    01064          * means, upperLeft()'s components are moved by -borderWidth
    01065          * and lowerRight()'s by borderWidth. (If borderWidth is
    01066          * negative, the rectangle will get smaller accordingly.)
    01067          */
    01068     void addBorder(int borderWidth)
    01069     {
    01070         upperLeft_ += Diff2D(-borderWidth, -borderWidth);
    01071         lowerRight_ += Diff2D(borderWidth, borderWidth);
    01072     }
    01073
    01074         /** Adds a border with possibly different widths in x- and
    01075          * y-directions around the rectangle. That means, each x
    01076          * component is moved borderWidth pixels and each y component
    01077          * is moved borderHeight pixels to the outside. (If
    01078          * borderWidth is negative, the rectangle will get smaller
    01079          * accordingly.)
    01080          */
    01081     void addBorder(int borderWidth, int borderHeight)
    01082     {
    01083         upperLeft_ += Diff2D(-borderWidth, -borderHeight);
    01084         lowerRight_ += Diff2D(borderWidth, borderHeight);
    01085     }
    01086
    01087         /// equality check
    01088     bool operator==(Rect2D const &r) const
    01089     {
    01090         return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_);
    01091     }
    01092
    01093         /// inequality check
    01094     bool operator!=(Rect2D const &r) const
    01095     {
    01096         return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_);
    01097     }
    01098
    01099         /** Return whether this rectangle is considered empty. It is
    01100          * non-empty if both coordinates of the lower right corner are
    01101          * greater than the corresponding coordinate of the upper left
    01102          * corner. Uniting an empty rectangle with something will return
    01103          * the bounding rectangle of the 'something', intersecting with an
    01104          * empty rectangle will yield again an empty rectangle.
    01105          */
    01106     bool isEmpty() const
    01107     {
    01108         return ((lowerRight_.x <= upperLeft_.x) ||
    01109                 (lowerRight_.y <= upperLeft_.y));
    01110     }
    01111
    01112         /** Return whether this rectangle contains the given point. That
    01113          * is, if the point lies within the valid range of an
    01114          * ImageIterator walking from upperLeft() to lowerRight()
    01115          * (excluding the latter).
    01116          */
    01117     bool contains(Point2D const &p) const
    01118     {
    01119         return ((upperLeft_.x <= p.x) &&
    01120                 (upperLeft_.y <= p.y) &&
    01121                 (p.x < lowerRight_.x) &&
    01122                 (p.y < lowerRight_.y));
    01123     }
    01124
    01125         /** Return whether this rectangle contains the given
    01126          * one. <tt>r1.contains(r2)</tt> returns the same as
    01127          * <tt>r1 == (r1|r2)</tt> (but is of course more
    01128          * efficient). That also means, a rectangle (even an empty one!)
    01129          * contains() any empty rectangle.
    01130          */
    01131     bool contains(Rect2D const &r) const
    01132     {
    01133         return r.isEmpty() ||
    01134             contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1));
    01135     }
    01136
    01137         /** Return whether this rectangle overlaps with the given
    01138          * one. <tt>r1.intersects(r2)</tt> returns the same as
    01139          * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more
    01140          * efficient).
    01141          */
    01142     bool intersects(Rect2D const &r) const
    01143     {
    01144         return ((r.upperLeft_.x < lowerRight_.x) &&
    01145                 (upperLeft_.x < r.lowerRight_.x) &&
    01146                 (r.upperLeft_.y < lowerRight_.y) &&
    01147                 (upperLeft_.y < r.lowerRight_.y))
    01148             && !r.isEmpty();
    01149     }
    01150
    01151         /** Modifies this rectangle by including the given point. The
    01152          * result is the bounding rectangle of the rectangle and the
    01153          * point. If isEmpty returns true, the union will be a
    01154          * rectangle containing only the given point.
    01155          */
    01156     Rect2D &operator|=(Point2D const &p)
    01157     {
    01158         if(isEmpty())
    01159         {
    01160             upperLeft_ = p;
    01161             lowerRight_ = p + Diff2D(1, 1);
    01162         }
    01163         else
    01164         {
    01165             if(p.x < upperLeft_.x)
    01166                 upperLeft_.x = p.x;
    01167             if(p.y < upperLeft_.y)
    01168                 upperLeft_.y = p.y;
    01169             if(lowerRight_.x <= p.x)
    01170                 lowerRight_.x = p.x + 1;
    01171             if(lowerRight_.y <= p.y)
    01172                 lowerRight_.y = p.y + 1;
    01173         }
    01174         return *this;
    01175     }
    01176
    01177         /** Returns the union of this rectangle and the given
    01178          * point. The result is the bounding rectangle of the
    01179          * rectangle and the point. If isEmpty returns true, the union
    01180          * will be a rectangle containing only the given point.
    01181          */
    01182     Rect2D operator|(Point2D const &p) const
    01183     {
    01184         Rect2D result(*this);
    01185         result |= p;
    01186         return result;
    01187     }
    01188
    01189         /** Modifies this rectangle by uniting it with the given
    01190          * one. The result is the bounding rectangle of both
    01191          * rectangles. If one of the rectangles isEmpty(), the union
    01192          * will be the other one.
    01193          */
    01194     Rect2D &operator|=(Rect2D const &r)
    01195     {
    01196         if(r.isEmpty())
    01197             return *this;
    01198         if(isEmpty())
    01199             return operator=(r);
    01200
    01201         if(r.upperLeft_.x < upperLeft_.x)
    01202             upperLeft_.x = r.upperLeft_.x;
    01203         if(r.upperLeft_.y < upperLeft_.y)
    01204             upperLeft_.y = r.upperLeft_.y;
    01205         if(lowerRight_.x < r.lowerRight_.x)
    01206             lowerRight_.x = r.lowerRight_.x;
    01207         if(lowerRight_.y < r.lowerRight_.y)
    01208             lowerRight_.y = r.lowerRight_.y;
    01209         return *this;
    01210     }
    01211
    01212         /** Returns the union of this rectangle and the given one. The
    01213          * result is the bounding rectangle of both rectangles. If one
    01214          * of the rectangles isEmpty(), the union will be the other
    01215          * one.
    01216          */
    01217     Rect2D operator|(Rect2D const &r) const
    01218     {
    01219         Rect2D result(*this);
    01220         result |= r;
    01221         return result;
    01222     }
    01223
    01224         /** Modifies this rectangle by intersecting it with the given
    01225          * point. The result is the bounding rect of the point (with
    01226          * width and height equal to 1) if it was contained in the
    01227          * original rect, or an empty rect otherwise.
    01228          */
    01229     Rect2D &operator&=(Point2D const &p)
    01230     {
    01231         if(contains(p))
    01232         {
    01233             upperLeft_ = p;
    01234             lowerRight_ = p + Diff2D(1, 1);
    01235         }
    01236         else
    01237             lowerRight_ = upperLeft_;
    01238         return *this;
    01239     }
    01240
    01241         /** Intersects this rectangle with the given point. The result
    01242          * is the bounding rect of the point (with width and height
    01243          * equal to 1) if it was contained in the original rect, or an
    01244          * empty rect otherwise.
    01245          */
    01246     Rect2D operator&(Point2D const &p) const
    01247     {
    01248         Rect2D result(*this);
    01249         result &= p;
    01250         return result;
    01251     }
    01252
    01253         /** Modifies this rectangle by intersecting it with the given
    01254          * one. The result is the maximal rectangle contained in both
    01255          * original ones. Intersecting with an empty rectangle will
    01256          * yield again an empty rectangle.
    01257          */
    01258     Rect2D &operator&=(Rect2D const &r)
    01259     {
    01260         if(isEmpty())
    01261             return *this;
    01262         if(r.isEmpty())
    01263             return operator=(r);
    01264
    01265         if(upperLeft_.x < r.upperLeft_.x)
    01266             upperLeft_.x = r.upperLeft_.x;
    01267         if(upperLeft_.y < r.upperLeft_.y)
    01268             upperLeft_.y = r.upperLeft_.y;
    01269         if(r.lowerRight_.x < lowerRight_.x)
    01270             lowerRight_.x = r.lowerRight_.x;
    01271         if(r.lowerRight_.y < lowerRight_.y)
    01272             lowerRight_.y = r.lowerRight_.y;
    01273         return *this;
    01274     }
    01275
    01276         /** Intersects this rectangle with the given one. The result
    01277          * is the maximal rectangle contained in both original ones.
    01278          * Intersecting with an empty rectangle will yield again an
    01279          * empty rectangle.
    01280          */
    01281     Rect2D operator&(Rect2D const &r) const
    01282     {
    01283         Rect2D result(*this);
    01284         result &= r;
    01285         return result;
    01286     }
    01287 };
    01288
    01289 /********************************************************/
    01290 /*                                                      */
    01291 /*                      Dist2D                          */
    01292 /*                                                      */
    01293 /********************************************************/
    01294
    01295 /** @deprecated use \ref vigra::Diff2D instead
    01296 */
    01297 class Dist2D
    01298 {
    01299   public:
    01300     Dist2D(int the_width, int the_height)
    01301     : width(the_width),
    01302       height(the_height)
    01303     {}
    01304
    01305     Dist2D(Dist2D const & s)
    01306     : width(s.width),
    01307       height(s.height)
    01308     {}
    01309
    01310     Dist2D & operator=(Dist2D const & s)
    01311     {
    01312         if(this != &s)
    01313         {
    01314             width = s.width;
    01315             height = s.height;
    01316         }
    01317         return *this;
    01318     }
    01319
    01320     Dist2D & operator+=(Dist2D const & s)
    01321     {
    01322         width += s.width;
    01323         height += s.height;
    01324
    01325         return *this;
    01326     }
    01327
    01328     Dist2D  operator+(Dist2D const & s) const
    01329     {
    01330         Dist2D ret(*this);
    01331         ret += s;
    01332
    01333         return ret;
    01334     }
    01335
    01336     operator Diff2D()
    01337         { return Diff2D(width, height); }
    01338
    01339     int width;
    01340     int height;
    01341  };
    01342
    01343 //@}
    01344
    01345 /**
    01346  * Output a \ref vigra::Diff2D as a tuple.
    01347  * Example Diff2D(-12, 13) -> "(-12, 13)"
    01348  */
    01349 inline
    01350 std::ostream & operator<<(std::ostream & o, vigra::Diff2D const & d)
    01351 {
    01352     o << '(' << d.x << ", " << d.y << ')';
    01353     return o;
    01354 }
    01355
    01356 /**
    01357  * Output a \ref vigra::Size2D.
    01358  * Example Size2D(100, 200) -> "(100x200)"
    01359  */
    01360 inline
    01361 std::ostream &operator <<(std::ostream &s, vigra::Size2D const &d)
    01362 {
    01363     s << '(' << d.x << 'x' << d.y << ')';
    01364     return s;
    01365 }
    01366
    01367 /**
    01368  * Output a description of a \ref vigra::Rect2D.
    01369  * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]"
    01370  */
    01371 inline
    01372 std::ostream &operator <<(std::ostream &s, vigra::Rect2D const &r)
    01373 {
    01374     s << "[" << r.upperLeft() << " to " << r.lowerRight()
    01375       << " = " << r.size() << "]";
    01376     return s;
    01377 }
    01378
    01379 } // namespace vigra
    01380
    01381 #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.6.0 (13 Aug 2008)