1 /************************************************************************/
2 /*                                                                      */
3 /*                  Copyright 1998-2003 by Hans Meine                   */
4 /*       Cognitive Systems Group, University of Hamburg, Germany        */
5 /*                                                                      */
6 /*    This file is part of the VIGRA computer vision library.           */
7 /*    ( Version 1.5.0, Dec 07 2006 )                                    */
8 /*    The VIGRA Website is                                              */
9 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
10 /*    Please direct questions, bug reports, and contributions to        */
11 /*        koethe@informatik.uni-hamburg.de          or                  */
12 /*        vigra@kogs1.informatik.uni-hamburg.de                         */
13 /*                                                                      */
14 /*    Permission is hereby granted, free of charge, to any person       */
15 /*    obtaining a copy of this software and associated documentation    */
16 /*    files (the "Software"), to deal in the Software without           */
17 /*    restriction, including without limitation the rights to use,      */
18 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
19 /*    sell copies of the Software, and to permit persons to whom the    */
20 /*    Software is furnished to do so, subject to the following          */
21 /*    conditions:                                                       */
22 /*                                                                      */
23 /*    The above copyright notice and this permission notice shall be    */
24 /*    included in all copies or substantial portions of the             */
25 /*    Software.                                                         */
26 /*                                                                      */
27 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
28 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
29 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
30 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
31 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
32 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
33 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
34 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
35 /*                                                                      */
36 /************************************************************************/
37 
38 #ifndef VIGRA_DIFF2D_HXX
39 #define VIGRA_DIFF2D_HXX
40 
41 #include <cmath> // for sqrt()
42 #include <iosfwd>
43 #include "config.hxx"
44 #include "iteratortags.hxx"
45 #include "iteratortraits.hxx"
46 #include "iteratoradapter.hxx"
47 #include "tuple.hxx"
48 
49 namespace vigra {
50 
51 template <class Diff>
52 class Diff2DConstRowIteratorPolicy
53 {
54   public:
55     typedef Diff                            BaseType;
56     typedef Diff                            value_type;
operator ()vigra::CornerResponseFunctor57     typedef typename Diff::MoveX            difference_type;
58     typedef Diff const &                    reference;
59     typedef Diff                            index_reference;
60     typedef Diff const *                    pointer;
61     typedef std::random_access_iterator_tag iterator_category;
62 
63     static void initialize(BaseType &) {}
64 
65     static reference dereference(BaseType const & d)
66         { return d; }
67 
68     static index_reference dereference(BaseType d, difference_type n)
69     {
70         d.x += n;
71         return d;
72     }
73 
74     static bool equal(BaseType const & d1, BaseType const & d2)
75         { return d1.x == d2.x; }
76 
77     static bool less(BaseType const & d1, BaseType const & d2)
operator ()vigra::FoerstnerCornerFunctor78         { return d1.x < d2.x; }
79 
80     static difference_type difference(BaseType const & d1, BaseType const & d2)
81         { return d1.x - d2.x; }
82 
83     static void increment(BaseType & d)
84         { ++d.x; }
85 
86     static void decrement(BaseType & d)
87         { --d.x; }
88 
89     static void advance(BaseType & d, difference_type n)
90         { d.x += n; }
91 };
92 
93 template <class Diff>
94 class Diff2DConstColumnIteratorPolicy
95 {
96   public:
97     typedef Diff                            BaseType;
98     typedef Diff                            value_type;
operator ()vigra::RohrCornerFunctor99     typedef typename Diff::MoveY            difference_type;
100     typedef Diff const &                    reference;
101     typedef Diff                            index_reference;
102     typedef Diff const *                    pointer;
103     typedef std::random_access_iterator_tag iterator_category;
104 
105     static void initialize(BaseType & /*d*/) {}
106 
107     static reference dereference(BaseType const & d)
108         { return d; }
109 
110     static index_reference dereference(BaseType d, difference_type n)
111     {
112         d.y += n;
113         return d;
114     }
115 
116     static bool equal(BaseType const & d1, BaseType const & d2)
117         { return d1.y == d2.y; }
118 
119     static bool less(BaseType const & d1, BaseType const & d2)
operator ()vigra::BeaudetCornerFunctor120         { return d1.y < d2.y; }
121 
122     static difference_type difference(BaseType const & d1, BaseType const & d2)
123         { return d1.y - d2.y; }
124 
125     static void increment(BaseType & d)
126         { ++d.y; }
127 
128     static void decrement(BaseType & d)
129         { --d.y; }
130 
131     static void advance(BaseType & d, difference_type n)
132         { d.y += n; }
133 };
134 
135 /** \addtogroup RangesAndPoints Two-dimensional Ranges and Points
136 
137     Specify a 2D position, extent, or rectangle.
138 */
139 //@{
140 
141 /********************************************************/
142 /*                                                      */
143 /*                      Diff2D                          */
144 /*                                                      */
145 /********************************************************/
146 
147 /** \brief Two dimensional difference vector.
148 
149     This class acts primarily as a difference vector for specifying
150     pixel coordinates and region sizes. In addition, Diff2D fulfills
151     the requirements of an \ref ImageIterator, so that it can be used to
152     simulate an image whose pixels' values equal their coordinates. This
153     secondary usage is explained on page \ref CoordinateIterator.
154 
155     Standard usage as a difference vector is mainly needed in the context
156     of images. For example, Diff2D may be used as an index for <TT>operator[]</TT>:
157 
158     \code
159     vigra::Diff2D location(...);
160 
161     value = image[location];
162     \endcode
163 
164     This is especially important in connection with accessors, where the
165     offset variant of <TT>operator()</TT> takes only one offset object:
166 
167     \code
168     // accessor(iterator, dx, dy); is not allowed
169     value = accessor(iterator, vigra::Diff2D(dx, dy));
170     \endcode
171 
172 
173     Diff2D is also returned by <TT>image.size()</TT>, so that we can create
174     new images by calculating their size using Diff2D's arithmetic
175     functions:
176 
177     \code
178     // create an image that is 10 pixels smaller in each direction
179     Image new_image(old_image.size() - Diff2D(10,10));
180     \endcode
181 
182     <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br>
183     Namespace: vigra
184 */
185 class Diff2D
186 {
187   public:
188         /** The iterator's value type: a coordinate.
189         */
190     typedef Diff2D PixelType;
191 
192         /** The iterator's value type: a coordinate.
193         */
194     typedef Diff2D value_type;
195 
196         /** the iterator's reference type (return type of <TT>*iter</TT>)
197         */
198     typedef Diff2D const &       reference;
199 
200         /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
201         */
202     typedef Diff2D               index_reference;
203 
204         /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
205         */
206     typedef Diff2D const *       pointer;
207 
208         /** the iterator's difference type (argument type of <TT>iter[diff]</TT>)
209         */
210     typedef Diff2D               difference_type;
211 
212         /** the iterator tag (image traverser)
213         */
214     typedef image_traverser_tag  iterator_category;
215 
216         /** The associated row iterator.
217         */
218     typedef IteratorAdaptor<Diff2DConstRowIteratorPolicy<Diff2D> >    row_iterator;
219 
220         /** The associated column iterator.
221         */
222    typedef IteratorAdaptor<Diff2DConstColumnIteratorPolicy<Diff2D> > column_iterator;
223 
224         /** type of the iterator's x-navigator
225         */
226     typedef int MoveX;
227         /** type of the iterator's y-navigator
228         */
229     typedef int MoveY;
230 
231 
232         /** Default Constructor. Init iterator at position (0,0)
233         */
234     Diff2D()
235     : x(0), y(0)
236     {}
237 
238         /** Construct at given position.
239         */
240     Diff2D(int ax, int ay)
241     : x(ax), y(ay)
242     {}
243 
244         /** Copy Constructor.
245         */
246     Diff2D(Diff2D const & v)
247     : x(v.x), y(v.y)
248     {}
249 
250         /** Copy Assigment.
251         */
252     Diff2D & operator=(Diff2D const & v)
253     {
cornerResponseFunction(SrcIterator sul,SrcIterator slr,SrcAccessor as,DestIterator dul,DestAccessor ad,double scale)254         if(this != &v)
255         {
256             x = v.x;
257             y = v.y;
258         }
259         return *this;
260     }
261 
262         /** Unary negation.
263         */
264     Diff2D operator-() const
265     {
266         return Diff2D(-x, -y);
267     }
268 
269         /** Increase coordinate by specified offset.
270         */
271     Diff2D & operator+=(Diff2D const & offset)
272     {
273         x += offset.x;
274         y += offset.y;
275         return *this;
276     }
277 
278         /** Decrease coordinate by specified vector.
279         */
280     Diff2D & operator-=(Diff2D const & offset)
281     {
282         x -= offset.x;
283         y -= offset.y;
284         return *this;
285     }
286 
cornerResponseFunction(triple<SrcIterator,SrcIterator,SrcAccessor> src,pair<DestIterator,DestAccessor> dest,double scale)287        /** Create vector by scaling by factor.
288         */
289     Diff2D & operator*=(int factor)
290     {
291         x *= factor;
292         y *= factor;
293         return *this;
294     }
295 
296        /** Create vector by scaling by factor.
297         */
298     Diff2D & operator*=(double factor)
299     {
300         x = (int)(x * factor);
301         y = (int)(y * factor);
302         return *this;
303     }
304 
305        /** Create vector by scaling by 1/factor.
306         */
307     Diff2D & operator/=(int factor)
308     {
309         x /= factor;
310         y /= factor;
311         return *this;
312     }
313 
314        /** Create vector by scaling by 1/factor.
315         */
316     Diff2D & operator/=(double factor)
317     {
318         x = (int)(x / factor);
319         y = (int)(y / factor);
320         return *this;
321     }
322 
323        /** Create vector by scaling by factor.
324         */
325     Diff2D operator*(int factor) const
326     {
327         return Diff2D(x * factor, y * factor);
328     }
329 
330        /** Create vector by scaling by factor.
331         */
332     Diff2D operator*(double factor) const
333     {
334         return Diff2D((int)(x * factor), (int)(y * factor));
335     }
336 
337        /** Create vector by scaling by 1/factor.
338         */
339     Diff2D operator/(int factor) const
340     {
341         return Diff2D(x / factor, y / factor);
342     }
343 
344        /** Create vector by scaling by 1/factor.
345         */
346     Diff2D operator/(double factor) const
347     {
348         return Diff2D((int)(x / factor), (int)(y / factor));
349     }
350 
351         /** Calculate length of difference vector.
352         */
353     int squaredMagnitude() const
354     {
355         return x*x + y*y;
356     }
357 
358         /** Calculate length of difference vector.
359         */
360     double magnitude() const
361     {
362         return VIGRA_CSTD::sqrt((double)squaredMagnitude());
363     }
364 
365         /** Equality.
366         */
367     bool operator==(Diff2D const & r) const
368     {
369         return (x == r.x) && (y == r.y);
370     }
371 
372         /** Inequality.
373         */
374     bool operator!=(Diff2D const & r) const
375     {
376         return (x != r.x) || (y != r.y);
377     }
378 
379         /** Used for both access to the current x-coordinate \em and
380             to specify that an iterator navigation command is to be
381             applied in x-direction. <br>
382             usage:  <TT> x = diff2d.x </TT> (use \p Diff2D::x  as component of difference vector) <br>
383             or <TT>&nbsp; ++diff.x &nbsp; </TT> (use Diff2D as iterator, move right)
384          */
385     int x;
386         /** Used for both access to the current y-coordinate \em and
387             to specify that an iterator navigation command is to be
388             applied in y-direction. <br>
389             usage:  <TT> y = diff2d.y </TT> (use \p Diff2D::y as component of difference vector) <br>
390             or <TT>&nbsp; ++diff.y &nbsp; </TT> (use Diff2D as iterator, move right)
391         */
392     int y;
393 
394         /** Access current coordinate.
395         */
396     reference operator*() const
397     {
398         return *this;
399     }
400 
401         /** Read coordinate at an offset.
402         */
403     index_reference operator()(int const & dx, int const & dy) const
foerstnerCornerDetector(SrcIterator sul,SrcIterator slr,SrcAccessor as,DestIterator dul,DestAccessor ad,double scale)404     {
405         return Diff2D(x + dx, y + dy);
406     }
407 
408         /** Read coordinate at an offset.
409         */
410     index_reference operator[](Diff2D const & offset) const
411     {
412         return Diff2D(x + offset.x, y + offset.y);
413     }
414 
415         /** Read vector components.
416         */
417     int operator[](int index) const
418     {
419         return (&x)[index];
420     }
421 
422         /** Access current coordinate.
423         */
424     pointer operator->() const
425     {
426         return this;
427     }
428 
429         /** Get a row iterator at the current position.
430         */
431     row_iterator rowIterator() const
432         { return row_iterator(*this); }
433 
434         /** Get a column iterator at the current position.
435         */
436     column_iterator columnIterator() const
foerstnerCornerDetector(triple<SrcIterator,SrcIterator,SrcAccessor> src,pair<DestIterator,DestAccessor> dest,double scale)437         { return column_iterator(*this); }
438 };
439 
440 
441 template <>
442 struct IteratorTraits<Diff2D >
443 {
444     typedef Diff2D                               Iterator;
445     typedef Iterator                             iterator;
446     typedef Iterator                             const_iterator;
447     // typedef                                   multable_iterator; undefined
448     typedef iterator::iterator_category          iterator_category;
449     typedef iterator::value_type                 value_type;
450     typedef iterator::reference                  reference;
451     typedef iterator::index_reference            index_reference;
452     typedef iterator::pointer                    pointer;
453     typedef iterator::difference_type            difference_type;
454     typedef iterator::row_iterator               row_iterator;
455     typedef iterator::column_iterator            column_iterator;
456     typedef StandardConstValueAccessor<Diff2D>   DefaultAccessor;
457     typedef StandardConstValueAccessor<Diff2D>   default_accessor;
458     typedef VigraTrueType                        hasConstantStrides;
459 
460 };
461 
462 
463 /********************************************************/
464 /*                                                      */
465 /*                      Size2D                          */
466 /*                                                      */
467 /********************************************************/
468 
469 /** \brief Two dimensional size object.
470 
471     Specializes \ref Diff2D for the specification of a 2-dimensional
472     extent, in contrast to a point or position (for the latter
473     use \ref Point2D).
474 
475     \code
476     // create an image that is 10 pixels squared
477     Image new_image(Size2D(10,10));
478     \endcode
479 
480     <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br>
481     Namespace: vigra
482 */
483 class Size2D : public Diff2D
484 {
485 public:
486         /** Default Constructor. Init point at position (0,0)
487         */
488     Size2D()
489     {}
490 
491         /** Construct point at given position.
492         */
493     Size2D(int width, int height)
494     : Diff2D(width, height)
495     {}
496 
497         /** Copy Constructor.
498         */
499     Size2D(Size2D const & v)
500     : Diff2D(v)
501     {}
502 
503         /** Explicit conversion Constructor.
504         */
505     explicit Size2D(Diff2D const & v)
506     : Diff2D(v)
507     {}
508 
509         /** Query the width.
510          */
511     int width() const
512     {
513         return x;
514     }
515 
516         /** Query the height.
517          */
518     int height() const
519     {
520         return y;
521     }
522 
523         /** Change the width.
524          */
525     void setWidth(int w)
526     {
527         x = w;
528     }
529 
530         /** Change the height.
531          */
532     void setHeight(int h)
533     {
534         y = h;
535     }
536 
537         /** Returns width()*height(), the area of a rectangle of this size.
538          */
539     int area() const
540     {
541         return width()*height();
542     }
543 
544         /** Copy Assigment.
545         */
546     Size2D & operator=(Diff2D const & v)
547     {
548         return static_cast<Size2D &>(Diff2D::operator=(v));
549     }
550 
rohrCornerDetector(SrcIterator sul,SrcIterator slr,SrcAccessor as,DestIterator dul,DestAccessor ad,double scale)551         /** Unary negation.
552         */
553     Size2D operator-() const
554     {
555         return Size2D(-x, -y);
556     }
557 
558         /** Increase size by specified offset.
559         */
560     Size2D & operator+=(Diff2D const & offset)
561     {
562         return static_cast<Size2D &>(Diff2D::operator+=(offset));
563     }
564 
565         /** Decrease size by specified offset.
566         */
567     Size2D & operator-=(Diff2D const & offset)
568     {
569         return static_cast<Size2D &>(Diff2D::operator-=(offset));
570     }
571 };
572 
573 /********************************************************/
574 /*                                                      */
575 /*                     Point2D                          */
576 /*                                                      */
577 /********************************************************/
578 
579 /** \brief Two dimensional point or position.
580 
581     Specializes \ref Diff2D for the specification of a 2-dimensional
582     point or position, in contrast to an extent (for the latter
583     use \ref Size2D).
rohrCornerDetector(triple<SrcIterator,SrcIterator,SrcAccessor> src,pair<DestIterator,DestAccessor> dest,double scale)584 
585     \code
586     // access an image at a point
587     value = image[Point2D(10, 20)];
588     \endcode
589 
590     <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br>
591     Namespace: vigra
592 */
593 class Point2D : public Diff2D
594 {
595 public:
596         /** The iterator's value type: a coordinate.
597         */
598     typedef Point2D PixelType;
599 
600         /** The iterator's value type: a coordinate.
601         */
602     typedef Point2D value_type;
603 
604         /** the iterator's reference type (return type of <TT>*iter</TT>)
605         */
606     typedef Point2D const & reference;
607 
608         /** the iterator's index reference type (return type of <TT>iter[diff]</TT>)
609         */
610     typedef Point2D         index_reference;
611 
612         /** the iterator's pointer type (return type of <TT>iter.operator->()</TT>)
613         */
614     typedef Point2D const * pointer;
615 
616         /** Default Constructor. Init point at position (0,0)
617         */
618     Point2D()
619     {}
620 
621         /** Construct point at given position.
622         */
623     Point2D(int x, int y)
624     : Diff2D(x, y)
625     {}
626 
627         /** Copy Constructor.
628         */
629     Point2D(Point2D const & v)
630     : Diff2D(v)
631     {}
632 
633         /** Explicit conversion Constructor.
634         */
635     explicit Point2D(Diff2D const & v)
636     : Diff2D(v)
637     {}
638 
639         /** Query the points' x coordinate
640          */
641     int px() const
642     {
643         return x;
644     }
645 
646         /** Query the points' y coordinate
647          */
648     int py() const
649     {
650         return y;
651     }
652 
653         /** Copy Assigment.
654         */
655     Point2D & operator=(Diff2D const & v)
656     {
657         return static_cast<Point2D &>(Diff2D::operator=(v));
658     }
659 
660         /** Unary negation.
661         */
662     Point2D operator-() const
663     {
664         return Point2D(-x, -y);
665     }
666 
667         /** Increase point coordinates by specified offset.
668         */
669     Point2D & operator+=(Diff2D const & offset)
670     {
671         return static_cast<Point2D &>(Diff2D::operator+=(offset));
672     }
673 
674         /** Decrease point coordinates by specified offset.
675         */
676     Point2D & operator-=(Diff2D const & offset)
677     {
678         return static_cast<Point2D &>(Diff2D::operator-=(offset));
679     }
680 
681         /** Access current point coordinate.
682         */
683     reference operator*() const
684     {
685         return *this;
686     }
687 
688         /** Read point coordinate at an offset.
689         */
690     index_reference operator()(int const & dx, int const & dy) const
691     {
692         return Point2D(x + dx, y + dy);
693     }
694 
695         /** Read point coordinate at an offset.
696         */
697     index_reference operator[](Diff2D const & offset) const
698     {
699         return Point2D(x + offset.x, y + offset.y);
700     }
701 
702         /** Access current point coordinate.
703         */
704     pointer operator->() const
705     {
706         return this;
707     }
708 };
709 
710 /** Create vector by subtracting specified offset.
711  */
712 inline Diff2D operator-(Diff2D const &a, Diff2D const &b)
713 {
714     return Diff2D(a.x - b.x, a.y - b.y);
715 }
716 
717 /** Create size by subtracting specified offset.
718  */
719 inline Size2D operator-(Size2D const & s, Diff2D const &offset)
beaudetCornerDetector(triple<SrcIterator,SrcIterator,SrcAccessor> src,pair<DestIterator,DestAccessor> dest,double scale)720 {
721     return Size2D(s.x - offset.x, s.y - offset.y);
722 }
723 
724 /** Calculate size of rect between two points.
725  */
726 inline Point2D operator-(Point2D const & s, Diff2D const & offset)
727 {
728     return Point2D(s.x - offset.x, s.y - offset.y);
729 }
730 
731 /** The difference of two points is a size
732  */
733 inline Size2D operator-(Point2D const & s, Point2D const & p)
734 {
735     return Size2D(s.x - p.x, s.y - p.y);
736 }
737 
738 /** Create vector by adding specified offset.
739  */
740 inline Diff2D operator+(Diff2D const &a, Diff2D const &b)
741 {
742     return Diff2D(a.x + b.x, a.y + b.y);
743 }
744 
745 /** Create size by adding specified offset.
746  */
747 inline Size2D operator+(Size2D const &a, Diff2D const &b)
748 {
749     return Size2D(a.x + b.x, a.y + b.y);
750 }
751 
752 /** Create point by adding specified offset.
753  */
754 inline Point2D operator+(Point2D const &a, Diff2D const &b)
755 {
756     return Point2D(a.x + b.x, a.y + b.y);
757 }
758 
759 /** Add size and point
760  */
761 inline Point2D operator+(Size2D const & s, Point2D const & p)
762 {
763     return Point2D(s.x + p.x, s.y + p.y);
764 }
765 
766 inline Point2D operator*(Point2D l, double r)
767 {
768     l *= r;
769     return l;
770 }
771 
772 inline Point2D operator*(double l, Point2D r)
773 {
774     r *= l;
775     return r;
776 }
777 
778 inline Size2D operator*(Size2D l, double r)
779 {
780     l *= r;
781     return l;
782 }
783 
784 inline Size2D operator*(double l, Size2D r)
785 {
786     r *= l;
787     return r;
788 }
789 
790 inline Point2D operator/(Point2D l, double r)
791 {
792     l /= r;
793     return l;
794 }
795 
796 inline Size2D operator/(Size2D l, double r)
797 {
798     l /= r;
799     return l;
800 }
801 
802 inline Point2D operator*(Point2D l, int r)
803 {
804     l *= r;
805     return l;
806 }
807 
808 inline Point2D operator*(int l, Point2D r)
809 {
810     r *= l;
811     return r;
812 }
813 
814 inline Size2D operator*(Size2D l, int r)
815 {
816     l *= r;
817     return l;
818 }
819 
820 inline Size2D operator*(int l, Size2D r)
821 {
822     r *= l;
823     return r;
824 }
825 
826 inline Point2D operator/(Point2D l, int r)
827 {
828     l /= r;
829     return l;
830 }
831 
832 inline Size2D operator/(Size2D l, int r)
833 {
834     l /= r;
835     return l;
836 }
837 
838 
839 /********************************************************/
840 /*                                                      */
841 /*                      Rect2D                          */
842 /*                                                      */
843 /********************************************************/
844 
845 /** \brief Two dimensional rectangle.
846 
847     This class stores a 2-dimensional rectangular range or region. Thus,
848     it follows the VIGRA convention that the upper left corner is inside
849     the rectangle, while the lower right is 1 pixel to the right and below the
850     last pixel in the rectangle.
851 
852     A major advantage of this class is that it can be constructed from either
853     a pair of \ref Point2D, or from a \ref Point2D and an extend
854     (\ref Size2D). Rect2D overloads operators |=, &=, |, & to realize set
855     union (in the sense of a minimal bounding rectangle) and set intersection.
856 
857     \code
858     Rect2D r1(Point2D(0,0), Point2D(10, 20)),
859            r2(Point2D(10, 15), Size2D(20, 20));
860     Point2D p(0,100);
861 
862     Rect2D r3 =  r1 | r2; // upper left is (0,0), lower right is (30, 35)
863     assert(r3.contains(r2));
864     assert(!r3.contains(p));
865 
866     r3 |= p;       // lower right now (30,101) so that p is inside r3
867     assert(r3.contains(p));
868     \endcode
869 
870     <b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx</a>"<br>
871     Namespace: vigra
872 */
873 class Rect2D
874 {
875     Point2D upperLeft_, lowerRight_;
876 
877 public:
878         /** Construct a null rectangle (isEmpty() will return true)
879          */
880     Rect2D()
881     {}
882 
883         /** Construct a rectangle representing the given range
884          * (lowerRight is considered to be outside the rectangle as
885          * usual in the VIGRA)
886          */
887     Rect2D(Point2D const &upperLeft, Point2D const &lowerRight)
888     : upperLeft_(upperLeft), lowerRight_(lowerRight)
889     {}
890 
891         /** Construct a rectangle representing the given range
892          */
893     Rect2D(int left, int top, int right, int bottom)
894     : upperLeft_(left, top), lowerRight_(right, bottom)
895     {}
896 
897         /** Construct a rectangle of given position and size
898          */
899     Rect2D(Point2D const &upperLeft, Size2D const &size)
900     : upperLeft_(upperLeft), lowerRight_(upperLeft + size)
901     {}
902 
903         /** Construct a rectangle of given size at position (0,0)
904          */
905     explicit Rect2D(Size2D const &size)
906     : lowerRight_(Point2D(size))
907     {}
908 
909         /** Return the first point (scan-order wise) which is
910          * considered to be "in" the rectangle.
911          */
912     Point2D const & upperLeft() const
913     {
914         return upperLeft_;
915     }
916 
917         /** Return the first point to the right and below the
918          * rectangle.
919          */
920     Point2D const & lowerRight() const
921     {
922         return lowerRight_;
923     }
924 
925         /** Change upperLeft() without changing lowerRight(), which
926          * will change the size most probably.
927          */
928     void setUpperLeft(Point2D const &ul)
929     {
930         upperLeft_ = ul;
931     }
932 
933         /** Change lowerRight() without changing upperLeft(), which
934          * will change the size most probably.
935          */
936     void setLowerRight(Point2D const &lr)
937     {
938         lowerRight_ = lr;
939     }
940 
941         /** Move the whole rectangle so that the given point will be
942          * upperLeft() afterwards.
943          */
944     void moveTo(Point2D const &newUpperLeft)
945     {
946         lowerRight_ += newUpperLeft - upperLeft_;
947         upperLeft_ = newUpperLeft;
948     }
949 
950         /** Move the whole rectangle so that upperLeft() will become
951          * Point2D(left, top) afterwards.
952          */
953     void moveTo(int left, int top)
954     {
955         moveTo(Point2D(left, top));
956     }
957 
958         /** Move the whole rectangle by the given 2D offset.
959          */
960     void moveBy(Diff2D const &offset)
961     {
962         upperLeft_ += offset;
963         lowerRight_ += offset;
964     }
965 
966         /** Move the whole rectangle by the given x- and y-offsets.
967          */
968     void moveBy(int xOffset, int yOffset)
969     {
970         moveBy(Diff2D(xOffset, yOffset));
971     }
972 
973         /** Return the left coordinate of this rectangle.
974          */
975     int left() const
976     {
977         return upperLeft_.x;
978     }
979 
980         /** Return the top coordinate of this rectangle.
981          */
982     int top() const
983     {
984         return upperLeft_.y;
985     }
986 
987         /** Return the right coordinate of this rectangle. That is the
988          * first column to the right of the rectangle.
989          */
990     int right() const
991     {
992         return lowerRight_.x;
993     }
994 
995         /** Return the bottom coordinate of this rectangle. That is the
996          * first row below the rectangle.
997          */
998     int bottom() const
999     {
1000         return lowerRight_.y;
1001     }
1002 
1003         /** Determine and return the width of this rectangle. It might be
1004          * zero or even negative, and if so, isEmpty() will return true.
1005          */
1006     int width() const
1007     {
1008         return lowerRight_.x - upperLeft_.x;
1009     }
1010 
1011         /** Determine and return the height of this rectangle. It might be
1012          * zero or even negative, and if so, isEmpty() will return true.
1013          */
1014     int height() const
1015     {
1016         return lowerRight_.y - upperLeft_.y;
1017     }
1018 
1019         /** Determine and return the area of this rectangle. That is, if
1020          * this rect isEmpty(), returns zero, otherwise returns
1021          * width()*height().
1022          */
1023     int area() const
1024     {
1025         return isEmpty() ? 0 : width()*height();
1026     }
1027 
1028         /** Determine and return the size of this rectangle. The width
1029          * and/or height might be zero or even negative, and if so,
1030          * isEmpty() will return true.
1031          */
1032     Size2D size() const
1033     {
1034         return lowerRight_ - upperLeft_;
1035     }
1036 
1037         /** Resize this rectangle to the given extents. This will move
1038          * the lower right corner only.
1039          */
1040     void setSize(Size2D const &size)
1041     {
1042         lowerRight_ = upperLeft_ + size;
1043     }
1044 
1045         /** Resize this rectangle to the given extents. This will move
1046          * the lower right corner only.
1047          */
1048     void setSize(int width, int height)
1049     {
1050         lowerRight_ = upperLeft_ + Size2D(width, height);
1051     }
1052 
1053         /** Increase the size of the rectangle by the given offset. This
1054          * will move the lower right corner only. (If any of offset's
1055          * components is negative, the rectangle will get smaller
1056          * accordingly.)
1057          */
1058     void addSize(Size2D const &offset)
1059     {
1060         lowerRight_ += offset;
1061     }
1062 
1063         /** Adds a border of the given width around the rectangle. That
1064          * means, upperLeft()'s components are moved by -borderWidth
1065          * and lowerRight()'s by borderWidth. (If borderWidth is
1066          * negative, the rectangle will get smaller accordingly.)
1067          */
1068     void addBorder(int borderWidth)
1069     {
1070         upperLeft_ += Diff2D(-borderWidth, -borderWidth);
1071         lowerRight_ += Diff2D(borderWidth, borderWidth);
1072     }
1073 
1074         /** Adds a border with possibly different widths in x- and
1075          * y-directions around the rectangle. That means, each x
1076          * component is moved borderWidth pixels and each y component
1077          * is moved borderHeight pixels to the outside. (If
1078          * borderWidth is negative, the rectangle will get smaller
1079          * accordingly.)
1080          */
1081     void addBorder(int borderWidth, int borderHeight)
1082     {
1083         upperLeft_ += Diff2D(-borderWidth, -borderHeight);
1084         lowerRight_ += Diff2D(borderWidth, borderHeight);
1085     }
1086 
1087         /// equality check
1088     bool operator==(Rect2D const &r) const
1089     {
1090         return (upperLeft_ == r.upperLeft_) && (lowerRight_ == r.lowerRight_);
1091     }
1092 
1093         /// inequality check
1094     bool operator!=(Rect2D const &r) const
1095     {
1096         return (upperLeft_ != r.upperLeft_) || (lowerRight_ != r.lowerRight_);
1097     }
1098 
1099         /** Return whether this rectangle is considered empty. It is
1100          * non-empty if both coordinates of the lower right corner are
1101          * greater than the corresponding coordinate of the upper left
1102          * corner. Uniting an empty rectangle with something will return
1103          * the bounding rectangle of the 'something', intersecting with an
1104          * empty rectangle will yield again an empty rectangle.
1105          */
1106     bool isEmpty() const
1107     {
1108         return ((lowerRight_.x <= upperLeft_.x) ||
1109                 (lowerRight_.y <= upperLeft_.y));
1110     }
1111 
1112         /** Return whether this rectangle contains the given point. That
1113          * is, if the point lies within the valid range of an
1114          * ImageIterator walking from upperLeft() to lowerRight()
1115          * (excluding the latter).
1116          */
1117     bool contains(Point2D const &p) const
1118     {
1119         return ((upperLeft_.x <= p.x) &&
1120                 (upperLeft_.y <= p.y) &&
1121                 (p.x < lowerRight_.x) &&
1122                 (p.y < lowerRight_.y));
1123     }
1124 
1125         /** Return whether this rectangle contains the given
1126          * one. <tt>r1.contains(r2)</tt> returns the same as
1127          * <tt>r1 == (r1|r2)</tt> (but is of course more
1128          * efficient). That also means, a rectangle (even an empty one!)
1129          * contains() any empty rectangle.
1130          */
1131     bool contains(Rect2D const &r) const
1132     {
1133         return r.isEmpty() ||
1134             (contains(r.upperLeft()) && contains(r.lowerRight()-Diff2D(1,1)));
1135     }
1136 
1137         /** Return whether this rectangle overlaps with the given
1138          * one. <tt>r1.intersects(r2)</tt> returns the same as
1139          * <tt>!(r1&r2).isEmpty()</tt> (but is of course much more
1140          * efficient).
1141          */
1142     bool intersects(Rect2D const &r) const
1143     {
1144         return ((r.upperLeft_.x < lowerRight_.x) &&
1145                 (upperLeft_.x < r.lowerRight_.x) &&
1146                 (r.upperLeft_.y < lowerRight_.y) &&
1147                 (upperLeft_.y < r.lowerRight_.y))
1148             && !r.isEmpty();
1149     }
1150 
1151         /** Modifies this rectangle by including the given point. The
1152          * result is the bounding rectangle of the rectangle and the
1153          * point. If isEmpty returns true, the union will be a
1154          * rectangle containing only the given point.
1155          */
1156     Rect2D &operator|=(Point2D const &p)
1157     {
1158         if(isEmpty())
1159         {
1160             upperLeft_ = p;
1161             lowerRight_ = p + Diff2D(1, 1);
1162         }
1163         else
1164         {
1165             if(p.x < upperLeft_.x)
1166                 upperLeft_.x = p.x;
1167             if(p.y < upperLeft_.y)
1168                 upperLeft_.y = p.y;
1169             if(lowerRight_.x <= p.x)
1170                 lowerRight_.x = p.x + 1;
1171             if(lowerRight_.y <= p.y)
1172                 lowerRight_.y = p.y + 1;
1173         }
1174         return *this;
1175     }
1176 
1177         /** Returns the union of this rectangle and the given
1178          * point. The result is the bounding rectangle of the
1179          * rectangle and the point. If isEmpty returns true, the union
1180          * will be a rectangle containing only the given point.
1181          */
1182     Rect2D operator|(Point2D const &p) const
1183     {
1184         Rect2D result(*this);
1185         result |= p;
1186         return result;
1187     }
1188 
1189         /** Modifies this rectangle by uniting it with the given
1190          * one. The result is the bounding rectangle of both
1191          * rectangles. If one of the rectangles isEmpty(), the union
1192          * will be the other one.
1193          */
1194     Rect2D &operator|=(Rect2D const &r)
1195     {
1196         if(r.isEmpty())
1197             return *this;
1198         if(isEmpty())
1199             return operator=(r);
1200 
1201         if(r.upperLeft_.x < upperLeft_.x)
1202             upperLeft_.x = r.upperLeft_.x;
1203         if(r.upperLeft_.y < upperLeft_.y)
1204             upperLeft_.y = r.upperLeft_.y;
1205         if(lowerRight_.x < r.lowerRight_.x)
1206             lowerRight_.x = r.lowerRight_.x;
1207         if(lowerRight_.y < r.lowerRight_.y)
1208             lowerRight_.y = r.lowerRight_.y;
1209         return *this;
1210     }
1211 
1212         /** Returns the union of this rectangle and the given one. The
1213          * result is the bounding rectangle of both rectangles. If one
1214          * of the rectangles isEmpty(), the union will be the other
1215          * one.
1216          */
1217     Rect2D operator|(Rect2D const &r) const
1218     {
1219         Rect2D result(*this);
1220         result |= r;
1221         return result;
1222     }
1223 
1224         /** Modifies this rectangle by intersecting it with the given
1225          * point. The result is the bounding rect of the point (with
1226          * width and height equal to 1) if it was contained in the
1227          * original rect, or an empty rect otherwise.
1228          */
1229     Rect2D &operator&=(Point2D const &p)
1230     {
1231         if(contains(p))
1232         {
1233             upperLeft_ = p;
1234             lowerRight_ = p + Diff2D(1, 1);
1235         }
1236         else
1237             lowerRight_ = upperLeft_;
1238         return *this;
1239     }
1240 
1241         /** Intersects this rectangle with the given point. The result
1242          * is the bounding rect of the point (with width and height
1243          * equal to 1) if it was contained in the original rect, or an
1244          * empty rect otherwise.
1245          */
1246     Rect2D operator&(Point2D const &p) const
1247     {
1248         Rect2D result(*this);
1249         result &= p;
1250         return result;
1251     }
1252 
1253         /** Modifies this rectangle by intersecting it with the given
1254          * one. The result is the maximal rectangle contained in both
1255          * original ones. Intersecting with an empty rectangle will
1256          * yield again an empty rectangle.
1257          */
1258     Rect2D &operator&=(Rect2D const &r)
1259     {
1260         if(isEmpty())
1261             return *this;
1262         if(r.isEmpty())
1263             return operator=(r);
1264 
1265         if(upperLeft_.x < r.upperLeft_.x)
1266             upperLeft_.x = r.upperLeft_.x;
1267         if(upperLeft_.y < r.upperLeft_.y)
1268             upperLeft_.y = r.upperLeft_.y;
1269         if(r.lowerRight_.x < lowerRight_.x)
1270             lowerRight_.x = r.lowerRight_.x;
1271         if(r.lowerRight_.y < lowerRight_.y)
1272             lowerRight_.y = r.lowerRight_.y;
1273         return *this;
1274     }
1275 
1276         /** Intersects this rectangle with the given one. The result
1277          * is the maximal rectangle contained in both original ones.
1278          * Intersecting with an empty rectangle will yield again an
1279          * empty rectangle.
1280          */
1281     Rect2D operator&(Rect2D const &r) const
1282     {
1283         Rect2D result(*this);
1284         result &= r;
1285         return result;
1286     }
1287 };
1288 
1289 /********************************************************/
1290 /*                                                      */
1291 /*                      Dist2D                          */
1292 /*                                                      */
1293 /********************************************************/
1294 
1295 /** @deprecated use \ref vigra::Diff2D instead
1296 */
1297 class Dist2D
1298 {
1299   public:
1300     Dist2D(int the_width, int the_height)
1301     : width(the_width),
1302       height(the_height)
1303     {}
1304 
1305     Dist2D(Dist2D const & s)
1306     : width(s.width),
1307       height(s.height)
1308     {}
1309 
1310     Dist2D & operator=(Dist2D const & s)
1311     {
1312         if(this != &s)
1313         {
1314             width = s.width;
1315             height = s.height;
1316         }
1317         return *this;
1318     }
1319 
1320     Dist2D & operator+=(Dist2D const & s)
1321     {
1322         width += s.width;
1323         height += s.height;
1324 
1325         return *this;
1326     }
1327 
1328     Dist2D  operator+(Dist2D const & s) const
1329     {
1330         Dist2D ret(*this);
1331         ret += s;
1332 
1333         return ret;
1334     }
1335 
1336     operator Diff2D()
1337         { return Diff2D(width, height); }
1338 
1339     int width;
1340     int height;
1341  };
1342 
1343 //@}
1344 
1345 /**
1346  * Output a \ref vigra::Diff2D as a tuple.
1347  * Example Diff2D(-12, 13) -> "(-12, 13)"
1348  */
1349 inline
1350 std::ostream & operator<<(std::ostream & o, vigra::Diff2D const & d)
1351 {
1352     o << '(' << d.x << ", " << d.y << ')';
1353     return o;
1354 }
1355 
1356 /**
1357  * Output a \ref vigra::Size2D.
1358  * Example Size2D(100, 200) -> "(100x200)"
1359  */
1360 inline
1361 std::ostream &operator <<(std::ostream &s, vigra::Size2D const &d)
1362 {
1363     s << '(' << d.x << 'x' << d.y << ')';
1364     return s;
1365 }
1366 
1367 /**
1368  * Output a description of a \ref vigra::Rect2D.
1369  * Example Rect2D(10, 10, 30, 20) -> "[(10, 10) to (30, 20) = (20x10)]"
1370  */
1371 inline
1372 std::ostream &operator <<(std::ostream &s, vigra::Rect2D const &r)
1373 {
1374     s << "[" << r.upperLeft() << " to " << r.lowerRight()
1375       << " = " << r.size() << "]";
1376     return s;
1377 }
1378 
1379 } // namespace vigra
1380 
1381 #endif // VIGRA_DIFF2D_HXX
1382