LSSTApplications  18.0.0+64,19.0.0+37,19.0.0+4,19.0.0+40,19.0.0+43,19.0.0+48,19.0.0+8,19.0.0-1-g20d9b18+20,19.0.0-1-g49a97f9+2,19.0.0-1-g5549ca4+3,19.0.0-1-g8c57eb9+20,19.0.0-1-ga72da6b+2,19.0.0-1-gbfe0924+29,19.0.0-1-ge272bc4+20,19.0.0-1-gefe1d0d+19,19.0.0-10-ged17d6e+1,19.0.0-12-gcc0ea3c,19.0.0-13-g154200d1e+1,19.0.0-2-g0d9f9cd+40,19.0.0-2-g260436e+23,19.0.0-2-g9675b69+2,19.0.0-2-g9b11441+28,19.0.0-2-gde8e5e3+2,19.0.0-2-gf01c5b1,19.0.0-2-gff6972b+4,19.0.0-22-g282de62,19.0.0-29-g47457369+1,19.0.0-3-g27e4659+8,19.0.0-3-g6513920+30,19.0.0-3-gce3f959+16,19.0.0-5-g9aa49c1+1,19.0.0-7-g2f7a0e4+8,19.0.0-7-g686a884+3,19.0.0-7-g99cd2d5+4,19.0.0-7-ga57c4689+15,19.0.0-8-g079e426+5,w.2020.09
LSSTDataManagementBasePackage
Box.h
Go to the documentation of this file.
1 /*
2  * Developed for the LSST Data Management System.
3  * This product includes software developed by the LSST Project
4  * (https://www.lsst.org).
5  * See the COPYRIGHT file at the top-level directory of this distribution
6  * for details of code ownership.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef LSST_GEOM_BOX_H
23 #define LSST_GEOM_BOX_H
24 
25 #include <vector>
26 
27 #include "boost/format.hpp"
28 #include "ndarray.h"
29 
30 #include "lsst/geom/Point.h"
31 #include "lsst/geom/Extent.h"
32 #include "lsst/geom/Interval.h"
33 
34 namespace lsst {
35 namespace geom {
36 
37 class Box2D;
38 
55 class Box2I final {
56 public:
57  typedef Point2I Point;
58  typedef Extent2I Extent;
59  typedef int Element;
60 
62 
64 
66  Box2I() noexcept : _minimum(0), _dimensions(0) {}
67 
76  Box2I(Point2I const& minimum, Point2I const& maximum, bool invert = true);
77 
90  Box2I(Point2I const& corner, Extent2I const& dimensions, bool invert = true);
91 
98  Box2I(Interval const & x, Interval const & y) :
99  Box2I(Point(x.getMin(), y.getMin()), Point(x.getMax(), y.getMax()), false)
100  {}
101 
119  explicit Box2I(Box2D const& other, EdgeHandlingEnum edgeHandling = EXPAND);
120 
122  Box2I(Box2I const&) noexcept = default;
123  Box2I(Box2I&&) noexcept = default;
124  ~Box2I() noexcept = default;
125 
139  static Box2I makeCenteredBox(Point2D const& center, Extent const& size);
140 
141  void swap(Box2I& other) noexcept {
142  _minimum.swap(other._minimum);
143  _dimensions.swap(other._dimensions);
144  }
145 
147  Box2I& operator=(Box2I const&) noexcept = default;
148  Box2I& operator=(Box2I&&) noexcept = default;
149 
156  Point2I const getMin() const noexcept { return _minimum; }
157  int getMinX() const noexcept { return _minimum.getX(); }
158  int getMinY() const noexcept { return _minimum.getY(); }
159 
160  Point2I const getMax() const noexcept { return _minimum + _dimensions - Extent2I(1); }
161  int getMaxX() const noexcept { return _minimum.getX() + _dimensions.getX() - 1; }
162  int getMaxY() const noexcept { return _minimum.getY() + _dimensions.getY() - 1; }
164 
171  Point2I const getBegin() const noexcept { return _minimum; }
172  int getBeginX() const noexcept { return _minimum.getX(); }
173  int getBeginY() const noexcept { return _minimum.getY(); }
174 
175  Point2I const getEnd() const noexcept { return _minimum + _dimensions; }
176  int getEndX() const noexcept { return _minimum.getX() + _dimensions.getX(); }
177  int getEndY() const noexcept { return _minimum.getY() + _dimensions.getY(); }
179 
186  Extent2I const getDimensions() const noexcept { return _dimensions; }
187  int getWidth() const noexcept { return _dimensions.getX(); }
188  int getHeight() const noexcept { return _dimensions.getY(); }
189  int getArea() const { return getWidth() * getHeight(); }
191 
198  Point2D const getCenter() const noexcept;
199  double getCenterX() const noexcept { return this->getCenter().getX(); }
200  double getCenterY() const noexcept { return this->getCenter().getY(); }
202 
204 
208 
210  ndarray::View<boost::fusion::vector2<ndarray::index::Range, ndarray::index::Range> > getSlices() const;
211 
213  bool isEmpty() const noexcept { return _dimensions.getX() == 0 && _dimensions.getY() == 0; }
214 
216  bool contains(Point2I const& point) const noexcept;
218  bool contains(Element x, Element y) const noexcept { return contains(Point2I(x, y)); }
220 
226  bool contains(Box2I const& other) const noexcept;
227 
229 
234  bool overlaps(Box2I const& other) const noexcept;
235  bool intersects(Box2I const& other) const noexcept { return overlaps(other); }
237 
241  bool isDisjointFrom(Box2I const & other) const noexcept;
242 
249  void grow(int buffer) { grow(Extent2I(buffer)); }
250 
257  void grow(Extent2I const& buffer);
258 
260  void shift(Extent2I const& offset);
261 
263  void flipLR(int xExtent);
264 
266  void flipTB(int yExtent);
267 
269  void include(Point2I const& point);
270 
272  void include(Box2I const& other);
273 
280  void clip(Box2I const& other) noexcept;
281 
294  Box2I dilatedBy(Extent const & buffer) const;
295  Box2I dilatedBy(Element buffer) const {
296  return dilatedBy(Extent(buffer, buffer));
297  }
299 
312  Box2I erodedBy(Extent const & buffer) const { return dilatedBy(-buffer); }
313  Box2I erodedBy(Element buffer) const { return dilatedBy(-buffer); }
315 
322  Box2I shiftedBy(Extent const & offset) const;
323 
329  Box2I reflectedAboutX(Element x) const;
330 
336  Box2I reflectedAboutY(Element y) const;
337 
339 
347  Box2I expandedTo(Point const & other) const;
348  Box2I expandedTo(Box2I const & other) const;
350 
358  Box2I clippedTo(Box2I const & other) const noexcept;
359 
365  bool operator==(Box2I const& other) const noexcept;
366 
372  bool operator!=(Box2I const& other) const noexcept;
373 
375  std::size_t hash_value() const noexcept;
376 
384 
386  return (boost::format("Box2I(%s,%s)") % _minimum.toString() % _dimensions.toString()).str();
387  }
388 
389 private:
390  Point2I _minimum;
391  Extent2I _dimensions;
392 };
393 
413 class Box2D final {
414 public:
415  typedef Point2D Point;
416  typedef Extent2D Extent;
417  typedef double Element;
418 
420 
425  static double const EPSILON;
426 
428  static double const INVALID;
429 
431  Box2D() noexcept;
432 
443  Box2D(Point2D const& minimum, Point2D const& maximum, bool invert = true) noexcept;
444 
455  Box2D(Point2D const& corner, Extent2D const& dimensions, bool invert = true) noexcept;
456 
463  Box2D(Interval const & x, Interval const & y) :
464  Box2D(Point(x.getMin(), y.getMin()), Point(x.getMax(), y.getMax()), false)
465  {}
466 
476  explicit Box2D(Box2I const& other) noexcept;
477 
479  Box2D(Box2D const&) noexcept = default;
480  Box2D(Box2D&&) noexcept = default;
481 
482  ~Box2D() noexcept = default;
483 
495  // It's hard to guarantee postconditions (especially size) with non-finite inputs
496  static Box2D makeCenteredBox(Point2D const& center, Extent const& size) noexcept;
497 
498  void swap(Box2D& other) noexcept {
499  _minimum.swap(other._minimum);
500  _maximum.swap(other._maximum);
501  }
502 
504  Box2D& operator=(Box2D const&) noexcept = default;
505  Box2D& operator=(Box2D&&) noexcept = default;
506 
513  Point2D const getMin() const noexcept { return _minimum; }
514  double getMinX() const noexcept { return _minimum.getX(); }
515  double getMinY() const noexcept { return _minimum.getY(); }
516 
517  Point2D const getMax() const noexcept { return _maximum; }
518  double getMaxX() const noexcept { return _maximum.getX(); }
519  double getMaxY() const noexcept { return _maximum.getY(); }
521 
528  Extent2D const getDimensions() const noexcept { return isEmpty() ? Extent2D(0.0) : _maximum - _minimum; }
529  double getWidth() const noexcept { return isEmpty() ? 0 : _maximum.getX() - _minimum.getX(); }
530  double getHeight() const noexcept { return isEmpty() ? 0 : _maximum.getY() - _minimum.getY(); }
531  double getArea() const noexcept {
532  Extent2D dim(getDimensions());
533  return dim.getX() * dim.getY();
534  }
536 
538  Interval getX() const { return Interval::fromMinMax(getMinX(), getMaxX()); }
542 
549  Point2D const getCenter() const noexcept {
550  return Point2D((_minimum.asEigen() + _maximum.asEigen()) * 0.5);
551  }
552  double getCenterX() const noexcept { return (_minimum.getX() + _maximum.getX()) * 0.5; }
553  double getCenterY() const noexcept { return (_minimum.getY() + _maximum.getY()) * 0.5; }
555 
557  bool isEmpty() const noexcept { return _minimum.getX() != _minimum.getX(); }
558 
560  bool contains(Point2D const& point) const noexcept;
562  bool contains(Element x, Element y) const noexcept { return contains(Point2D(x, y)); }
564 
570  bool contains(Box2D const& other) const;
571 
573 
578  bool overlaps(Box2D const& other) const noexcept;
579  bool intersects(Box2D const& other) const noexcept { return overlaps(other); }
581 
582 
586  bool isDisjointFrom(Box2D const & other) const noexcept;
587 
594  void grow(double buffer) { grow(Extent2D(buffer)); }
595 
602  void grow(Extent2D const& buffer);
603 
605  void shift(Extent2D const& offset);
606 
608  void flipLR(float xExtent);
609 
611  void flipTB(float yExtent);
612 
620  void include(Point2D const& point) noexcept;
621 
623  void include(Box2D const& other) noexcept;
624 
631  void clip(Box2D const& other) noexcept;
632 
634 
649  Box2D dilatedBy(Extent const & buffer) const;
650  Box2D dilatedBy(Element buffer) const {
651  return dilatedBy(Extent(buffer, buffer));
652  }
654 
656 
671  Box2D erodedBy(Extent const & buffer) const { return dilatedBy(-buffer); }
672  Box2D erodedBy(Element buffer) const { return dilatedBy(-buffer); }
674 
685  Box2D shiftedBy(Extent const & offset) const;
686 
695  Box2D reflectedAboutX(Element x) const;
696 
705  Box2D reflectedAboutY(Element y) const;
706 
717  Box2D expandedTo(Point const & other) const;
718 
725  Box2D expandedTo(Box2D const & other) const;
726 
734  Box2D clippedTo(Box2D const & other) const;
735 
741  bool operator==(Box2D const& other) const noexcept;
742 
748  bool operator!=(Box2D const& other) const noexcept;
749 
751  std::size_t hash_value() const noexcept;
752 
760 
762  return (boost::format("Box2D(%s,%s)") % _minimum.toString() % _maximum.toString()).str();
763  }
764 
765 private:
766  void _tweakMax(int n) noexcept {
767  if (_maximum[n] < 0.0) {
768  _maximum[n] *= (1.0 - EPSILON);
769  } else if (_maximum[n] > 0.0) {
770  _maximum[n] *= (1.0 + EPSILON);
771  } else {
772  _maximum[n] = EPSILON;
773  }
774  }
775  Point2D _minimum;
776  Point2D _maximum;
777 };
778 
779 typedef Box2D BoxD;
780 typedef Box2I BoxI;
781 
783 
785 
786 } // namespace geom
787 } // namespace lsst
788 
789 namespace std {
790 template <>
794  size_t operator()(argument_type const& x) const noexcept { return x.hash_value(); }
795 };
796 
797 template <>
801  size_t operator()(argument_type const& x) const noexcept { return x.hash_value(); }
802 };
803 } // namespace std
804 
805 #endif
bool operator==(Box2I const &other) const noexcept
Compare two boxes for equality.
Definition: Box.cc:248
double getMinY() const noexcept
Definition: Box.h:515
Extent2I const getDimensions() const noexcept
Definition: Box.h:186
bool isDisjointFrom(Box2I const &other) const noexcept
Return true if there are no points in both this and other.
Definition: Box.cc:126
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:174
Point2D Point
Definition: Box.h:415
double getHeight() const noexcept
1-d interval accessors
Definition: Box.h:530
Point2I const getMax() const noexcept
Definition: Box.h:160
Box2I reflectedAboutY(Element y) const
Reflect the box about a horizontal line (returning a new object).
Definition: Box.cc:228
constexpr double EPSILON
Definition: constants.h:54
std::string toString() const
Definition: Box.h:761
Box2I expandedTo(Point const &other) const
Expand the box to ensure that contains(other) is true (returning a new object).
Definition: Box.cc:233
void flipLR(int xExtent)
Flip a bounding box about the y-axis given a parent box of extent (xExtent).
Definition: Box.cc:138
double getWidth() const noexcept
1-d interval accessors
Definition: Box.h:529
int getHeight() const noexcept
Definition: Box.h:188
A floating-point coordinate rectangle geometry.
Definition: Box.h:413
Point2D const getCenter() const noexcept
Definition: Box.h:549
Box2D erodedBy(Extent const &buffer) const
Decrease the size of the box by the given amount(s) on all sides (returning a new object)...
Definition: Box.h:671
Box2D erodedBy(Element buffer) const
Decrease the size of the box by the given amount(s) on all sides (returning a new object)...
Definition: Box.h:672
double getMinX() const noexcept
Definition: Box.h:514
A coordinate class intended to represent absolute positions.
bool isEmpty() const noexcept
Return true if the box contains no points.
Definition: Box.h:213
Box2I reflectedAboutX(Element x) const
Reflect the box about a vertical line (returning a new object).
Definition: Box.cc:223
int y
Definition: SpanSet.cc:49
double getMaxX() const noexcept
Definition: Box.h:518
STL namespace.
Box2D BoxD
Definition: Box.h:779
Extent2D const getDimensions() const noexcept
1-d interval accessors
Definition: Box.h:528
std::string toString() const
Definition: Point.h:143
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.
Definition: Relationship.h:55
ItemVariant const * other
Definition: Schema.cc:56
Point2D const getMin() const noexcept
Definition: Box.h:513
std::vector< Point2I > getCorners() const
Get the corner points.
Definition: Box.cc:261
int getEndY() const noexcept
Definition: Box.h:177
bool contains(Element x, Element y) const noexcept
Return true if the box contains the point.
Definition: Box.h:218
std::string toString() const
Definition: Extent.h:179
Box2I shiftedBy(Extent const &offset) const
Shift the position of the box by the given offset (returning a new object).
Definition: Box.cc:218
Interval getY() const
1-d interval accessors
Definition: Box.h:206
Point< double, 2 > Point2D
Definition: Point.h:324
static double const EPSILON
Value the maximum coordinate is multiplied by to increase it by the smallest possible amount...
Definition: Box.h:425
A floating-point coordinate rectangle geometry.
Definition: Interval.h:413
int getBeginY() const noexcept
Definition: Box.h:173
STL class.
Point2I const getMin() const noexcept
Definition: Box.h:156
bool isEmpty() const noexcept
Return true if the box contains no points.
Definition: Box.h:557
static IntervalI fromMinMax(Element min, Element max)
Construct an interval from its lower and upper bounds.
Definition: Interval.cc:53
afw::table::PointKey< int > dimensions
Definition: GaussianPsf.cc:49
double getMaxY() const noexcept
Definition: Box.h:519
Box2I dilatedBy(Element buffer) const
Increase the size of the box by the given amount(s) on all sides (returning a new object)...
Definition: Box.h:295
double getCenterX() const noexcept
Definition: Box.h:199
double getCenterX() const noexcept
Definition: Box.h:552
A base class for image defects.
void grow(int buffer)
Increase the size of the box by the given buffer amount in all directions.
Definition: Box.h:249
int getMaxY() const noexcept
Definition: Box.h:162
static double const INVALID
Value used to specify undefined coordinate values.
Definition: Box.h:428
int getArea() const
Definition: Box.h:189
size_t operator()(argument_type const &x) const noexcept
Definition: Box.h:794
Point2I Point
Definition: Box.h:57
void grow(double buffer)
Increase the size of the box by the given buffer amount in all directions.
Definition: Box.h:594
int getBeginX() const noexcept
Definition: Box.h:172
bool contains(Element x, Element y) const noexcept
Return true if the box contains the point.
Definition: Box.h:562
int getWidth() const noexcept
Definition: Box.h:187
Box2I clippedTo(Box2I const &other) const noexcept
Shrink an interval to ensure that it is contained by other (returning a new object).
Definition: Box.cc:243
std::ostream & operator<<(std::ostream &os, lsst::geom::AffineTransform const &transform)
int Element
Definition: Box.h:59
A coordinate class intended to represent offsets and dimensions.
Point< int, 2 > Point2I
Definition: Point.h:321
int getMaxX() const noexcept
Definition: Box.h:161
Point2I const getEnd() const noexcept
Definition: Box.h:175
static IntervalI fromMinSize(Element min, Element size)
Construct an interval from its lower bound and size.
Definition: Interval.cc:57
double x
void swap(Point &other) noexcept
Definition: Point.h:202
Extent2I Extent
Definition: Box.h:58
double getArea() const noexcept
1-d interval accessors
Definition: Box.h:531
std::size_t hash_value() const noexcept
Return a hash of this object.
Definition: Box.cc:256
Point2D const getMax() const noexcept
Definition: Box.h:517
double getCenterY() const noexcept
Definition: Box.h:200
void swap(Extent &other) noexcept
Definition: Extent.h:245
bool operator!=(Box2I const &other) const noexcept
Compare two boxes for equality.
Definition: Box.cc:252
double getCenterY() const noexcept
Definition: Box.h:553
int getMinX() const noexcept
Definition: Box.h:157
void swap(Box2D &other) noexcept
Definition: Box.h:498
Extent< int, 2 > Extent2I
Definition: Extent.h:397
STL class.
Extent2D Extent
Definition: Box.h:416
int getEndX() const noexcept
Definition: Box.h:176
std::string toString() const
Definition: Box.h:385
bool intersects(Box2D const &other) const noexcept
Return true if any points in other are also in this.
Definition: Box.h:579
void include(Point2I const &point)
Expand this to ensure that this->contains(point).
Definition: Box.cc:152
A 1-d integer coordinate range.
Definition: Interval.h:50
double Element
Definition: Box.h:417
void shift(Extent2I const &offset)
Shift the position of the box by the given offset.
Definition: Box.cc:134
bool overlaps(Box2I const &other) const noexcept
Return true if any points in other are also in this.
Definition: Box.cc:122
bool contains(Point2I const &point) const noexcept
Return true if the box contains the point.
Definition: Box.cc:114
~Box2I() noexcept=default
void clip(Box2I const &other) noexcept
Shrink this to ensure that other.contains(*this).
Definition: Box.cc:189
Point2D const getCenter() const noexcept
Definition: Box.cc:93
ndarray::View< boost::fusion::vector2< ndarray::index::Range, ndarray::index::Range > > getSlices() const
Return slices to extract the box&#39;s region from an ndarray::Array.
Definition: Box.cc:109
Interval getX() const
1-d interval accessors
Definition: Box.h:539
static Box2I makeCenteredBox(Point2D const &center, Extent const &size)
Create a box centered as closely as possible on a particular point.
Definition: Box.cc:97
Box2I() noexcept
Construct an empty box.
Definition: Box.h:66
size_t operator()(argument_type const &x) const noexcept
Definition: Box.h:801
Interval getX() const
1-d interval accessors
Definition: Box.h:205
Extent< double, 2 > Extent2D
Definition: Extent.h:400
Point2I const getBegin() const noexcept
Definition: Box.h:171
std::ostream * os
Definition: Schema.cc:746
Box2I dilatedBy(Extent const &buffer) const
Increase the size of the box by the given amount(s) on all sides (returning a new object)...
Definition: Box.cc:213
An integer coordinate rectangle.
Definition: Box.h:55
STL class.
bool intersects(Box2I const &other) const noexcept
Return true if any points in other are also in this.
Definition: Box.h:235
Box2I erodedBy(Element buffer) const
Decrease the size of the box by the given amount(s) on all sides (returning a new object)...
Definition: Box.h:313
Box2I(Interval const &x, Interval const &y)
Construct a box from a pair of intervals.
Definition: Box.h:98
Box2D dilatedBy(Element buffer) const
Increase the size of the box by the given amount(s) on all sides (returning a new object)...
Definition: Box.h:650
Interval getY() const
1-d interval accessors
Definition: Box.h:540
int getMinY() const noexcept
Definition: Box.h:158
Box2I & operator=(Box2I const &) noexcept=default
Standard assignment operator.
void flipTB(int yExtent)
Flip a bounding box about the x-axis given a parent box of extent (yExtent).
Definition: Box.cc:145
void swap(Box2I &other) noexcept
Definition: Box.h:141
Box2I BoxI
Definition: Box.h:780
Box2I erodedBy(Extent const &buffer) const
Decrease the size of the box by the given amount(s) on all sides (returning a new object)...
Definition: Box.h:312