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> ++diff.x </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> ++diff.y </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