LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Box.h
Go to the documentation of this file.
1 /*
2  * LSST Data Management System
3  * Copyright 2014-2015 AURA/LSST.
4  *
5  * This product includes software developed by the
6  * LSST Project (http://www.lsst.org/).
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 LSST License Statement and
19  * the GNU General Public License along with this program. If not,
20  * see <https://www.lsstcorp.org/LegalNotices/>.
21  */
22 
23 #ifndef LSST_SPHGEOM_BOX_H_
24 #define LSST_SPHGEOM_BOX_H_
25 
29 
30 #include <iosfwd>
31 
32 #include "AngleInterval.h"
33 #include "LonLat.h"
35 #include "Region.h"
36 #include "UnitVector3d.h"
37 
38 
39 namespace lsst {
40 namespace sphgeom {
41 
54 class Box : public Region {
55 public:
56  static constexpr uint8_t TYPE_CODE = 'b';
57 
58  // Factory functions
59  static Box fromDegrees(double lon1, double lat1, double lon2, double lat2) {
60  return Box(NormalizedAngleInterval::fromDegrees(lon1, lon2),
61  AngleInterval::fromDegrees(lat1, lat2));
62  }
63 
64  static Box fromRadians(double lon1, double lat1, double lon2, double lat2) {
65  return Box(NormalizedAngleInterval::fromRadians(lon1, lon2),
66  AngleInterval::fromRadians(lat1, lat2));
67  }
68 
69  static Box empty() { return Box(); }
70 
71  static Box full() { return Box(allLongitudes(), allLatitudes()); }
72 
78 
83  }
84 
88  return AngleInterval(Angle(-0.5 * PI), Angle(0.5 * PI));
89  }
90 
92  Box() {}
93 
95  explicit Box(LonLat const & p) :
96  _lon(p.getLon()),
97  _lat(p.getLat())
98  {
99  _enforceInvariants();
100  }
101 
105  Box(LonLat const & p1, LonLat const & p2) :
106  _lon(p1.getLon(), p2.getLon()),
107  _lat(p1.getLat(), p2.getLat())
108  {
109  _enforceInvariants();
110  }
111 
114  Box(LonLat const & p, Angle w, Angle h) :
116  _lat(AngleInterval(p.getLat()).dilatedBy(h))
117  {
118  _enforceInvariants();
119  }
120 
123  Box(NormalizedAngleInterval const & lon, AngleInterval const & lat) :
124  _lon(lon),
125  _lat(lat)
126  {
127  _enforceInvariants();
128  }
129 
131  bool operator==(Box const & b) const {
132  return _lon == b._lon && _lat == b._lat;
133  }
134 
135  bool operator!=(Box const & b) const { return !(*this == b); }
136 
138  bool operator==(LonLat const & p) const {
139  return _lat == p.getLat() && _lon == p.getLon();
140  }
141 
142  bool operator!=(LonLat const & p) const { return !(*this == p); }
143 
145  NormalizedAngleInterval const & getLon() const { return _lon; }
146 
148  AngleInterval const & getLat() const { return _lat; }
149 
151  bool isEmpty() const { return _lat.isEmpty(); }
152 
155  bool isFull() const { return _lon.isFull() && _lat == allLatitudes(); }
156 
159  LonLat getCenter() const {
160  return LonLat(_lon.getCenter(), _lat.getCenter());
161  }
162 
165  NormalizedAngle getWidth() const { return _lon.getSize(); }
166 
169  Angle getHeight() const { return _lat.getSize(); }
170 
174  bool contains(LonLat const & x) const {
175  return _lat.contains(x.getLat()) && _lon.contains(x.getLon());
176  }
177 
178  bool contains(Box const & x) const {
179  return _lat.contains(x._lat) && _lon.contains(x._lon);
180  }
182 
186  bool isDisjointFrom(LonLat const & x) const { return !intersects(x); }
187 
188  bool isDisjointFrom(Box const & x) const { return !intersects(x); }
190 
194  bool intersects(LonLat const & x) const {
195  return _lat.intersects(x.getLat()) && _lon.intersects(x.getLon());
196  }
197 
198  bool intersects(Box const & x) const {
199  return _lat.intersects(x._lat) && _lon.intersects(x._lon);
200  }
202 
206  bool isWithin(LonLat const & x) const {
207  return _lat.isWithin(x.getLat()) && _lon.isWithin(x.getLon());
208  }
209 
210  bool isWithin(Box const & x) const {
211  return _lat.isWithin(x._lat) && _lon.isWithin(x._lon);
212  }
214 
217  Box & clipTo(LonLat const & x) {
218  _lon.clipTo(x.getLon());
219  _lat.clipTo(x.getLat());
220  _enforceInvariants();
221  return *this;
222  }
223 
227  Box & clipTo(Box const & x) {
228  _lon.clipTo(x.getLon());
229  _lat.clipTo(x.getLat());
230  _enforceInvariants();
231  return *this;
232  }
233 
235  Box clippedTo(LonLat const & x) const { return Box(*this).clipTo(x); }
236 
240  Box clippedTo(Box const & x) const { return Box(*this).clipTo(x); }
241 
246  Box & expandTo(LonLat const & x) {
247  _lon.expandTo(x.getLon());
248  _lat.expandTo(x.getLat());
249  return *this;
250  }
251 
252  Box & expandTo(Box const & x) {
253  _lon.expandTo(x.getLon());
254  _lat.expandTo(x.getLat());
255  return *this;
256  }
258 
263  Box expandedTo(LonLat const & x) const { return Box(*this).expandTo(x); }
264  Box expandedTo(Box const & x) const { return Box(*this).expandTo(x); }
266 
272  Box & dilateBy(Angle r);
273  Box dilatedBy(Angle r) const { return Box(*this).dilateBy(r); }
274 
290  Box & dilateBy(Angle w, Angle h);
291  Box dilatedBy(Angle w, Angle h) const { return Box(*this).dilateBy(w, h); }
292  Box & erodeBy(Angle r) { return dilateBy(-r); }
293  Box & erodeBy(Angle w, Angle h) { return dilateBy(-w, -h); }
294  Box erodedBy(Angle r) const { return dilatedBy(-r); }
295  Box erodedBy(Angle w, Angle h) const { return dilatedBy(-w, -h); }
296 
297  Relationship relate(LonLat const & p) const { return relate(Box(p)); }
298 
300  double getArea() const;
301 
302  // Region interface
303  std::unique_ptr<Region> clone() const override {
304  return std::unique_ptr<Box>(new Box(*this));
305  }
306 
307  Box getBoundingBox() const override { return *this; }
308  Box3d getBoundingBox3d() const override;
309  Circle getBoundingCircle() const override;
310 
311  bool contains(UnitVector3d const & v) const override {
312  return contains(LonLat(v));
313  }
314 
315  using Region::contains;
316 
317  Relationship relate(Region const & r) const override {
318  // Dispatch on the type of r.
319  return invert(r.relate(*this));
320  }
321 
322  Relationship relate(Box const & b) const override {
323  Relationship r1 = _lon.relate(b._lon);
324  Relationship r2 = _lat.relate(b._lat);
325  // If the box longitude or latitude intervals are disjoint, then the
326  // boxes are disjoint. The other spatial relationships must hold for
327  // both the longitude and latitude intervals in order to hold for the
328  // boxes.
329  return ((r1 & r2) & (CONTAINS | WITHIN)) | ((r1 | r2) & DISJOINT);
330  }
331 
332  Relationship relate(Circle const &) const override;
333  Relationship relate(ConvexPolygon const &) const override;
334  Relationship relate(Ellipse const &) const override;
335 
336  std::vector<uint8_t> encode() const override;
337 
341  return decode(s.data(), s.size());
342  }
343  static std::unique_ptr<Box> decode(uint8_t const * buffer, size_t n);
345 
346 private:
347  static constexpr size_t ENCODED_SIZE = 33;
348 
349  void _enforceInvariants() {
350  // Make sure that _lat ⊆ [-π/2, π/2].
351  _lat.clipTo(allLatitudes());
352  // Make sure that both longitude and latitude intervals are
353  // empty, or neither is. This simplifies the implementation
354  // of the spatial relation tests.
355  if (_lat.isEmpty()) {
356  _lon = NormalizedAngleInterval();
357  } else if (_lon.isEmpty()) {
358  _lat = AngleInterval();
359  }
360  }
361 
362  NormalizedAngleInterval _lon;
363  AngleInterval _lat;
364 };
365 
366 std::ostream & operator<<(std::ostream &, Box const &);
367 
368 }} // namespace lsst::sphgeom
369 
370 #endif // LSST_SPHGEOM_BOX_H_
This file defines a class for representing angle intervals.
double x
This file contains a class representing spherical coordinates.
This file declares a class representing closed intervals of normalized angles, i.e.
This file defines an interface for spherical regions.
table::Key< int > b
This file declares a class for representing unit vectors in ℝ³.
Angle represents an angle in radians.
Definition: Angle.h:43
AngleInterval represents closed intervals of arbitrary angles.
Definition: AngleInterval.h:40
static AngleInterval fromDegrees(double x, double y)
Definition: AngleInterval.h:44
static AngleInterval fromRadians(double x, double y)
Definition: AngleInterval.h:49
Box3d represents a box in ℝ³.
Definition: Box3d.h:42
Box represents a rectangle in spherical coordinate space that contains its boundary.
Definition: Box.h:54
Relationship relate(Box const &b) const override
Definition: Box.h:322
Box erodedBy(Angle w, Angle h) const
Definition: Box.h:295
Box & clipTo(Box const &x)
x.clipTo(y) sets x to the smallest box containing the intersection of x and y.
Definition: Box.h:227
Box clippedTo(LonLat const &x) const
clippedTo returns the intersection of this box and x.
Definition: Box.h:235
Box getBoundingBox() const override
getBoundingBox returns a bounding-box for this region.
Definition: Box.h:307
bool operator==(LonLat const &p) const
A box is equal to a point p if it contains only p.
Definition: Box.h:138
Box dilatedBy(Angle r) const
Definition: Box.h:273
static NormalizedAngle halfWidthForCircle(Angle r, Angle lat)
halfWidthForCircle computes the half-width of bounding boxes for circles with radius r and centers at...
Definition: Box.cc:43
Box()
This constructor creates an empty box.
Definition: Box.h:92
bool operator!=(LonLat const &p) const
Definition: Box.h:142
std::vector< uint8_t > encode() const override
encode serializes this region into an opaque byte string.
Definition: Box.cc:447
NormalizedAngle getWidth() const
getWidth returns the width in longitude angle of this box.
Definition: Box.h:165
double getArea() const
getArea returns the area of this box in steradians.
Definition: Box.cc:115
Box3d getBoundingBox3d() const override
getBoundingBox3d returns a 3-dimensional bounding-box for this region.
Definition: Box.cc:127
static Box fromRadians(double lon1, double lat1, double lon2, double lat2)
Definition: Box.h:64
AngleInterval const & getLat() const
getLat returns the latitude interval of this box.
Definition: Box.h:148
bool isWithin(Box const &x) const
Definition: Box.h:210
Box & clipTo(LonLat const &x)
clipTo shrinks this box until it contains only x.
Definition: Box.h:217
Box expandedTo(LonLat const &x) const
Definition: Box.h:263
bool operator==(Box const &b) const
Two boxes are equal if they contain the same points.
Definition: Box.h:131
Box dilatedBy(Angle w, Angle h) const
Definition: Box.h:291
Box(LonLat const &p1, LonLat const &p2)
This constructor creates a box spanning the longitude interval [p1.getLon(), p2.getLon()] and latitud...
Definition: Box.h:105
bool operator!=(Box const &b) const
Definition: Box.h:135
bool contains(UnitVector3d const &v) const override
contains tests whether the given unit vector is inside this region.
Definition: Box.h:311
Relationship relate(LonLat const &p) const
Definition: Box.h:297
bool isDisjointFrom(LonLat const &x) const
Definition: Box.h:186
Box & expandTo(LonLat const &x)
Definition: Box.h:246
static std::unique_ptr< Box > decode(std::vector< uint8_t > const &s)
Definition: Box.h:340
Box(LonLat const &p)
This constructor creates a box containing a single point.
Definition: Box.h:95
Box & erodeBy(Angle w, Angle h)
Definition: Box.h:293
static Box empty()
Definition: Box.h:69
bool isFull() const
isFull returns true if this box contains all points on the unit sphere.
Definition: Box.h:155
Box expandedTo(Box const &x) const
Definition: Box.h:264
static constexpr uint8_t TYPE_CODE
Definition: Box.h:56
virtual bool contains(UnitVector3d const &) const=0
contains tests whether the given unit vector is inside this region.
Box & dilateBy(Angle r)
dilateBy minimally expands this Box to include all points within angular separation r of its boundary...
Definition: Box.cc:78
Angle getHeight() const
getHeight returns the height in latitude angle of this box.
Definition: Box.h:169
LonLat getCenter() const
getCenter returns the center of this box.
Definition: Box.h:159
Box(LonLat const &p, Angle w, Angle h)
This constructor creates a box with center p, half-width (in longitude angle) w and half-height (in l...
Definition: Box.h:114
NormalizedAngleInterval const & getLon() const
getLon returns the longitude interval of this box.
Definition: Box.h:145
static NormalizedAngleInterval allLongitudes()
allLongitudes returns a normalized angle interval containing all valid longitude angles.
Definition: Box.h:81
bool isDisjointFrom(Box const &x) const
Definition: Box.h:188
Box(NormalizedAngleInterval const &lon, AngleInterval const &lat)
This constructor creates a box spanning the given longitude and latitude intervals.
Definition: Box.h:123
Box & expandTo(Box const &x)
Definition: Box.h:252
bool isWithin(LonLat const &x) const
Definition: Box.h:206
Relationship relate(Region const &r) const override
Definition: Box.h:317
Box clippedTo(Box const &x) const
clippedTo returns the smallest box containing the intersection of this box and x.
Definition: Box.h:240
bool intersects(Box const &x) const
Definition: Box.h:198
std::unique_ptr< Region > clone() const override
clone returns a deep copy of this region.
Definition: Box.h:303
Box erodedBy(Angle r) const
Definition: Box.h:294
static AngleInterval allLatitudes()
allLatitudes returns an angle interval containing all valid latitude angles.
Definition: Box.h:87
Box & erodeBy(Angle r)
Definition: Box.h:292
bool contains(LonLat const &x) const
Definition: Box.h:174
static Box fromDegrees(double lon1, double lat1, double lon2, double lat2)
Definition: Box.h:59
bool isEmpty() const
isEmpty returns true if this box does not contain any points.
Definition: Box.h:151
static Box full()
Definition: Box.h:71
bool contains(Box const &x) const
Definition: Box.h:178
bool intersects(LonLat const &x) const
Definition: Box.h:194
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
Definition: Box.cc:187
Circle is a circular region on the unit sphere that contains its boundary.
Definition: Circle.h:46
ConvexPolygon is a closed convex polygon on the unit sphere.
Definition: ConvexPolygon.h:57
Ellipse is an elliptical region on the sphere.
Definition: Ellipse.h:170
bool isWithin(Scalar x) const
Definition: Interval.h:140
Interval & expandTo(Scalar x)
Definition: Interval.h:192
Scalar getSize() const
getSize returns the size (length, width) of this interval.
Definition: Interval.h:93
Interval & clipTo(Scalar x)
Definition: Interval.h:159
bool isEmpty() const
isEmpty returns true if this interval does not contain any points.
Definition: Interval.h:83
Relationship relate(Scalar x) const
Definition: Interval.h:249
bool intersects(Scalar x) const
Definition: Interval.h:130
Scalar getCenter() const
getCenter returns the center of this interval.
Definition: Interval.h:89
bool contains(Scalar x) const
Definition: Interval.h:98
LonLat represents a spherical coordinate (longitude/latitude angle) pair.
Definition: LonLat.h:48
Angle getLat() const
Definition: LonLat.h:90
NormalizedAngle getLon() const
Definition: LonLat.h:88
NormalizedAngle is an angle that lies in the range [0, 2π), with one exception - a NormalizedAngle ca...
NormalizedAngleInterval represents closed intervals of normalized angles, i.e.
NormalizedAngleInterval & clipTo(NormalizedAngle x)
clipTo shrinks this interval until all its points are in x.
bool isFull() const
isFull returns true if this interval contains all normalized angles.
NormalizedAngle getCenter() const
getCenter returns the center of this interval.
Relationship relate(NormalizedAngle x) const
NormalizedAngle getSize() const
getSize returns the size (length, width) of this interval.
NormalizedAngleInterval & expandTo(NormalizedAngle x)
static NormalizedAngleInterval fromDegrees(double a, double b)
static NormalizedAngleInterval fromRadians(double a, double b)
static NormalizedAngleInterval full()
bool isEmpty() const
isEmpty returns true if this interval does not contain any normalized angles.
Region is a minimal interface for 2-dimensional regions on the unit sphere.
Definition: Region.h:79
virtual Relationship relate(Region const &) const =0
virtual bool contains(UnitVector3d const &) const =0
contains tests whether the given unit vector is inside this region.
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.
Definition: UnitVector3d.h:55
T data(T... args)
lsst::geom::Angle Angle
Definition: misc.h:33
std::ostream & operator<<(std::ostream &, Angle const &)
Definition: Angle.cc:34
constexpr double PI
Definition: constants.h:36
Relationship invert(Relationship r)
Given the relationship between two sets A and B (i.e.
Definition: Relationship.h:55
A base class for image defects.
T size(T... args)
double w
Definition: CoaddPsf.cc:69